From 11143430529d9374b27b7d4e7015180bb68b26cc Mon Sep 17 00:00:00 2001 From: Suraj Date: Sat, 1 Apr 2023 15:26:53 +0530 Subject: [PATCH 1/3] Initial setup: Added project files and configurations. --- .env | 1 + .gitignore | 2 + .prettierignore | 3 + .prettierrc.json | 4 + package-lock.json | 1017 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 30 ++ src/index.ts | 4 + tsconfig.json | 22 + 8 files changed, 1083 insertions(+) create mode 100644 .env create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 .prettierrc.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/index.ts create mode 100644 tsconfig.json diff --git a/.env b/.env new file mode 100644 index 0000000..ba0e436 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +API_ENDPOINT=https://example.com \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d2b47d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +node_modules \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..209170d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +.idea +node_modules +.prettierrc.json \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..dcb7279 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..339bd79 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1017 @@ +{ + "name": "tilli-ticker", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "tilli-ticker", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "dotenv": "^16.0.3" + }, + "devDependencies": { + "nodemon": "^2.0.22", + "prettier": "^2.8.7", + "ts-node": "^10.9.1", + "typescript": "^5.0.3" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", + "dev": true, + "peer": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nodemon": { + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", + "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz", + "integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "@types/node": { + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", + "dev": true, + "peer": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "nodemon": { + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", + "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "prettier": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "dev": true + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "typescript": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz", + "integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==", + "dev": true + }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..eb8c387 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "tilli-ticker", + "version": "1.0.0", + "description": "Tilli Nodejs challenge.", + "main": "index.js", + "scripts": { + "start": "nodemon src/index.ts", + "build": "tsc", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/backendsuraj/node-developer-challenge.git" + }, + "author": "Suraj Rana", + "license": "ISC", + "bugs": { + "url": "https://github.com/backendsuraj/node-developer-challenge/issues" + }, + "homepage": "https://github.com/backendsuraj/node-developer-challenge#readme", + "devDependencies": { + "nodemon": "^2.0.22", + "prettier": "^2.8.7", + "ts-node": "^10.9.1", + "typescript": "^5.0.3" + }, + "dependencies": { + "dotenv": "^16.0.3" + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..b41ff2e --- /dev/null +++ b/src/index.ts @@ -0,0 +1,4 @@ +import * as dotenv from 'dotenv'; +dotenv.config({path: '.env'}); + +console.log(process.env.API_KEY); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..4cf8990 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "target": "ESNext", + "moduleResolution": "Node", + "sourceMap": true, + "outDir": "dist", + "baseUrl": ".", + "paths": { + "*": [ + "node_modules/*", + "src/types/*" + ] + } + }, + "include": [ + "src/**/*" + ], + "exclude": ["node_modules"] +} \ No newline at end of file From 4afde5edbef948242caf973232971a279a04d301 Mon Sep 17 00:00:00 2001 From: Suraj Date: Sat, 1 Apr 2023 19:02:16 +0530 Subject: [PATCH 2/3] Completed Tilli CLI implementation with local state, interactive mode, and additional features. --- .env | 2 +- .gitignore | 3 +- .prettierignore | 3 +- .prettierrc.json | 4 - .ttrc | 4 + Dockerfile | 20 ++ package-lock.json | 578 ++++++++++++++++++++++++++++++++++++-- package.json | 46 ++- src/constants/index.ts | 63 +++++ src/core/alpha-vantage.ts | 79 ++++++ src/core/state.ts | 85 ++++++ src/index.ts | 74 ++++- src/prompter/actions.ts | 113 ++++++++ src/prompter/index.ts | 190 +++++++++++++ src/types/index.ts | 26 ++ src/utils/index.ts | 37 +++ 16 files changed, 1277 insertions(+), 50 deletions(-) delete mode 100644 .prettierrc.json create mode 100644 .ttrc create mode 100644 Dockerfile create mode 100644 src/constants/index.ts create mode 100644 src/core/alpha-vantage.ts create mode 100644 src/core/state.ts create mode 100644 src/prompter/actions.ts create mode 100644 src/prompter/index.ts create mode 100644 src/types/index.ts create mode 100644 src/utils/index.ts diff --git a/.env b/.env index ba0e436..eb8ab72 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -API_ENDPOINT=https://example.com \ No newline at end of file +ALPHA_VANTAGE_API_URL=https://www.alphavantage.co/query \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2d2b47d..76fb2e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea -node_modules \ No newline at end of file +node_modules +dist \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 209170d..2d2b47d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,2 @@ .idea -node_modules -.prettierrc.json \ No newline at end of file +node_modules \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index dcb7279..0000000 --- a/.prettierrc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "singleQuote": true, - "trailingComma": "all" -} \ No newline at end of file diff --git a/.ttrc b/.ttrc new file mode 100644 index 0000000..e7f062d --- /dev/null +++ b/.ttrc @@ -0,0 +1,4 @@ +{ + "apiKey": "", + "exchange": "BSE" +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..88d7d1f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +# Use the official Node.js image as the base image +FROM node:14-alpine + +# Create a new directory to hold our application code +WORKDIR /app + +# Copy package.json and package-lock.json files into the container +COPY package*.json ./ + +# Install the dependencies +RUN npm install + +# Copy the rest of the application code into the container +COPY . . + +# Build the TypeScript code +RUN npm run build + +# Set the entrypoint to run the CLI +ENTRYPOINT ["node", "dist/index.js"] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 339bd79..16553dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,13 +9,34 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "dotenv": "^16.0.3" + "axios": "^1.3.4", + "chalk": "^4.1.2", + "cli-table3": "^0.6.3", + "commander": "^10.0.0", + "dotenv": "^16.0.3", + "figlet": "^1.5.2", + "nanospinner": "^1.1.0", + "prompts": "^2.4.2" + }, + "bin": { + "tt": "dist/index.js" }, "devDependencies": { + "@types/figlet": "^1.5.5", + "@types/prompts": "^2.4.4", "nodemon": "^2.0.22", - "prettier": "^2.8.7", + "prettier": "2.8.7", "ts-node": "^10.9.1", - "typescript": "^5.0.3" + "typescript": "^5.0.2" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "optional": true, + "engines": { + "node": ">=0.1.90" } }, "node_modules/@cspotcode/source-map-support": { @@ -79,12 +100,27 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "node_modules/@types/figlet": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/figlet/-/figlet-1.5.5.tgz", + "integrity": "sha512-0sMBeFoqdGgdXoR/hgKYSWMpFufSpToosNsI2VgmkPqZJgeEXsXNu2hGr0FN401dBro2tNO5y2D6uw3UxVaxbg==", + "dev": true + }, "node_modules/@types/node": { "version": "18.15.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", + "dev": true + }, + "node_modules/@types/prompts": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.4.tgz", + "integrity": "sha512-p5N9uoTH76lLvSAaYSZtBCdEXzpOOufsRjnhjVSrZGXikVGHX9+cc9ERtHRV4hvBKHyZb1bg4K+56Bd2TqUn4A==", "dev": true, - "peer": true + "dependencies": { + "@types/node": "*", + "kleur": "^3.0.3" + } }, "node_modules/abbrev": { "version": "1.1.1", @@ -113,6 +149,28 @@ "node": ">=0.4.0" } }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -132,6 +190,21 @@ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -169,6 +242,21 @@ "node": ">=8" } }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -196,6 +284,73 @@ "fsevents": "~2.3.2" } }, + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.0.tgz", + "integrity": "sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==", + "engines": { + "node": ">=14" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -217,6 +372,14 @@ "ms": "^2.1.1" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -234,6 +397,14 @@ "node": ">=12" } }, + "node_modules/figlet": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.2.tgz", + "integrity": "sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -246,6 +417,38 @@ "node": ">=8" } }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -273,12 +476,11 @@ } }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/ignore-by-default": { @@ -308,6 +510,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -329,12 +539,39 @@ "node": ">=0.12.0" } }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -353,6 +590,14 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/nanospinner": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nanospinner/-/nanospinner-1.1.0.tgz", + "integrity": "sha512-yFvNYMig4AthKYfHFl1sLj7B2nkHL4lzdig4osvl9/LdGbXwrdFRoqBS98gsEsOakr0yH+r5NZ/1Y9gdVB8trA==", + "dependencies": { + "picocolors": "^1.0.0" + } + }, "node_modules/nodemon": { "version": "2.0.22", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", @@ -381,6 +626,27 @@ "url": "https://opencollective.com/nodemon" } }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -405,6 +671,11 @@ "node": ">=0.10.0" } }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -432,6 +703,23 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -480,16 +768,31 @@ "semver": "bin/semver.js" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/to-regex-range": { @@ -560,9 +863,9 @@ } }, "node_modules/typescript": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz", - "integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -595,6 +898,12 @@ } }, "dependencies": { + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "optional": true + }, "@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -650,12 +959,27 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "@types/figlet": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/figlet/-/figlet-1.5.5.tgz", + "integrity": "sha512-0sMBeFoqdGgdXoR/hgKYSWMpFufSpToosNsI2VgmkPqZJgeEXsXNu2hGr0FN401dBro2tNO5y2D6uw3UxVaxbg==", + "dev": true + }, "@types/node": { "version": "18.15.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", + "dev": true + }, + "@types/prompts": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.4.tgz", + "integrity": "sha512-p5N9uoTH76lLvSAaYSZtBCdEXzpOOufsRjnhjVSrZGXikVGHX9+cc9ERtHRV4hvBKHyZb1bg4K+56Bd2TqUn4A==", "dev": true, - "peer": true + "requires": { + "@types/node": "*", + "kleur": "^3.0.3" + } }, "abbrev": { "version": "1.1.1", @@ -675,6 +999,19 @@ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -691,6 +1028,21 @@ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -722,6 +1074,15 @@ "fill-range": "^7.0.1" } }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -738,6 +1099,58 @@ "readdirp": "~3.6.0" } }, + "cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.0.tgz", + "integrity": "sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -759,6 +1172,11 @@ "ms": "^2.1.1" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -770,6 +1188,11 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" }, + "figlet": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.2.tgz", + "integrity": "sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ==" + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -779,6 +1202,21 @@ "to-regex-range": "^5.0.1" } }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -796,10 +1234,9 @@ } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "ignore-by-default": { "version": "1.0.1", @@ -822,6 +1259,11 @@ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -837,12 +1279,30 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -858,6 +1318,14 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "nanospinner": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nanospinner/-/nanospinner-1.1.0.tgz", + "integrity": "sha512-yFvNYMig4AthKYfHFl1sLj7B2nkHL4lzdig4osvl9/LdGbXwrdFRoqBS98gsEsOakr0yH+r5NZ/1Y9gdVB8trA==", + "requires": { + "picocolors": "^1.0.0" + } + }, "nodemon": { "version": "2.0.22", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", @@ -874,6 +1342,23 @@ "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.5" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "nopt": { @@ -891,6 +1376,11 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -903,6 +1393,20 @@ "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", "dev": true }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -941,13 +1445,25 @@ } } }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } }, "to-regex-range": { @@ -990,9 +1506,9 @@ } }, "typescript": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz", - "integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true }, "undefsafe": { diff --git a/package.json b/package.json index eb8c387..bcd66c2 100644 --- a/package.json +++ b/package.json @@ -2,29 +2,57 @@ "name": "tilli-ticker", "version": "1.0.0", "description": "Tilli Nodejs challenge.", - "main": "index.js", + "main": "dist/index.js", + "bin": { + "tt": "dist/index.js" + }, + "prettier": { + "arrowParens": "always", + "singleQuote": true, + "trailingComma": "es5", + "tabWidth": 2, + "printWidth": 80, + "overrides": [ + { + "files": ["src/**/*.ts"], + "options": { + "parser": "typescript" + } + } + ] + }, "scripts": { - "start": "nodemon src/index.ts", + "start": "nodemon --no-stdin src/index.ts", "build": "tsc", + "prettier": "prettier --write \"src/**/*.ts\"", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "git+https://github.com/backendsuraj/node-developer-challenge.git" }, - "author": "Suraj Rana", - "license": "ISC", "bugs": { "url": "https://github.com/backendsuraj/node-developer-challenge/issues" }, "homepage": "https://github.com/backendsuraj/node-developer-challenge#readme", + "author": "backendsuraj@gmail.com", + "license": "ISC", + "dependencies": { + "axios": "^1.3.4", + "chalk": "^4.1.2", + "cli-table3": "^0.6.3", + "commander": "^10.0.0", + "dotenv": "^16.0.3", + "figlet": "^1.5.2", + "nanospinner": "^1.1.0", + "prompts": "^2.4.2" + }, "devDependencies": { + "@types/figlet": "^1.5.5", + "@types/prompts": "^2.4.4", "nodemon": "^2.0.22", - "prettier": "^2.8.7", + "prettier": "2.8.7", "ts-node": "^10.9.1", - "typescript": "^5.0.3" - }, - "dependencies": { - "dotenv": "^16.0.3" + "typescript": "^5.0.2" } } diff --git a/src/constants/index.ts b/src/constants/index.ts new file mode 100644 index 0000000..471a372 --- /dev/null +++ b/src/constants/index.ts @@ -0,0 +1,63 @@ +import chalk from 'chalk'; + +export const THEME = { + GREEN: '#2CC88D', + PURPLE: '#573280', + DARK_BLUE: '#011638', + DEEP_BLUE: '#020119', + STEEL_BLUE: '#3F88C5', + RED: '#e61351', + ORANGE: '#EAA24E', + WHITE: '#FFF', + RED_STOCK: '#f93c3c', + GREEN_STOCK: '#00b457', +}; + +export const StockExchanges = [ + { title: 'New York Stock Exchange (NYSE)', value: 'NYSE' }, + { title: 'NASDAQ', value: 'NASDAQ' }, + { title: 'London Stock Exchange (LSE)', value: 'LSE' }, + { title: 'Bombay Stock Exchange (BSE)', value: 'BSE' }, + { title: 'National Stock Exchange of India (NSE)', value: 'NSE' }, + { title: 'Singapore Exchange (SGX)', value: 'SGX' }, + { title: chalk.hex(THEME.STEEL_BLUE)('Enter Manually...'), value: null }, +]; + +export const InteractivePrompts = [ + { title: 'View Ticker', value: 'view' }, + { title: 'Save Ticker', value: 'save' }, + { title: 'View & Save Ticker', value: 'viewAndSave' }, + { title: 'List All Tickers', value: 'list' }, + { title: chalk.hex(THEME.RED)('Delete Current Ticker'), value: 'delete' }, + { title: chalk.hex(THEME.GREEN)('Change Ticker?'), value: 'changeTicker' }, + { title: chalk.hex(THEME.ORANGE)('Exit!'), value: null }, +]; + +export const CLI_DESCRIPTION = `DESCRIPTION: + tt a CLI app that allows you to continuously track stocks using the AlphaVantage API. An AlphaVantage API key is needed to use this utility.`; + +export const FILE_CONFIG_DESC = `FILES + .ttrc + The global configuration file.`; + +export const CLI_CONFIG_START_MSG = `It's time to set up the CLI!`; +export const CLI_CONFIG_FINISH_MSG = `Awesome! You're now ready to unleash the power of the CLI!`; +export const EXIT_CLI_MSG = `Thank you for using our CLI tool. Have a great day!`; + +export const DIAGNOSTIC_MSG = `DIAGNOSTICS: + The following diagnostics may be issued on stderr: + + Rate limit exceeded. + The API key used in the configuration has gone past the rate limit set by the AlphaVantage API. \n Please either wait for a new rate period or upgrade your API key. + + Invalid API key. + The provided API key is invalid or has been revoked. Please check your API key and try again. + + Stock symbol not found. + The specified stock symbol could not be found. Please verify the stock symbol and try again. + + Stock exchange not supported. + The specified stock exchange is not supported by the AlphaVantage API. \n Please check the exchange abbreviation and try again. + + Configuration file error. + An error occurred while reading or parsing the configuration file. Please verify the contents of the configuration file and try again.`; diff --git a/src/core/alpha-vantage.ts b/src/core/alpha-vantage.ts new file mode 100644 index 0000000..0c75991 --- /dev/null +++ b/src/core/alpha-vantage.ts @@ -0,0 +1,79 @@ +import axios, { AxiosInstance } from 'axios'; +import ApplicationState from '../core/state'; +import { AlphaVantageApiResponse } from 'index'; +import * as process from 'process'; + +export class AlphaVantageAPIError extends Error {} + +class AlphaVantageService { + private readonly apiKey: string; + private readonly apiUrl: string; + private readonly axiosInstance: AxiosInstance; + private applicationState: ApplicationState; + + constructor(apiKey: string) { + this.applicationState = ApplicationState.getInstance(); + this.apiKey = apiKey; + this.apiUrl = process.env.ALPHA_VANTAGE_API_URL; + this.axiosInstance = axios.create({ + baseURL: this.apiUrl, + timeout: 5000, + }); + } + + async getStockInfo(symbol: string) { + try { + //check in local cache if we already fetched! + let checkCacheForSymbol = this.applicationState.getFromCache(symbol); + if (checkCacheForSymbol) { + return checkCacheForSymbol; + } + + const response = await this.axiosInstance.get('', { + params: { + function: 'GLOBAL_QUOTE', + symbol: symbol, + apikey: this.apiKey, + }, + }); + + this.handleAlphaVantageErrors(response); + + const data = response.data['Global Quote']; + let apiResponse: AlphaVantageApiResponse = { + symbol: data['01. symbol'], + date: data['07. latest trading day'], + open: parseFloat(data['02. open']), + high: parseFloat(data['03. high']), + low: parseFloat(data['04. low']), + price: parseFloat(data['05. price']), + change: parseFloat(data['09. change']), + volume: parseInt(data['06. volume']), + }; + await this.applicationState.addToCache(symbol, apiResponse); + return apiResponse; + } catch (error) { + throw error; + } + } + + private handleAlphaVantageErrors(response) { + if (response.data['Error Message']) { + const errorMessage = response.data['Error Message']; + if (errorMessage.toLowerCase().includes('invalid')) { + throw new AlphaVantageAPIError('Invalid symbol or API key'); + } else if (errorMessage.toLowerCase().includes('rate limit exceeded')) { + throw new AlphaVantageAPIError('API rate limit exceeded'); + } else { + throw new AlphaVantageAPIError(errorMessage); + } + } + if (response.data['Note']) { + const note = response.data['Note']; + throw new AlphaVantageAPIError(`API usage limit reached: ${note}`); + } + return true; + } +} + +export default AlphaVantageService; diff --git a/src/core/state.ts b/src/core/state.ts new file mode 100644 index 0000000..e765230 --- /dev/null +++ b/src/core/state.ts @@ -0,0 +1,85 @@ +class ApplicationState { + private static instance: ApplicationState; + + exchange: string; + apiKey: string; + ticker: string; + stockData: Record; + cache: Record; + + private constructor( + exchange: string, + apiKey: string, + ticker: string, + stockData: Record + ) { + this.exchange = exchange; + this.apiKey = apiKey; + this.ticker = ticker; + this.stockData = stockData; + this.cache = {}; + } + + public static getInstance(): ApplicationState { + if (!ApplicationState.instance) { + ApplicationState.instance = new ApplicationState('', '', '', {}); + } + return ApplicationState.instance; + } + + public setExchange(exchange: string) { + this.exchange = exchange; + } + + public setApiKey(apiKey: string) { + this.apiKey = apiKey; + } + + public setTicker(ticker: string) { + this.ticker = ticker; + } + + public setStockData( + exchange: string, + ticker: string, + stockData: Record + ) { + if (!this.stockData[exchange]) { + this.stockData[exchange] = {}; + } + this.stockData[exchange][ticker] = stockData; + } + + public getStocksByExchange(exchange: string) { + return this.stockData[exchange]; + } + + public deleteStockByExchange(exchange: string, ticker: string) { + if (this.stockData[exchange]) { + delete this.stockData[exchange][ticker]; + } + } + + public getProperty(propertyName: string): any { + return this[propertyName]; + } + + public addToCache(key: string, value: any) { + this.cache[key] = value; + } + + public getFromCache(key: string): any { + return this.cache[key]; + } + + public getState(): Record { + return { + exchange: this.exchange, + apiKey: this.apiKey, + ticker: this.ticker, + stockData: this.stockData, + }; + } +} + +export default ApplicationState; diff --git a/src/index.ts b/src/index.ts index b41ff2e..3f61fc5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,74 @@ +#!/usr/bin/env node import * as dotenv from 'dotenv'; -dotenv.config({path: '.env'}); +dotenv.config({ path: '.env' }); +import { Command } from 'commander'; +import chalk from 'chalk'; +import figlet from 'figlet'; +import { spacer } from './utils'; +import { + THEME, + DIAGNOSTIC_MSG, + CLI_DESCRIPTION, + FILE_CONFIG_DESC, +} from './constants'; +import Prompter from './prompter'; +import { CommanderOptions } from './types'; -console.log(process.env.API_KEY); \ No newline at end of file +class TilliTicker { + init() { + console.log( + chalk.bgHex(THEME.DEEP_BLUE).hex(THEME.RED)( + figlet.textSync('Tilli Ticker', { + horizontalLayout: 'full', + }) + ) + ); + + spacer(); + + const program = new Command(); + program + .name(chalk.bgHex(THEME.DARK_BLUE)(`tt`)) + .usage( + chalk.bgHex(THEME.DARK_BLUE)( + '[-x exchange] [-a api-key] [-c config-file] [exchange:]ticker' + ) + ) + .option( + '-x, --exchange', + `Specific stock exchange to use when doing the stock symbol lookup. This can be appended to the ticker argument directly by preceding the ticker argument with the exchange plus ":" (e.g. NASDAQ:AAPL) Throws if the exchange does not exist or if the stock symbol is not found on the exchange.` + ) + .option( + '-a, --apiKey', + 'Use specified AlphaVantage API key. If no global config present or global config has no API key then interactive mode will launch to query the user for an API key.' + ) + .option( + '-v, --view', + 'View the stock summary stats for the current day once found or chosen. Is inferred to be true if the -s flag is not present.' + ) + .option('-s, --save', 'Save the stock symbol and its summary statistics.') + .option('-l, --list', 'View all saved stocks.') + .option('-d, --delete', 'Delete a saved stock symbol.') + .option( + '-c, --configFile ', + 'Specify the configuration file to use.' + ) + .argument('[ticker]') + .on('--help', () => { + spacer(); + console.log(chalk.bgHex(THEME.DARK_BLUE)(CLI_DESCRIPTION)); + spacer(); + console.log(FILE_CONFIG_DESC); + spacer(); + console.log(chalk.hex(THEME.ORANGE)(DIAGNOSTIC_MSG)); + spacer(); + }); + program.parse(process.argv); + const options: CommanderOptions = program.opts(); + options.ticker = program.processedArgs.pop(); + const prompter = new Prompter(options); + } +} + +const tilliTicker = new TilliTicker(); +tilliTicker.init(); diff --git a/src/prompter/actions.ts b/src/prompter/actions.ts new file mode 100644 index 0000000..68f2915 --- /dev/null +++ b/src/prompter/actions.ts @@ -0,0 +1,113 @@ +import ApplicationState from '../core/state'; +import AlphaVantageService, { + AlphaVantageAPIError, +} from '../core/alpha-vantage'; +import { createSpinner } from 'nanospinner'; +import { displayStockDetails, logError, spacer } from '../utils'; + +export class InteractivePromptsHandler { + private applicationState: ApplicationState; + private alphaVantageService: AlphaVantageService; + + constructor() { + this.applicationState = ApplicationState.getInstance(); + this.alphaVantageService = new AlphaVantageService( + this.applicationState.getProperty('apiKey') + ); + } + + public async handleSelectedOption(selectedOption: string) { + switch (selectedOption) { + case 'view': + await this.handleView(); + break; + case 'save': + await this.handleSave(); + break; + case 'viewAndSave': + await this.handleView(); + await this.handleSave(); + break; + case 'list': + await this.handleList(); + break; + case 'delete': + await this.handleDelete(); + break; + default: + break; + } + } + + private async handleView() { + try { + let spin = createSpinner('Loading...'); + spacer(); + let { ticker, exchange } = this.applicationState.getState(); + let getTickerInfo = await this.alphaVantageService.getStockInfo( + `${ticker}.${exchange}` + ); + spin.success({ text: 'Loaded' }); + displayStockDetails([getTickerInfo]); + return true; + } catch (e) { + if (e instanceof AlphaVantageAPIError) { + logError(`Alpha Vantage API error: ${e.message}`); + } else { + logError(`Unexpected error: ${e.message}`); + } + } + } + + private async handleSave() { + try { + let spin = createSpinner('Processing...'); + spacer(); + const { ticker, exchange } = this.applicationState.getState(); + let getTickerInfo = await this.alphaVantageService.getStockInfo( + `${ticker}.${exchange}` + ); + this.applicationState.setStockData(exchange, ticker, getTickerInfo); + spin.success({ text: 'Done....' }); + spacer(); + return true; + } catch (e) { + if (e instanceof AlphaVantageAPIError) { + logError(`Alpha Vantage API error: ${e.message}`); + } else { + logError(`Unexpected error: ${e.message}`); + } + } + } + + private async handleList() { + try { + let spin = createSpinner('Loading...'); + spacer(); + const { exchange } = this.applicationState.getState(); + let stocksByExchange = + this.applicationState.getStocksByExchange(exchange); + const output = []; + for (let key in stocksByExchange) { + output.push(stocksByExchange[key]); + } + spin.success({ text: 'Done....' }); + displayStockDetails(output); + } catch (e) { + logError(`Unexpected error: ${e.message}`); + } + } + + private async handleDelete() { + try { + let spin = createSpinner('Processing...'); + spacer(); + const { ticker, exchange } = this.applicationState.getState(); + this.applicationState.deleteStockByExchange(exchange, ticker); + spin.success({ text: 'Done....' }); + spacer(); + } catch (e) { + logError(`Unexpected error: ${e.message}`); + } + } +} diff --git a/src/prompter/index.ts b/src/prompter/index.ts new file mode 100644 index 0000000..0883cbf --- /dev/null +++ b/src/prompter/index.ts @@ -0,0 +1,190 @@ +import prompts, { PromptObject } from 'prompts'; +import * as path from 'path'; +import { promises as fs } from 'fs'; +import { RCFileContent } from '../types'; +import ApplicationState from '../core/state'; +import chalk from 'chalk'; +import { logError, spacer } from '../utils'; +import { + THEME, + StockExchanges, + InteractivePrompts, + EXIT_CLI_MSG, + CLI_CONFIG_START_MSG, + CLI_CONFIG_FINISH_MSG, +} from '../constants'; +import { InteractivePromptsHandler } from './actions'; + +class Prompter { + private exchange: string; + private apiKey: string; + private viewStock: boolean; + private saveStock: boolean; + private listStock: boolean; + private deleteStock: boolean; + private configFile: string; + private ticker: string; + private isManualMode: Boolean = false; + private applicationState: ApplicationState; + + constructor(params) { + this.applicationState = ApplicationState.getInstance(); + const { + exchange, + apiKey, + view, + save, + list, + delete: deleteOption, + configFile, + ticker, + } = params; + + this.exchange = exchange; + this.apiKey = apiKey; + this.viewStock = view; + this.saveStock = save; + this.listStock = list; + this.deleteStock = deleteOption; + this.configFile = configFile; + this.ticker = ticker; + this.promptForMandatory(); + } + + private mapArgsToActionPrompts() { + let actionToTake = ''; + switch (true) { + case this.viewStock && this.saveStock: + actionToTake = 'viewAndSave'; + break; + case this.viewStock: + actionToTake = 'view'; + break; + case this.saveStock: + actionToTake = 'save'; + break; + case this.deleteStock: + actionToTake = 'delete'; + break; + case this.listStock: + actionToTake = 'list'; + break; + default: + break; + } + return actionToTake; + } + + public async actionPrompts() { + let actions = new InteractivePromptsHandler(); + let actionToTake = this.mapArgsToActionPrompts(); + if (actionToTake !== '') { + this.isManualMode = true; + await actions.handleSelectedOption(actionToTake); + } else { + this.isManualMode = false; + const { selectedOption } = await prompts({ + type: 'select', + name: 'selectedOption', + message: 'Which action would you like to perform?', + choices: InteractivePrompts, + }); + if (!selectedOption) { + spacer(); + console.log(chalk.hex(THEME.ORANGE)(EXIT_CLI_MSG)); + spacer(); + return; + } + if (selectedOption === 'changeTicker') { + const { ticker } = await prompts({ + type: 'text', + name: 'ticker', + message: 'Please provide ticker:', + validate: (value) => + value.length < 3 ? 'Please enter a valid ticket' : true, + }); + this.ticker = ticker; + this.applicationState.setTicker(ticker); + } + await actions.handleSelectedOption(selectedOption); + await this.actionPrompts(); + } + } + + public async promptForMandatory() { + const promptsToRun: PromptObject[] = []; + if (this.configFile) { + let processConfigFile = await this.checkForConfigFile(); + if (!processConfigFile) return; + } + if (!this.exchange || !this.apiKey) { + console.log(chalk.bgHex(THEME.PURPLE)(CLI_CONFIG_START_MSG)); + spacer(); + } + if (!this.apiKey) { + promptsToRun.push({ + type: 'text', + name: 'apiKey', + message: 'Enter the API key:', + validate: (value) => + value.length < 3 ? 'Please enter valid api key' : true, + }); + } + if (!this.exchange) { + promptsToRun.push({ + type: 'select', + name: 'exchange', + message: 'Select a stock exchange:', + choices: StockExchanges, + }); + promptsToRun.push({ + type: (prev) => (prev === null ? 'text' : null), + name: 'exchange', + message: 'Please provide the exchange code.', + validate: (value) => + value < 3 ? `Please provide valid exchange code.` : true, + }); + } + if (!this.ticker) { + promptsToRun.push({ + type: 'text', + name: 'ticker', + message: 'Please provide ticker:', + validate: (value) => + value.length < 3 ? 'Please enter a valid ticket' : true, + }); + } + + const { exchange, apiKey, ticker } = await prompts(promptsToRun); + this.exchange = exchange || this.exchange; + this.apiKey = apiKey || this.apiKey; + this.ticker = ticker || this.ticker; + this.applicationState.setApiKey(this.apiKey); + this.applicationState.setExchange(this.exchange); + this.applicationState.setTicker(this.ticker); + spacer(); + if (this.isManualMode) { + console.log(chalk.bgHex(THEME.PURPLE)(CLI_CONFIG_FINISH_MSG)); + spacer(); + } + await this.actionPrompts(); + } + + private async checkForConfigFile() { + try { + const filePath = path.resolve(process.cwd(), this.configFile); + const data = await fs.readFile(filePath, 'utf8'); + const jsonData: RCFileContent = JSON.parse(data); + this.apiKey = jsonData.apiKey || null; + this.exchange = jsonData.exchange || null; + this.applicationState.setApiKey(this.apiKey); + this.applicationState.setExchange(this.exchange); + return true; + } catch (error) { + logError(`Invalid .ttrc File.`); + return false; + } + } +} + +export default Prompter; diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..6fccf7f --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,26 @@ +export interface CommanderOptions { + configFile?: string; + exchange?: string; + apiKey?: string; + ticker?: string; + view?: boolean; + save?: boolean; + list?: boolean; + delete?: boolean; +} + +export interface AlphaVantageApiResponse { + symbol: string; + date: string; + open: number; + high: number; + low: number; + price: number; + change: number; + volume: number; +} + +export interface RCFileContent { + apiKey?: string; + exchange?: string; +} diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..4331d43 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,37 @@ +import Table from 'cli-table3'; +import chalk from 'chalk'; +import { THEME } from '../constants'; + +export const spacer = () => console.log(''); + +export const logError = (msg) => + console.log(chalk.bgHex(THEME.RED).hex(THEME.WHITE)(msg)); + +export const displayStockDetails = (obj) => { + const table = new Table({ + head: [ + 'Ticker ✌️', + 'Date ⌚', + 'Open ☼', + 'High ▲', + 'Low ▼', + 'Price $', + 'Change ∓', + 'Volume 📦', + ], + style: { head: [], border: [] }, + }); + + const arrayOfValues = obj.map((obj) => { + const color = + obj.change < 0 + ? chalk.hex(THEME.RED_STOCK) + : chalk.hex(THEME.GREEN_STOCK); + return Object.values(obj).map((value) => color(value)); + }); + + table.push(...arrayOfValues); + spacer(); + console.log(table.toString()); + spacer(); +}; From 3b3274a58e4b30b98b6ea66507a80faad3d6dcee Mon Sep 17 00:00:00 2001 From: Suraj Date: Sat, 1 Apr 2023 19:47:29 +0530 Subject: [PATCH 3/3] Added documentation for the CLI in the README.md file and fixed a bug that caused issues when an exchange:ticker value was provided. --- README.md | 216 ++++++++++++------------------------------ docs/imgs/img.png | Bin 0 -> 65710 bytes docs/imgs/img_0.png | Bin 0 -> 25894 bytes docs/imgs/img_1.png | Bin 0 -> 30282 bytes package.json | 4 +- src/prompter/index.ts | 7 ++ 6 files changed, 68 insertions(+), 159 deletions(-) create mode 100644 docs/imgs/img.png create mode 100644 docs/imgs/img_0.png create mode 100644 docs/imgs/img_1.png diff --git a/README.md b/README.md index 8ff709d..269d135 100644 --- a/README.md +++ b/README.md @@ -1,181 +1,81 @@ -# Tilli Node.js Developer Challenge +# Tilli Ticker -Thank you for your interest in Tilli! The following coding challenge should take no longer than 2-3 hours. Please feel free to reach out for any clarification on the requirements presented below. +```tt``` is a CLI application that fetches stock details from the Alpha Vantage API. It allows you to track stocks and view summary statistics for any stock symbol and exchange supported by the API. -## Getting started +## Installation +Install the dependencies using ```cd node-developer-challenge && npm i``` -Fork this repository and use your fork to build the challenge. When you've finished and all of your work is pushed, let us know so that we can review (you can also submit a PR back to this repo to notify). - -## Terminology - -| Term | Description | AKA | Example(s) | -| :----------------- | :------------------------ | --- | ------- | -| Stock symbol | A unique series of letters assigned to a stock for trading purposes (e.g. AAPL for Apple Inc.) | Stock ticker, Ticker symbol | AAPL (Apple Inc.) | -| Exchange | A market where financial securities such as stocks, bonds, and commodities are traded. | Stock exchange | NASDAQ, NYSE, NSE | - -## The challenge - -Your task is to create an interactive Node.js CLI application that will show summary statistics for requested stock ticker symbols using the [Alpha Vantage](https://www.alphavantage.co/documentation/) API. The interactive CLI app will require managing and persisting state, processing input arguments, and showing interactive prompts and follow up prompts depending on the inputs. The application should be able to handle the below requirements for any amount of stock symbols on any exchange supported via the Alpha Vantage API. - -### Features - -The output below is a stubbed version of the helper text (`-h` flag, though the actual output below is more representative of a `man` page) for the application. Flags in the `OPTIONS` section correspond with features. The interactive CLI app should be able to parse incoming arguments and generate interactive prompts to fill in missing information. - -Some sections are deliberately left incomplete (they will be marked via `[STUBBED]`); your final submission should also include updated documentation. - -Any implementation details that have not been included have been deliberately left out for you to create your own solution. - -```zsh -> tt -h - -# output -NAME - tt - tilli ticker - -SYNOPSIS - tt [-x exchange] [-a api-key] [-c config-file] [exchange:]ticker - -DESCRIPTION - tt a CLI app that allows you to continuously track stocks using the AlphaVantage API. An AlphaVantage API key is needed to use this utility. - -OPTIONS - -x exchange - Specific stock exchange to use when doing the stock symbol lookup. This can be appended to the ticker argument directly by preceding the ticker argument with the exchange plus ":" (e.g. NASDAQ:AAPL) Throws if the exchange does not exist or if the stock symbol is not found on the exchange. - - -a api-key - Use specified AlphaVantage API key. If no global config present or global config has no API key then interactive mode will launch to query the user for an API key. - - -v View the stock summary stats for the current day once found or chosen. Is inferred to be true if the -s flag is not present. - - -s Save the stock symbol and its summary statistics. - - -l View all saved stocks. - - -d Delete a saved stock symbol. - - -h View command usage. - -FILES - ~/.ttrc - The global configuration file. - -DIAGNOSTICS - The following diagnostics may be issued on stderr: - - Rate limit exceeded. - The API key used in the configuration has gone past the rate limit set by the AlphaVantage API. Please either wait for a new rate period or upgrade your API key. - [STUBBED] - add additional potential diagnostics for errors here - -AUTHOR - [STUBBED] - make sure to sign your code! +```sh +npm run build +npm link ``` -### Interactive mode +This command will link our package to the global npm directory on the local machine, allowing us to use the ```tt``` command directly. -The CLI app should launch interactive mode whenever additional input is needed from the user. Below is a diagram showing some of the code paths taken by interactive mode and how certain paths can be skipped via arguments being passed in. +## Usage +To use ```tt```, run the following command: -```mermaid -flowchart TD - init[Invoke with `tt`] - - apiKey[Input API Key] - - exchange[Input stock exchange] - - ticker[Input ticker] - - listAll[[1.View specific stock\n2.Save specific stock\n3.View and save a specific stock\n4.List all saved stocks\n5.Delete a saved stock]] - - view[View stock] - - listStocks[List stocks] - - save[Save stock] - - delete[Delete stock] - - init-- "tt" ---->apiKey-->ticker---->exchange---->listAll - linkStyle 0 stroke:#fff - linkStyle 1 stroke:#fff - linkStyle 2 stroke:#fff - linkStyle 3 stroke:#fff - - init-- "tt ticker" --->apiKey-->exchange-->listAll - linkStyle 4 stroke:#ff3 - linkStyle 5 stroke:#ff3 - linkStyle 6 stroke:#ff3 - - init-- "tt -x [exchange]" -->apiKey-->ticker-->listAll - linkStyle 7 stroke:#f3f - linkStyle 8 stroke:#f3f - linkStyle 9 stroke:#f3f - - init-- "tt -a [api-key]" -->ticker-->exchange-->listAll - linkStyle 10 stroke:#3ff - linkStyle 11 stroke:#3ff - linkStyle 12 stroke:#3ff - - init-- "tt -a [api-key] ticker" --------->exchange-->listAll - linkStyle 13 stroke:#f33 - linkStyle 14 stroke:#f33 - - init-- "tt -x [exchange] ticker" -->apiKey-->listAll - linkStyle 15 stroke:#33f - linkStyle 16 stroke:#33f +``` +tt [options] exchange:ticker +``` - init-- "tt -x [exchange] -a [api-key] ticker" -->listAll - linkStyle 17 stroke:#999 +The [options] argument is optional and specifies how you want to interact with tt CLI. The ```exchange:ticker``` specifies the exchange and stock symbol . If you do not specify an exchange, CLI will enter the interactive mode. - init-- "tt -x [exchange] \ \n-a [api-key] -s ticker" -->save - linkStyle 18 stroke: #f9f +# Options +- -x, --exchange: Specifies the stock exchange to use when looking up the stock symbol. You can append the exchange directly to the ticker argument by preceding it with the exchange plus ":" (e.g. NASDAQ:AAPL). This option throws an error if the exchange does not exist or if the stock symbol is not found on the exchange. +- -a, --apiKey: Specifies the AlphaVantage API key to use. If there is no global config present or the global config has no API key, tt will launch interactive mode to query the user for an API key. +- -v, --view: Displays the stock summary statistics for the current day once found or chosen. This option is inferred to be true if the -s flag is not present. +- -s, --save: Saves the stock symbol and its summary statistics. +- -l, --list: Displays all saved stocks. +- -d, --delete: Deletes a saved stock symbol. +- -c, --configFile: Specifies the configuration file to use. +- -h, --help: Displays the help for the command. - init-- "tt -x [exchange] \ \n-a [api-key] -s -v ticker"-->save-->view - linkStyle 19 stroke:#f99 - linkStyle 20 stroke:#f99 +# Config FILES + `tt -c .ttrc` + The global configuration file. - init-- "tt -x [exchange] \ \n-a [api-key] -v ticker" -->view - linkStyle 21 stroke:#99f +# Diagnostics +The following diagnostics may be issued on stderr: - init-- "tt -x [exchange] \ \n-a [api-key] -l ticker" -->listStocks - linkStyle 22 stroke:#9f9 +- Rate limit exceeded.: The API key used in the configuration has gone past the rate limit set by the AlphaVantage API. Please wait for a new rate period or upgrade your API key. +- Invalid API key.: The provided API key is invalid or has been revoked. Please check your API key and try again. +- Stock symbol not found.: The specified stock symbol could not be found. Please verify the stock symbol and try again. +- Stock exchange not supported.: The specified stock exchange is not supported by the AlphaVantage API. Please check the exchange abbreviation and try again. +- Configuration file error.: An error occurred while reading or parsing the configuration file. Please verify the contents of the configuration file and try again. - init-- "tt -x [exchange] \ \n-a [api-key] -d ticker" -->delete - linkStyle 23 stroke:#6f6 +# Examples - listAll-- "3" -->save-->view - linkStyle 24 stroke:#f22 - linkStyle 25 stroke:#f22 +View Help - listAll-- "1" -->view - listAll-- "2" -->save - listAll-- "4" -->listStocks - listAll-- "5" -->delete +```sh +tt --help ``` -## Evaluation criteria - -- UX of the interactive mode of the CLI -- Argument processing -- Caching strategies -- State management -- Error management -- Code hygiene -- Documentation -- Secrets management -- Clean git history +![img.png](docs/imgs/img.png) -## Extra credit - -> Doing any of the below will help your application (if *done well*) but your strength as a candidate is only measured using the tangibles above. +Enter Interactive Mode +``` +tt +``` +![img.png](docs/imgs/img_0.png) -- use TypeScript -- add unit tests -- create a build process for distribution +View and save the ticker. +``` + tt -s -v IDEA +``` -## Some additional notes +![img.png](docs/imgs/img_1.png) -Certain implementation details have been **deliberately** left out in order to gauge your ability to fill in the gaps. Don't be afraid to ask questions, but also don't be surprised if for certain questions the response is that it's up to you to determine that. +Following Exchange & Tickers can be used to test the application Quickly. -There are no reservations about libraries that you use, and it is definitely recommended that you use one (or multiple) of the many CLI tooling packages in the js ecosystem in order to focus on building the functionality rather than the barebones CLI portion of this application. +- exchange ``BSE`` -Make sure to review all of the evaluation criteria! These are the exact points you will be judged on. \ No newline at end of file +- Tickers +`` +RELIANCE +TATAPOWER +IRCTC +IDEA +ZEELEARN +`` \ No newline at end of file diff --git a/docs/imgs/img.png b/docs/imgs/img.png new file mode 100644 index 0000000000000000000000000000000000000000..66a0bd662717ff647c5c48a7ea0579fa29284797 GIT binary patch literal 65710 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 literal 0 HcmV?d00001 diff --git a/docs/imgs/img_0.png b/docs/imgs/img_0.png new file mode 100644 index 0000000000000000000000000000000000000000..b65063bff3469cf75a61e6b9e7a2ab658bb6f3d8 GIT binary patch literal 25894 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 literal 0 HcmV?d00001 diff --git a/docs/imgs/img_1.png b/docs/imgs/img_1.png new file mode 100644 index 0000000000000000000000000000000000000000..9592b81d3e1dd1951272caadd891c007785a77e8 GIT binary patch literal 30282 zcmeFYXH=8h);5e46_qVYkt!e{(xi6~5$T{J1VRadNRt{mByo#?h=78C)JPXX2qkn# zM0)Qay%RdpOCY>AmVM6op7U(a_l)t5@s0O;`E`>!Yt6N;IoCC>HP=eueJ$k+=jhLo zk&#_cRk{0+jO?Tg8QF2OGsl5XQjC<&l99PxQoXD2$irl@;#e~W$dzz**kuq4VJK34 z`r>Q#GOy6tw-RGwwU_FhH7>su4|#=l@)nlPFI2hq+^+Iu=kc2B*zVZ&)@l#${^!<) zIY>v&1d)YHX&f;f=g}f(7cDKT?s@#F6r!5OY`)dgAuEJ z;^SoAR$$;Q>&w^OyxC-*nPX^N6l_N{NL29 z4reX7{zcqjy;zZ;rot}k_`=r%#>1-;s}rX@4k1h*!AKFo<}K9olcQ$wPUXx!9)F{ znQUw%L)+oigW3j<9&nIns;Hi{d5`|2aIdGGg~4=pdEa`i_{MA)S#+22d#Wu^$rYR~SYeFYBYeuxU9Fv^oY-2&5sPto&F_HdRGpP~n zeFC_|l#q9?=f9l-#da&|t<$682i7b&P&?h6D9>Qgm4zFqIB>s$)q|g2Ph}1F%(#^C zatpbg=dqL&CZvK^wY!38dEZc87~HMpx0@HH>T?tL?_S)t>w8tLqW=F!V_BDRSF>@z zTpeof$epylE2FNuk4?sd27m+~-`UcN*z?z$rQW)bgK4tud2IbDpKS zhtkP=$Z_R~5XO$ZK<6=l5*6~Cg%IWv0YE9N%g)X15AdU(p=tfe$HZnlSGKPX<)uD< z^D;(__fxH9daI8?hK!tRrjN;FD^V&_CjI8WVEaf;pum)5jS2*D&^(&V*RjN9Jz_>m z>B?c802{gqIuQ{}FKKjt20Z;uWE4E~zFp1z-SYqF+o1UW_^VOiPiQ)ze;XgS`R1sI z#z~#@MuO-v;L=8DW?r6ed(zL~R9Bo{e@IavJ7y>+(6h7H9WB5UQJ1b2(Plg32~mz9 zJhJ$g062m&bMK~ZxThUMM*O*T3y$!eM>oPfgCzj3hsW9H=l^rpoa>q2LVKf|Z3k7B z9(@qtiLOq+1N>JF^c+3q5*z=|U_Aa#6S4FLa~g#E&u|R{yz>Al;>PP zap+Qs$@yB_^-Yp7C_~;xU*A`4wq-TWJ9tZ8;) zSv<@UKBew10(q>Rq3SIc%%#t(u>0f_YbRQMqlanQ-%Fi-@i}(yQ+$OX^S) zf{HiY*tfV$dK`}UXO^J7zxGwD{3f$7=zE;yI)JCntaPf4beoG)k*?45D7r6}P9#!b zyq~pghKiu#_)m#;Wdx0Q94_0QlRu&NeThEWoN7`F+^O!ej_)&lJ*=`5{sBZ8%=teZ zKrgtN2c0``6;(@*%x$&hX}X!N_t!$0>;J(}tiNLRKjd};r!KS2_LK-F9)n%qcx+aBxJQ0~%-^j9<0&reIgN=!vTh^25(1>^? z*XfWZX3t7e0Dn2ZiRg!{8Qe{2Jwa?w_64+Fb=mYGb;-& zWkq|QNGy*f%`W>YwBSCDDi0W9w%tzxwBXKLBbT-g?$NT#i;4PO-wREOxEM=wrU)!P-!1Jo0Ag4pJ5P@Wk;(+Ikw=jPm9fd1QgUPm)whMWw_ zZB+hcTqxb6pn7B6hy9O+#RUON49HOpYwJN-M*bR*tLlojw0XD0G=Yb&fIXxJ)!Z`; z{mEmIY&?jZ@Lv6;BlG5TynDM*$DYjaC|g>A z$!afZHa&bYP3hKol#`x_3h+ql<*n5FCa4(=U|;MwP$iVsbvOM1 zzluy13RyT$b8$fmGX6f4n}x`OFA9w_P$LOtY+#q z*ev`0V-fg0BH2BKuInb2`q=+aEdL%ua3O-FN(~5$+P}hrFLMpg5Z(%k{|#c+{Ui=& z9sqf|zmV@y^t+%d1#!*%`zfdB!g*SSfK~f=@h{I)&Y^89yfa;J^N*t1ekN>#*IE0O zT43{nBkf{gQKzOy((hNDEhOOAG*%Vc2GbDFG3u=z0QXJ;ogMqxSymx+dS^y^@km84 zQT;g8Zr($gX^-XAOpiA@zv~%LBkHRz=Bsr}W-02+k}Dp%GPMA%C%*oObptydEep2v zAhr1Sq?;z9pg##>-jBSu-ZFOd@Z31tG?A;z!EavgU`1Y%fLqzf+i5 z#ny9PAMGCeSeF0FXUKuYtmF^UP=R+5@l^jkQ|ZJqMd+6ywnfpS{ourB1e^(Yy981) zDb(M>T>7olqsPdgWw=o*@Tb1byYgQsKcl6UV^AQ%O-VD}nz-OW-DtDC@W~Zfw)`wW zpjZk3M-N(*r<3&GlbcO`veFbFJI6zeLDjYk?|X*&9@xsd&%L$KzT7~$I#7}qQ}*|B zh+qf901SX_aW=n{l(lnI~1gwy;j0752PdA%ftNUz0Deg!+FIk%^w;_qBIJCQ0;Nv$f^kJu8g z+`O*aFhmEsJ+z3T7Z4lxzXcZhuNqJT?$~8{ubXmyM)myl+Ut%*gd5n=N>?V-RRj}OL&%H zvn<)!#9MLrF+~7XV%X39Yt#F0lAvz?0}5Z+(8nC%C4*`=*Q#iZmT-!TwJ%oc)lgqb z(o@}8;Xnv^^d$WU(Mu{$DcMNKWv~XPg_&sKjayO#3x6B)@q-D6jlx}q?ix0Yl~07W zMSHwjj1NCfeODZtZ-3{BfyLRH$hs{f#AGM`#ScIpU-+~ck?c91FG{=`j z)&F9y{E45N_~D_~Jy{=Y~hjh0|&+V7i3Nb`rIeSqx&e?Q#1-0esm z{*zMEflkI{{B9nSr2qtZiQ6lsH%$tt03cQV@(oCM*M*x&Ilpmakv6t{sz!h!(@ z0s)ZnR{%6V(29dT`kfne_Q=Wqy-tpHN=_CuGN)GLk(Q))Hng6ulSKc{>TajJ#14?2YyL;ADKf(3C9FiZ zBmNO^FKJ#w@BA*}X~IaAl|Zt+jG=$12ZaRwHDNWYLkek>I8HTc+mhGw8=&0~Y)o$LF7={keuK;XUPFKRK7m^NM`3g! z`=`|V=j!MGuxR>!oBfwMvivhJaEt)_&A&`L_5C5!|Nn@GnE=hE7R(;g%XXRv>(`HF zc3&Fszn!G0_R+x!SpiU8Z;#aZx3BUGVj?Lkwl5=hw~R+wNMbW$Bu;N@&(>(Qp6cqg&HFhr?WUUQY4Y|@WRk}tR-m%<$Tnlq zgRtuX9|~JaA8gunEhIr>BKIdBkr!#@cv2np_bEPduxdundG1bo#+S6|nGDeCm+^wP zZ4p*Ja&5ys7d9go;M&qOhn3gTIh0)wh#=eFTE7~~`#W%XA zw@Iz(DK%7q1SF}OAeJ7=IJC=ym<@g3S4vK`-&QXiv9jLMVh2lG*(QHdD=CQa^U>nr zZ=8(RjH;)L#*|*ax{A@7y3u7>jOb@pkW6ZYvd+d#8}dH$0$ODorY5D23PCux*9PqS%S3Mnx-yR zaZ!`8Yb05@Epkh8Br@m&LpTfa<&gh`E^cDy`jvoeU9|bHXf?3!>f`{?t0{ee?7DJ~ zBD0h3Q#AIb)zm1++f&XzHU5x4ciS523s+6`^X^jzM_eZCd#1u#A21$zSaxxAUf&Vu zPT)JE64EKRQ24@DB35Szv%9LQB0d#sr^|?ZIniE_>8kN-Iiak<_FMKP{c(E1Yqk!) zyCfHCzj=SKBa||RW>}3!GWO#8ErY((@cA!F7_sJHD5<RPp+IDT9(*!vvj$fy z8Zh7R(3e-XM!KR^yPVg{B?xUiOVALJ6jJ#_JfBHt!7bpOVT;YH;}nvss%z{0o~iCe;QB0BYeEwUJm1|R z9&Zm8;q8>%DDJ%kjFvGNPB~Hcn(xQZU%Y+Ibl{v{Y~BA%?iD7AyVNW6Wv5)x@_gy0 zsfLzMr!$1>8XDvnSbH!~fGEuD*}c6Ne{6Ll_8(m3Il5?QRuJ+Ytc(aov4P+vf)920 zT~6Iz;M-QhmMR%jQ6`|U@(*oG1Fe>L4(Bn;v39Nta{x&goLY2HVKkYwjfwA+8-2DB zQ5Wsh8rNrpBs3bdU-5C;BiDE7%DYRv0SdA$IEd~ywiEhTu&M$~!FCuEyB_tV)-roJ zp2T`hbUG|=ZWx_j7B?slD`}Z#NpBr{>hfpyFW4<(X|~V0YZ#rcaM&Zz8lT##ncLQ> zsVa3@S#;QyOqmKhj#AdmRNI-HFQfwz<}lFM$k_A;YvS0e2b!Ti96ox1C$d}q5T~)B ze6;&>glb|_nRfjz%hvKGgYdT3)quS*=4D&7W>83TV4IQZxsU7>V^lq2X^Iwhxj-_1#(=5pTDW}X+ zX*QAB{A6$75Id1CeMa@D^+z}OSM1RP8CmyP%_9?JWREWV|L7rzqi7UP?9aDkfo*g+ z*3gVqlCuouLCFCeo~L&9V~tz}mucY>chVhQ#lhu;oykeEj$_YVjtju%)T^j@*p}MV zVj{cJwQW6C%2sfux^Y1m_$Df^eH#L^ugMo-iHUT+$Rvd=Dd9fcqi`sl<1{GF%^g1+ z@bm5&sqnU#A{`JnK?RF%iUpNJnPr_OUgEZPRwvQ1_BAYGeId_4k@8z#%^|U?senNp zhak5tIUM(Gw+&&!^v9@611;{`sohOY z2d^%2xo^h^Xhr{;F4_<#>9i(FW*NFH=czY9G{5WKP<>lPtHDX{=J^=7F+pZ(KHK!Uc<#2X#*=JKOi8BKLo z5x({l*5IK{5x}jNy85xaUZ4-`{O{FO#LrfRZ>8rful$MS$y2g69-<@-^cqs1c+4ySdQVD80_md+QHp_TmByS>~TVT3USrhO$B>rI*t7{lce3_@qSfl5x`R znwpLcD)?vD?3Y}UEz2-4^d$gOUq|tyVQ?>L2EkoFVEM;ipT~y0VX5A(E2f~$7VF_~ z;y}CFfmAc2XrCB9#4S)A%o?AO^Xh9+T|%A0M((`ue#~i&7%DgNWNPCXC6vr=l7m)J z4x~5WSem|)T?#IBE3k_qoFzhddnf6&x*j7-Huf_O*HAFvjC*Q;GgisH<^1GV<@PUr ztFwYJ%IIC9jBU21+At@Mo$xTGE592|gq({j98%iTm0WM!_T=|Es5Gu?uO~v^#L}SG z%*i=>HG}kn#NP|MTgz|wW#@LxaN)$CJ!!|@ru;H|1_;*zJ6Q!H!eFrXAN7J zkK1cJa05fNy#S3B<1=$|gs2{CZ< zJntt;^i&9qnW2JUr(uvSN?6Vc{E>Xz9uU;G9uCArB4-b;ke*O$23;wjymxXNRukbQ z-$|Nk22c_4LPdz34KX#Oya%dCaR@v-o!U9?BUf2C(Zn0RShAoazKjzR6@9_*x$~cf zEi;HMUXg%T3Tz}94v0AF`F+;U*?82i(`e3Ho_W^GOz0iGcd@rT5< zl_P#R`z1psUF2Hc{koIvhdZH%`taiI5%0-@H8A4w^TmKtYD6Lhu6V-`ziBuT>rq@% zvTLYQy%hWkPg=l7O2Y9M`q!%*Kd@zI4*mo(!4AAt?y&dmKwy#I^Bf`!bfc)Z4(v!& z=gjXcUr@CzVBf49@($?s@azhk)b=vjl}qn1%y|(cymzIHn3or4Bms_Z z?N0OSW}Pn9)pErCHnq!aha=8Se5H4#1P$2i5=isx6_Ht;H-IhSGbR8O_>O2@(bCBJ zGD&+}JBe_^$4GD(%tBsM!KPF)!Zfw)OVtEl8RwTMKKAfSEhIk6e8cvY;i01%usDSX z5nGbv2YHh_Jh8qEDCZa&TDFSf@lgkwi<(s8eDuNjEhd79WqQkKb;pugWpVmvN#ywb zCj9;gH^|sk_XkGsVP5WDwoP@&URc?Fk|;{#EM&J4bWz|7kZ=6PbXkaB>rw>5{MJ@L zX>rkOJCmVJ;Ne~eAfwrg-mrVl8-*BFI!(y8r5YM&;f5;$W;?A<1_$@zrt3(`__B4-;s*(4VHqbj|M1dw|%~VFFeA08Pq;c=oFK#}`{iHyb(ol?_I2v4WR* zNT@3nwN!&H^-aU6bV@#s7s6D#l8p5hSW?_8^jhf-bj@eI(B^d^rB zh_`a9w6jGL3v?_QGkvWDzprKP7%We$u%3ht!S^#{^3?O(e-&k6QMirNhcj}k)t3hx zd^S;#2ng+gFGFZ6U6!>Zpw!})X*Zz-=O=|Vn|kk3Sg>$6*;j1#I>w!%rkQ>i_8P>c z71v(EA`dr$NBC9d91yqFU6}=nYHrFoX)#ULp13!PwW@QT@6IUJele7ow03NO}DggYX5?t6W(#Z-tf##EYW29;Kr zq!S z?%q`#OA{aO!rNKkzmO#1&LqvSzLl%A&au^lvT*MpBdY?mj7k}sW|JT0Y*gFy=RZ$8 zu zAefkC2N;VZHG_~{(}K%sN^bsluTM(U)oHcL(F{fhEx*kxaXdx#IR-GgQOu(uC_rQV ztLKyg(}B1N0l~`58%1pRu{7&BHhKSrSIlRODRD)$29ODOOQ1F?Uc@Vx!;Xf`l*!rw z%XOck7@wqDH40GH^1yVYG~jN2IH@6}u4bR= zJly?44r(Y$SaKGsuzXLtCSr_Ycd<^HcgVHRxbnHGkX(33ni6b5u+jyml^}EVnfjf? zkW&fiFgMMhuYD~I^#LsKufpHXL)TN?stMTm6XX{qbj+0DJv%3>I-&0MO%^;trppT5 zjSG-NuiPUzT`WR*b0Nrqessai17^w zoKjHfis>SQJ*pawJgLA$A)`%PeC@n?KV5)*GB&1DGQN57RhzZ6J-#!z5krqO{eTRb ztP8D+ZA!G&hGJ_C#OLAhWuclp9mJG4rs~Z*oQyKzO-qMb4O?zkv=Un&}OOoCA~8Qa|Bu;^G-o;(BQJV0R>L zoY>}lyAq0uSch#*PCh&Bsaj{**@2yj+NySrtp8qEw1$h+t}J&i-PQ%i5PYVsAALxrdqvjblJI@aB}31Q#k_1GFSl*PezFt&^7d^|AT% zvKlLM@BumOixJYei;cB&XZHE$)}c5l>DYXUI=Aa*vio#(_`BQaZDzjot12f)l+db9 zNE9(k&%vH`KII~h2Nho-Gi?C^cmq|H;(8V|#o80bb8MO%1e01WUEnvKPVnx?(|#on z)|0Nh!%-KK^^gLd%FnNAaP`U%SlO+@bK|xcy2f^)Cio=yM$tX?YfJfZ5SLzCK5Q>- zlRZ#2nMhMQjf}rH!q>pc1+h;oMPCdOwqLs5W*M9)U#rwpas8txq&38lZm`3acMTKk zx1c@rp}B;J@`6}%_@EOvm&Q zS?SQKCM&v}4WGrtn&4RtJHoOTmiJ-AE$hegMK@NJsB@DeFC#6B*o2)eu>0-P{=GO7 z^=V|>PH|}M!3hKZhQ%S&MB4P$obhe0Qu##(j`|FCx*0FBT?Hl@%l%`La%Dje6c{Gk zWIu|g{}?Rp5y{oS?I4hWU10Q?$!M2#0(d`nQ-bN3WL@iZbC#xN(Cu4JWY3-2N3cfw zl?mG8(kWlV*g6aN6#_nT7%#vSoDP_-Amk+7uwxWE;fuVdmxWBdTL6&BTdEdReHIA>wRaRUb@r6t^M4ju;&sG zNjIaQ>B!>3M!p7Q*;!6lknQy=2j>lK6!5nxy(pCyjKwt|BLmptHB`a5H_~sP??A2G z*~57>3W~MqRIl|`lY{j3s7uV*`>|8i%5~MDJH%7=f3SF>=?z>60EM5aYne#ntL9#L z?8H%LX~*}%KHU}?B9Z>XY_+?pHN)k*8nkYyn4sR_9xlSy2c1NHIL^lz*luPq9qsPq zd)K-5=`uR88yoTw?%TE1)hm^yGWwsUzIJF=LI?a^PP`3l?%P&t>W@Q{7l+QbY4JSW zE$GR`wv~!~E#-IVfol0+-y>|?R>Hlgx6eZx8ltLX*{C4tjjIN+7Y^s!Q|uryu^2|_ zN(`EUHm2-swnNE$CW_N!luiDnqV%gKW$twBYgakjhUHKvieWmwL@yCOFnW)oCXF71 zeRQEP+u{?ky|mzw@fFV!Eg4+iJA1J6L^9~?3&CUbENGbVpA3N2KxoWoz^eSq@JVPK zPSsFWRvf_K1;mhc&+zQ58iW?jzgz7T5*q)!7sgu{?yGgv=p0$j3|5p+zT=R4UvJ2_ zd-)0aRNSKq%6rv_CMAk8)5I`yuJq5kofmFj1S$+UUMNcWVk&vd1wmkw?UA#~3m@W2 zf%O(t_PRa}O{?ix5o)?F0J+##$cM3RXaI%8kM;HXQM3%d{HX4EumBN|ZwlKekVf{t zP+cjM5-k(vO25%Zm8slCWn|r@OP&c`?@mP1VJ4a ztE-9nKt5dM-~>Yc+q13-+~m$F{QZq9a2^Fa^yaK@LsC~_4a7Dz!kkb!>-mPiyJ6>S zoKLszp&0A1*FY5`*5%?G?U~&y!?qGxUM8gJ8`8kut$Q(XKHQQ;0YHu1L9BDPv1n4d z-_={cbx8BfGC7nRve&bytcLMhp*G>A;?>sTc@!NC=ee*3PmB+M`p%dsmr( ziIRj0cyA488z^=v@>@{ zx;Me$TJ0=vC!z5CcdeihrtNDu!wLS&B^=REkjQak>-ZqmI-$86AB;+}@G~-2*(Ydh zz$r9+RO>Id{c>#T4(6H7Le!^u&y#N(>q`fxbkr>&J6jt5`%KF*mAzTx$ zVo$~sliXhw%!oWaTs-T#s{o;rc^LM?to1*cwNd8mF-N>oh1l8z1FoG~G)KF2rj%Kc zJ>Q(}Pn!;aKz#<6WmovU&W%RcdNl>Z_2FVS9f#v3wKb9N+uyAs@gF?4IWsEL(?ZkB z3MAb&%)JrK$z2pzNFN%oSKy7ri2>zwaSFbTt+c0`(^5`^@(<_sfb20=>K$ox-gf{N zHlD8@;K21MmQc%O5ALqYA9hc36%>aEv=AF7OXLV540~ZNIOoOUnfsazw!Yb7;xs#1BQ4WkN{%%Xkrn z%h8`qO>&t=32{%^xquA9+4Y$I52nQdI>eic>dnIs;Hfo-k+*hBln_MK^V6HZA4jx#!-f)G%H#@!G9%We4wXz_`Gb7_R>Usr&PiD&mg%$^7Mr0s{{iZ1r!Jvr-Tg|@w<2gs-8d({v;(^mOTHIJ zXJgi4&dxFBmO@Nv$2uyrgIDWjb3PM#=jF+lf?hD|TK^TG@2_3Eydpqwj6OwnPjynk z#}4!i`Gx%Ji&=<;XC~3%%jZ0&D2j;}RE5Wv)l`bVTt=-(I@SV;&(`Q-&lZ04xE$%#kXP}55rGK_~P~Ze}n>+6<8`a@2ECHM#j;ObuqIzI_x1MQ`5KTVl&r@lSr(ntgWp@7md)L zmvCGBkS*&v|NeaO!PcPfu`j@eZ}`^k^?I?4vR;qM zj?djo32I0BnoQKcV`tFWAE{-z7Vp0y9Gjng&%dO$ie<(@y&Vao6khsn`SZ7C2e8}H z05!i_SQl0${3G9=`ybUWGRu6DRfLY^F9PL2Z-&DcZwhI=9^Z{BCRGQ&TU|qKu$n1E zSp~5bgQma!m|4UvfU6Jp*WLGr+;+u{IyAMqlFU<7ztPSYgv8pHHb7=C8}>#Ow^|A< z*}ZtGI2bxcAHwf4*qHkR3?9}VtO~}t($I~RFQDayTl1tfa#ScT^(`)V)!~hOAz0eJ z!arr{F5Wk@A*JyxvlqvvKWli#Q8S1%ZxW^t6w86X6J1u|6m=(Y-;xj|lJV?CK~&l_ z0K$M6BT!>ODs^xf?uqgp9d%t9x2J3RWqBO9P*VCnXc?aN;2lk>d!0~&E!ah4Z|m05 z)qTT4vnHw9P3G{z!O{(_9IU+LPq;Z=Y6gkjtdNdWHMG4HzJ3jN(NVj$seVT-$ou&S zUm(lJD1H^bItX;J{+Aina#;;x)sH(7W_2*XLlp z$$_Qf8Lk7}nq@6vrnJ*A0Ir{IdPzA!6c0Rw5^_Q-HQ!suWYw$mW!Gnpc~@;M5Ay^E zj|g)bzcev*N*glWRTyLtWm^gu*wCE2HK*7eGa=3=b*=8=_nyvce8p=bdieZyZ%5vzSg>Vo4+^c-E>fz#re0G zRRygkR{!Zgszj0Uu)-v(`(J=smNzItNH*5_@P^Q*^_)weFJUOhcwL^)+vL1%!o z0@srLf5RMR>sKfOG^zJF+qleadB}6blVI#vd1_p0*6-!Uu3i0_l{pDP^q`~)tjqmvrZVwq;vjJ1wcSQ z5&qO%t=Prsp8ztDdMKj4xzB)KOEMh!mb_L496XzN_D{`)gARLYQB$DsFfSg0dd%&! zlj41w&RPvgwflcOw4XMxa2Q>?Kz5Y}xr9Fs9OJ!U-TlLhUwh2OVHekR#W%}AE zSzuOA7a3P)Upkj&(`K$%>&TSBC&xh?7t)VPOPw*#5sQouV(cbYE-uweq2Jv^tjZ60 zbqPogZ^<8o;y2Xs8xAA8Vu8bj6KxM{na_uV~fnPiUoDy9C@m{#F z0%$EF3crVPKoAESvu3vyyRkqhzP~YoE?39NX{6WPb zas6;-2bqC8=tGbYuw8W_Kd!@hfdu2?-4aOYva24f$;;1*zg9D-JImfOZ2kR!le*YI z>lucw;cV9)quwOzOHT;WI~cf8>6HqOtS@Owtz$9QL^&+~P_>W{IZ@CK?%_KDyFCjW z%0=-{e;cn#*G9tE8o2Q5@hd))45JdBYbh=QD;{;y@clZ((EJ!nSXi7^xrs}aG*w@! z&lRMm5no{9>05YfZpl!-WYe46f56ntRJy|MO-{B}EK5YNc%@^W$ct1Xcsf{I(sp&N zpM%dtJ!N;WY`q*@NLnl{vtaZ!Pj%b&BhogBWtT91OT@#bpr7wBdz(LO$dsD6ZOQ3|KMbpKFiM%&`0ko8n zW9{VUS8l*8>*WIVdOEjSo6+mV<-$5;8W}R(gMk-_aCIi_kCDsoq;rlEN4Bex(ktaU zdyz|nMFAL0Y*^d~oVXOD(C0ZH)}kcWNKbcQrH2^#Aj(Jj!u-DamIVL4pK+Oc-&zT8 zvZ<8wl!^nwN6k!Mw~H-Z6s=b#;qlFMC+7UKN%nyBLVgYf;Rf%sVBf}F<+SA72o_*P za&n&uc&bBXDH&{4Hvs{6+;0kefH1BVl+aUiP6U;{2)(;`?oC|YzF+iv31OK5>^}aG z(7{TK+&tG|lxYR_%IDV%8u_yE*#W{C+^86UD4j{;$h}1l8^5&@Bki{M*8Z+n7*O^n zRy3ZVlo^9ZYTYy1D}WG1&u;D#kSsBuK7_^D3{Q@PQZFeHD+JF!hhMoF5xjgSw(H#F z&U@yT{D)Lky^5x)WksHqDM+g=;*`+G>;6s;aCd-%AH8^W9`NG;Ov7ymGk;66sN8(| z;uh)4=9f`qf%REsUMXqfzp5cY2(GD=w;leil@L;=~AdB%H7FLE^rJ8{iqXKbapEftmf~56D zEW#)n3epsX77$c(Dukx~chjv}_+FK5DM7YgHU4eMZi1sVGrG=?e?wbAk{~DJK+ zaq~Kg_JX*j`$4H}?Gk^f&R*HrlbLeFZJT2$?BW9>tvy$bmu;knhXQd(JvH45fM5w4 zKt+9YKY4fnB|*I$ba7M0C?-Hl<`q6p?s%*MPUNmVIstlW+dmV3)BfvqcG~DT1ZkJ5 z0$6_Q45K^#qe=TZ-Pki++6m>;k%mw9=?~DV!5YOPCuEnkl(sLBHx18uLn8%-&Awe) z8S-)M4;)P=B-NF9quL?f_IK?HkMNE@@Uqq)&}3ysI; zxmwiEr8k!1R1MBgCM8lMSfG_oT%LRr;%VuZhB;hVLKZ?xX6@7kE40_bIjZZ14O8(? zapEn*lw4O=(!<|O%3dZU+VdDyNX)Aii-gAYJ!STt+pbg{*}X-GyOrDIr+6_ntSf`v zO%z#-wUT|?ML3E49HZ^yQ#05ZrJn5k#OthzGpqb8%>gZVn#~G)mrH(MFFknFn?OFg zZU1h6OhAD5O3$F<+(2GlTFs>u{ny0L4Wl~K*agIw6wIc(f-IV73Ef^r^Z0MPzl4up zn0d0TOI)6vcc<2siljZLZ@s)-J`r@dg^b_b7BI%7S%hKd?8`&s_wU=nbqV3fppwO* zlJ%oo7;WAo>jx`{(G_jdU^JKfp1{bIz@?Pjjvzijfj|`%3&LI@Vs^^2POi`_f7?JQ z!gyTOo!6!pi{lefwrXP|r}rZp3`U*}%0t`x{MFa*M`5R&t$e`lE7|KG;PzaHrLRi1 z<;6K$l|t!m=23&RxH%}PG#bsmQeS52Qz_0b9gV&bo3B&)p;Nf+2~E-%`(TNcHC1~| zyGHjN0NLK1;?`=&C&LC$2b%)P25`CG2#Uz~F~Ux=fe ziKB$Jp7k$rtT(xY7udMw==$IVo5Hp}g0ex9OMY%qIbm<I)h6nN6>xcV8mWT29Z$M2j5G#e#5<6dtjs*>BU&G`6S5%HNP#EYbA% zfw+&0wtcEAWJ!u`YYrDOsu9bAjI&V2M14g%wt+Hh1 zPwyP9PkTAG!0hnmw?f=P;^Uw%?D*d+x{C1a@lU=;3r4a810S)EYk=H@Vrj&iZ_$eI zO=J5UIm4S}463CglaTkSn_wFS=}-IgU7?kplK34fcPl&1QA;v+|y+VmBV$67e>(kvZ9^`g!E*9|%1pr!cL z0AHF!B!k+5)4Q(~Wv%9Dxsw!Vv)Sy3QztpP@BBhewYp#T?B2o?@Tdw8>M(QlV_3aH z8Iv*|{x$L5msHQ$D?>dp=n=7G*~fYH-a4RW=!iBnWLv5Kn?2&39Gk%zS9XBZaAF6E z9y5Xx+pt@8THkCJzF166+-K4ZGEsS;y^)MHt*iePd~r;$68~;=CvE9t|C08!=|BPG z{(xm@2X-U5!e2N#Wtj!K1Yj8k4eRNX0?Q|NGHFRgD_*J`i~x?n1Qzea(pZC9<<|1X zjstf$M@ix8Dbd_Rv`q7!M+@ch%QEIne5v%FDI z!*(HXL4Rbgx9BwtZ~TB6w(;QLxS+M`9mRr&VLC9oZ=7gJSFVYj4JLu+1`sNqxizRL z&%FUY-DrOxNqQ!MWVV+8hXz$I!#+*Q^v)~hwBPjiYJJ85&u_c?T?6oN$^}YDBVA3v z3qvBX_eSn_4tfxeIkRO|h>?n(K0ejCz0w&jcCAm!%o5h&G0<{>#*HPjD&w)n=sP_0 ze*)3GXHPxayciBWKT}Tme#0V`8d;mE!e3dibJ++rIhLWT0Y{*OD zfFyI)))1VLyLyotWY&K!P18A1vnl+rEsE5%vM(@DRL!TB_2rJ>r6kvsqo3aq%Rm~p z?jdA*$~*33CTh0Ky9Y-sd&um-2|GJV3Uw13l!(1>KVlL)SF7=Ltv{Cg6$)4&pM#S# z1)jl1<9WjX<{T(cPjYYKE0Wp&Ry7bUvsTX@Ysb_?3IFC>6+nq!4R#ok8f8usHCUK_ z7NsLA1GT4AC-A@-K5RI{4>!sfx3n%DZrU~TomVDwR9#S>D7KPSa$&kO?|V2xGkVU9 zO3@u>$05NplPo|PHPZp`BvUw!`flAUHPyl9*F{t=QL}Mr|G;E9e{ttVX+$rRz{jRE zer-H*hH)h*Pf!U_A9sg`!>QLZ6(c^w=(}gT2fH<@wHIglAxKeJEDaV!bnSRCc&T{c z#L;b-0rJxhx&cD1XD_;@ZQj1Mu&@*xnb>R5+B!}t1reo3u@ zMx}+_z;(zf36tqFTj+*GVQRb+Nc>4?sP_ihu#wNB4aL~VbQauVECOptZRDJ>zLirk z!V=}eC0el3NTk2<@(CYQ%w8xBf17(97-}NluOa8MuxJ&EE}DI&0UfX9ef<&zxqUp6 ziAAZXvvl&5OMkQHQF4J6yS^r6MZeB3zp=LlL?rQPk!Is#x<~VsyN>Lh=jSm%nrD>W zCA?fS+F{I`+{$TKJgA3hgYNTHd#n3sIi6fGkn`d#=3c0KObSz7uXjehprxO=qlP0Q zwzs%QYi%SF7k?B^sWhrsDNtAc#ysPZ(z1!6+0M=%hj}NH<`KdlQCKa{J`tF2B~Elz zY#uo}tZQtkyk%U(dLRPgb7;-pKMisD>I+;rFWI|>Ym^OH*#I$MZvLbK%J||SJjHv2 z&%ASR0`nHVCoJ($Zfbw7eF`cIZnkOLc4>?fR`MqN_mQ5$N{e;E`Qil-=fZI?W`plRHZBY5G#H(PnIyzZQWrw^6!-5GD4 zR`{o?ZmmAz-1SM1wn~miCMXB;*N2ZMl8%U3tVkRA4r)?TA|2%%q5x9`!WXzTCHdIw zJq6M$CbFVS*+7K7ZZP|Ki!7If(K!*cS(j*YHho9cc=yIrbEd_$RD4=&WS}vBtNh_U zg7hUw4!S}-T)vEai{lu^4iQHT<@RupRO_?)nq3oH`5(qUmS*hM<%p%1rSVuzz-)!2 z^G_<@c~-aN*s6_OGbefi3W*_mAlwSfytCBw1R|1=(sQKw>G=bgUn?|xih>NSVpj5& zIpEqt(FyMk?i0B#al8vsk_4oz(dgQ@D#|i~A;1kRDh%uILVc!;SG@WbOtzbgu;>nm z)dLZs@y=)0EdpW?=XqMc%(%$oU4iwYLEs^1dg;C|POMWZwQi6JZSZh^Z|8xOBA$2= zrO_BCo>Cp$yfdo;iUDe-?gQFT8+!Z*Jcewmb5kg|MT)HL6`!%j*S? z)OoG%$c1dlU_et_%6+dz2m!e_bjuv$98wu~6x88wpf4EoK72=6wH9hI2Yu1@t{-AF z9Jkz7Nno;>>fX@yDV1>W3VwZ7vT1PO}I~?mMP6 zw0_R+0cl(t(TSH`1d2}hS!K87uet0#1_Fi7IG_;5?F3&3eq90N_ybwZk+sMotGb8I zpE0j32-wXQ*C)Kv{s--r+S&!f^Y>X@Yjc=iX~zU}k9XEwb&r$edd3X^dk7o%7(%@w zg^nKdb>_BXv3G#qC?x%>Hk_ZK-J%QRD`^rBfa`1}hLe1MDKDdTZDq8+$t z3YJ6Dq1;!bjcxm~?TR8tZ+)Jn&7peElA9@9{Ww_Jq9gfXPbjjOK;2pK>f&K-YG;E= zo!JlbCkFu2-2I<3>iUGx`4C*hF+vZ2rWQ}iu5+pLZl5SA~hm40fI;g zflve_bd*qpP=o-XhVS6a+~+>`54g|Q^7F~r>)mVZwcfq<+Uuk(B2Ttcw}c9S6zk7S zqQdDGyg++vklf)jaYxr~sJFYRw7loDPmkC-{i}D`37_&uags1aDTk*a@f<$TvvQJ= zJa2&^{>Y?1vo7Jj*2%5k$s+`#g=GR6-Je;+9@%qqK|2 z#Dkdk9WbkZPAl59EoN|1g>OZyPgQCBx6P6N7dZj=0EbR&azeb9t8kvFyo?$1h7K5O zE7e?mYYo%*jTA~zP}trwJn;3nEh59bcj{n%F4Vw$95L+FRKz#sNfw>hO@>@L9o*W= z-PsPe@k>oOUo&HF`JJuBKO`($#6f3GgfDP47Q(22?5_75)Dy&;QiLPIL^)4J=?%xf zG(Y~U&*J?wr#Qi8O&O%NtY|WxW#K77N?2t3(7VlP7-Dn^ahcD)NI)%@B9UIVIK7&_ zRr_08$%`O+WhHg_yPKD4IOy0nq-sjxm5B1=uqIy8$ANP>+7sTd5TRvhpOjtXnP8FR z5Va3FF@ob~rc%CW+e!O$`>E_c?oQ97T_xoJu>pys&e%XFkR`IPD!a+b``N;iSM{?O zjdzM0Ilo^K4+fHKndJKr5`kVTN1PT4X#O3wjh|1rP||T_C~fpc*vJ5W!MOnE6FjP+ z&TE_`gMA&_2w{HR3fNDFwDkamN0(>@a;$WLQs)GSC~%H?ZS+gH!Rj!=NXJJNyHxxE zleYN6=dJ(lHl_jf$Y7E^-ja)cp_%M~_Gh=6R5sT*BR3Fr{Og>hIpR6fh>da!Xii1x=tab#1efYCnDUvGEoI^Ur zFy-CUkJXgHZ{Y*JmoGp~m+X7=nT_TYY3uI-U)zNLTsFJg5&bCO?Grz?)#^9GU?oq; z*aa!QR!wSNJ4fHOZ8a|s7apCp{FhAKCpJ?xXn7Ox#Ml=QKMkZrO2~E{3>GU6V#OJT?yNH|CTIGdf(5ipFHpfA>!l~A3$@Aq)2P3M^(pXlyhkKG83Ee4I zs3F>_a>HAbIrkL-+jnfY96WP;&KeBkKnookIM)m?7AwrC+26u{!+-CZNc~L$xA{2A zu-jXetOhaHJ(PYsTOOmQR+eY8eReGDll64wq3C!A`NUW}YkG)G-o^tm`0-%T2@%YbmRr!8e6{3V(*jz+s9dQ(+ecy8*{niHz`oek+H#%b^x9GJYR=c! zt=9XAp{(^$Grf@nZ7%ui-GvBEgV-Io^3|}db7@%z){GcedWgB-zf!-P%Ddd?T^6Hb zFBStASXO0=d=s%X%~v3&GB+0_7RRvOX((s`%1DiGWM#d&PSHw4*mM&wCz5YT&+a5U zfIut7s)<~)#W%$tLwzAncCGh_6EOk@1g@&Dll`gM^-@b2kp6lXqq=Ji*>stJ7XOGQ zKyImy{T6(HS@iomcX3W#SsossKN23PEarHrccy4^po8ENwq^WtR<-uGPa%rDfJ83_ z`~8b9vh>&{t-pZmw9I1Rcuz^g*|^8dwa&;l_c<}klxPPR*~d|KaoI6--OZZD z+95#0EIC9^kEs#Q9DY5}&?8iCo;Gos>NjtvP-xnxcEl4V4)3D02=P05bg6PU4rGgYer+6Y?p&_!VV~Hxx?n%!kh7S@2*6stbQIJ zI;htVm_2I1j{qFr(G$*-!AABiF+o$w>IM#k?jAqm3oh~6#XUPdr&}(jzNOPWIFK;ejbRja;Zt!d9PkbR)?pBrWrMO4p;I3(#a*`N;UwJ)C?GYgtWcQ>;0mOS&C#mXA0HnuA37RqhFnxN z;8ulD!;qQ3{_Pjsy3B!zk4dtY^eyWgHs^GJ()jqeRepN2x}HDh%9BD&?`!GDO8W{z ze6tX!^&M#O1r$<`T0QXaeJ^Mzqi#_$V=bg`Zf+!DPkR)V^E~_dS;d@7`lD_ltI@WA zogP~sGLtx|Rtl;WNSS_U_*YZtyA!(9<9TM#xugm5xYLWWqngHmu}p2%2H>P`oH?!U zDaW^%9is>MUY7R=ZO{6ohX zIahid8W^S^AZ*}%0NoaL*9jY$ynj_W(34G9n{fQwvrWv!DFywKd+`9ULPPV4(9no4WEF; z$b~^-pPxiVEboQ3@I})!5_MF{38vi!d!kny&UOjNp+lM)zv6{~DCm&8^&R_WV_HSl zwDpPnS70#!^d^(0IJal50HC@u2X1}Yu9c9b*$)!V*(5&in@ujrj*sI#exiuoAYI~wynO1 zJItiO9A()hk*S%-KdeWQS0>Vyjpypm-U%2(R7gat)*-qw9yq8y>(R{vK4B^Ffk;(qw(;uVQ`8ENh%*KpDggAU(8Aq|(Ru71f;XeBlDXPBU?<+iQ#G+#Bpv zy{+r*HqYVJV*I9QU9WbV=EI^13uEhy=UWXSB0y->#%;C0GmG<*c*KLeAkmg5MSTqpknNx2D=0KSy) znO(Bf$H98gG$|N)jYB%U7A%yuYzWn_7MLTDjW^(&m+sw2=SlDrubo0o`jfjnwh6ovz-`!Tqqm?p5pvF z2){dxG}IDJZE;!tNnx=7g-r@I^nQboBfq~UvkvL}vx!*=-hKe8#z*!1&11FOyw7v) zDv+xclvX-E&dH62l=1;zYKVyZ-)-z+sn7qIO?v9%zx$!tqD~g?RsC}X*EaKoDQl!} z;-B^{4}bX|)V1YjqneKglN0se}E-pH~6mOUm!mdheo#|%J#8xhk*ZJzy zEL+!^u3Sx>m}e`NX$!x7YR8ct=-to=^KQ!%`bDTob5F$B{;>w|LfIR+z}4pTSG_<- z3q5^TprrP#=;7R&Z~~M6wD6=9aQ%7U#YLd1{6FpEBQu(v3H`U05Nl|Sfg`)A9bsqKnMy6i5oL!g~9-IUthokpls{_ ze1o05-ZjQtPijk;`Ot?QE* zV7ge9M6pV18yl^6?{ueLl}Aa4xV21rPDJ%yaF;l~uq0>W+`11GT@&N`b7z3k zHLFHfSB1*o&x58`GBPp(Empc4>*_`Y)pZMJu2ufN!I^H+mlnfG6WVs9Do?9GHGI)`}6gAY2T^S(?P7+q~%Q}Zw z*37yPXO)*fqmjrDY`9k=fzNc^Bc;dyY+S4!Yq^A z`+-kK9Sm;$;$){#>8QTH)gccwlDaDhO=H#^7A5aFcpk!jiu~#8BWD6ts}@RK}6-6H}=22xZZb4;mwHIkv)tpjnGKTQ5FT ze;Cl;KXacfoDAdn{$(`*<;)8RqruzBiEfk@5tagF2 zf7XC9rQM@h4-40JJ(@l&m@6XcQi{P~KKxi%D7xO566y5KtA;m4<+>=+Q;UOxgG!~M z@FpFK-Z^S7C&$K8Dnj38;cz&oteHu#ZAOMGg6Ywo;>KSrvBKEzXxAHSd_-Kyc{v{( z%E!7&UiCi@voxO@qtVsy4_(RsXIM)?sLti+e$$f|yxYXlm5fh8qVAn3=2=`S_99hf z7TQ=tjGHTLJtfKz1mmen;Y1&_=%j?GtE)r}Zt6~UrdVF^%kpgsJ>w|443n8;_T1kD ztDHr@oDQsu!j;g|FOB?YmF9vLQEpOFwhdlfe2U%3&EK=ar0`uRe?xU1)Evb2z?l9JNQ z!vUN8!4VH+6q{gwTAZk9hC4f*S{C0qO;??r+837y2?~mF3ov4NHGiCK0S|@*2aihE zqtT5fOb<`J#hJ*+$am$pC@_oEmEd_TNy(~|qPn&hwZQ!~9Z$oah27BFaN6)%(a@cI zQz!QInF)CFT7Ehc96F%2ZTIRt!|w~m*MtmA#s1^wvxEIHzwGz51@aD} zjMAtmBhfngfnD1YzCEz4jbwX9inf}3iE$-nLw8cm(zza$r)F_XJ@B-kHg!`5$kT>wNvr%xaeJ4FxZ}EV(Ho70ZAbfjC!XD@8gB z6))aBk*E*Gv_yxfn2N%va+oD^JwYZs;L;cD?eW%fcEXK&Sbv|3)GaOYT+PWlRt}1y zX_EqF1w~&{(eCBt987SLJNxf4T@6-#B1`q+!%QdTvl!<-OL|PIFQV3;cd)vO1a;hc zCq^&>g`i7B%4OuGP0fE7Yc4^4K7emmyMw4EttR_@N}!r=<*4(+uT_V$W8>zYtnrk1 zhJx$EOz2B(hR&48z-rjeL@kB9gz!+S@qCn6PUw7$6)`dwBiY6$>^8UEqQ84NHr{^HM0E7|nfOHP|;^7D~aaMU` zULRtjbbLFcaUs%esie$>J5GM8^juri!_O_1M@-w0S~Ax&ne zk1_M{w~J8+H$+Y87pvt_I5wK>!eibC?l`9@@N*Prq`mZLTJ+F4!Jw8T)tq7{`Q59J zJ{05X^_y$j;kva2Gs7K6>>_Sk`fm*7O&64vikHlKl znNnT(-Mq=#ctVzpDRr&7NOe9==yL*LI!J>WVdl)+M*Qw?qF6|joy>NnxU?Z=c_?u? zRU7Fz1ET+>G_psIUWSZv8`Mc8pIW}=l6(BC)pyNKuZ>hv*uiS2rErXAcOP4}3_moj z#?Q+@1cMN*4eJkSSClt#)*kTdo7?4DxmSj%nX1CUsqi~11QoMN$NpJinf}@GWRy%; zuBR!*mXO^x07_}H7Vwv#tT*_1@UV{?>u4DMuiLhCWS@G`8N@!ib|CUN{~dIGLXkjNyqAMv&5m(QrOKq4#4wq z6uH{r*>?nWO5(QD#)$q;%W`8lbB%w}v!NE(Spt0nzc?H&C6p_EQnewz_0miUV$;_C zv&}EQY08@LYGJcb`7o*IrE{Rx)p^-}rRVCbi`FWT;N*Z!!X5|+T9!~7FY>w|l(L-0 znD6pY$s0o#U0W54QFd=vvbwy}u^(GINSK?gx+6$Nd8b<&xU1H~W_4a?_`Ua)!C9qq zj)N7a6LFNAaj2L0Tax|%m+1ti^D&G95xizUC5JQSNEYk9=yzT}vOlE*yr6=i(b*H` zuU-F)07E7BS#U$kUI}8X8;dX34A!59w{X-%s=cY()`?;YDM+Z``R#RrJj(dwozm{u zfKWu3U(EZ^BB)_eUf2@og52%v!3)!ISBiEi!ZLBY0#ySAUK7MW?0dVM+;6$;Obqiy zVo#0{HaGOAH`-8_;&hney@*>{Hg)%m4%#mMLu*RNH} zDaMkbN}pqcr1bfFWV%Y5$;5y`nykVzt5=#Oo`%8J1KLPm&wy$7C=w9HKKR-26U`*5 z_3FZlr-RbItyT$F+l_PMRvOgb3+>}Om*??@`z#tO`@5foavxIwtoXiH;4J)P6)EGh~-0*V>jw;S;9$VCITUcn`CoN&rx%wHU6{WXU*`KR#5k@ijAKOO7bk zDDCe7o3^PgQxzP)<(Re}ltv?&^T3-4GNIW!-sIcC((2h%zbcZg^B&+9-0J}*GU%zU zR4HlY;9(;gb7q0?+u?Eowhk-b7JjrI!8Kc*{c5go)}>kn>wIA~UJ^$_qi3n-0kv8mq4Rl?x{Tmw_OG}<1X&<)TwsF9Qm9oeiaq;QVTql7H^I;JgHlp(3 z>owSa^k}(a@9{#X+%=Y$mswY$oq$))0)IH9%l|*Nz9R=mF_5FG96a5?Hv7mCZ7qX4 JWg526{{zMimI?p> literal 0 HcmV?d00001 diff --git a/package.json b/package.json index bcd66c2..a07a29b 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ "printWidth": 80, "overrides": [ { - "files": ["src/**/*.ts"], + "files": [ + "src/**/*.ts" + ], "options": { "parser": "typescript" } diff --git a/src/prompter/index.ts b/src/prompter/index.ts index 0883cbf..c08f9f3 100644 --- a/src/prompter/index.ts +++ b/src/prompter/index.ts @@ -48,6 +48,13 @@ class Prompter { this.deleteStock = deleteOption; this.configFile = configFile; this.ticker = ticker; + + if (this.ticker && ticker.includes(':')) { + const [exchangeValue, tickerValue] = ticker.split(':'); + this.exchange = exchangeValue; + this.ticker = tickerValue; + } + this.promptForMandatory(); }