From e69f5c1e988fefc2f034ccb073748e087a1defe3 Mon Sep 17 00:00:00 2001 From: Jae Bradley Date: Mon, 27 May 2019 14:18:03 -0700 Subject: [PATCH] feat(inputs): use enquirer instead of inquirer --- package-lock.json | 198 ++++++++++++--------------------- package.json | 9 +- src/GoogleMapsService.js | 38 ------- src/LocationSelector.js | 47 -------- src/createDirectionsService.js | 27 +++++ src/createLocationsSearcher.js | 19 ++++ src/gmtft.js | 2 + src/index.js | 32 +++--- src/searchLocations.js | 19 ++++ src/selectLocation.js | 45 ++++++++ src/selectTravelMode.js | 41 +++---- 11 files changed, 220 insertions(+), 257 deletions(-) delete mode 100644 src/GoogleMapsService.js delete mode 100644 src/LocationSelector.js create mode 100644 src/createDirectionsService.js create mode 100644 src/createLocationsSearcher.js create mode 100644 src/searchLocations.js create mode 100644 src/selectLocation.js diff --git a/package-lock.json b/package-lock.json index 14b3b4a..7761059 100644 --- a/package-lock.json +++ b/package-lock.json @@ -933,17 +933,17 @@ } }, "@babel/runtime": { - "version": "7.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0-rc.1.tgz", - "integrity": "sha512-Nifv2kwP/nwR39cAOasNxzjYfpeuf/ZbZNtQz5eYxWTC9yHARU9wItFnAwz1GTZ62MU+AtSjzZPMbLK5Q9hmbg==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", + "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", "requires": { - "regenerator-runtime": "^0.12.0" + "regenerator-runtime": "^0.13.2" }, "dependencies": { "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" } } }, @@ -2270,10 +2270,16 @@ } } }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==" + }, "ansi-escapes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==" + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "dev": true }, "ansi-regex": { "version": "2.1.1", @@ -2285,6 +2291,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -3220,17 +3227,13 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, - "chardet": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.5.0.tgz", - "integrity": "sha512-9ZTaoBaePSCFvNlNGrsyI8ZVACP2svUtq0DkM7t4K2ClAa96sqOIRjAzDTc8zXzFt1cZR46rRzLTiHFSJ+Qw0g==" - }, "chokidar": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", @@ -3297,6 +3300,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, "requires": { "restore-cursor": "^2.0.0" } @@ -3360,7 +3364,8 @@ "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true }, "cliui": { "version": "5.0.0", @@ -3478,6 +3483,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, "requires": { "color-name": "^1.1.1" } @@ -3485,12 +3491,13 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "colors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.1.tgz", - "integrity": "sha512-jg/vxRmv430jixZrC+La5kMbUWqIg32/JsYNZb94+JEmzceYbWKTsv1OuTp+7EaqiaWRR2tPcykibwCRgclIsw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", "optional": true }, "combined-stream": { @@ -3503,9 +3510,9 @@ } }, "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" }, "commondir": { "version": "1.0.1", @@ -4116,6 +4123,14 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.0.tgz", + "integrity": "sha512-RNGUbRVlfnjmpxV+Ed+7CGu0rg3MK7MmlW+DW0v7V2zdAUBC1s4BxCRiIAozbYB2UJ+q4D+8tW9UFb11kF72/g==", + "requires": { + "ansi-colors": "^3.2.1" + } + }, "env-ci": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-3.2.0.tgz", @@ -4223,7 +4238,8 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "escodegen": { "version": "1.11.1", @@ -4779,16 +4795,6 @@ } } }, - "external-editor": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.1.tgz", - "integrity": "sha512-e1neqvSt5pSwQcFnYc6yfGuJD2Q4336cdbHs5VeUO0zTkqPbrHMyw2q1r47fpfLWbvIG8H8A6YO3sck7upTV6Q==", - "requires": { - "chardet": "^0.5.0", - "iconv-lite": "^0.4.22", - "tmp": "^0.0.33" - } - }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -4905,6 +4911,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } @@ -5650,11 +5657,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "fuzzy": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/fuzzy/-/fuzzy-0.1.3.tgz", - "integrity": "sha1-THbsL/CsGjap3M+aAN+GIweNTtg=" - }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -6248,14 +6250,6 @@ } } }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -6402,66 +6396,6 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, - "inquirer": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.1.0.tgz", - "integrity": "sha512-f9K2MMx/G/AVmJSaZg2a+GVLRRmTdlGLbwxsibNd6yNTxXujqxPypjCnxnC0y4+Wb/rNY5KyKuq06AO5jrE+7w==", - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.0", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.1.0", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "inquirer-autocomplete-prompt": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/inquirer-autocomplete-prompt/-/inquirer-autocomplete-prompt-1.0.1.tgz", - "integrity": "sha512-Y4V6ifAu9LNrNjcEtYq8YUKhrgmmufUn5fsDQqeWgHY8rEO6ZAQkNUiZtBm2kw2uUQlC9HdgrRCHDhTPPguH5A==", - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "figures": "^2.0.0", - "run-async": "^2.3.0" - } - }, "into-stream": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-4.0.0.tgz", @@ -6709,7 +6643,8 @@ "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true }, "is-redirect": { "version": "1.0.0", @@ -7830,7 +7765,8 @@ "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true }, "lodash._reinterpolate": { "version": "3.0.0", @@ -7844,6 +7780,11 @@ "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=", "dev": true }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + }, "lodash.escaperegexp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", @@ -8186,7 +8127,8 @@ "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true }, "mimic-response": { "version": "1.0.1", @@ -8264,7 +8206,8 @@ "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true }, "nan": { "version": "2.14.0", @@ -12001,6 +11944,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, "requires": { "mimic-fn": "^1.0.0" } @@ -12106,7 +12050,8 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true }, "output-file-sync": { "version": "2.0.1", @@ -12899,6 +12844,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" @@ -12951,6 +12897,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, "requires": { "is-promise": "^2.1.0" } @@ -12967,14 +12914,6 @@ "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", "dev": true }, - "rxjs": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.2.tgz", - "integrity": "sha512-0MI8+mkKAXZUF9vMrEoPnaoHkfzBPP4IGwUYRJhIRJF6/w3uByO1e91bEHn8zd43RdkTMKiooYKmwz7RH6zfOQ==", - "requires": { - "tslib": "^1.9.0" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -12993,7 +12932,8 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, "sane": { "version": "4.1.0", @@ -13497,7 +13437,8 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true }, "signale": { "version": "1.4.0", @@ -13910,6 +13851,7 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, "requires": { "has-flag": "^3.0.0" }, @@ -13917,7 +13859,8 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true } } }, @@ -14144,7 +14087,8 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true }, "through2": { "version": "2.0.3", @@ -14166,6 +14110,7 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, "requires": { "os-tmpdir": "~1.0.2" } @@ -14343,7 +14288,8 @@ "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true }, "tunnel-agent": { "version": "0.6.0", @@ -14625,9 +14571,9 @@ } }, "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "validate-npm-package-license": { "version": "3.0.1", diff --git a/package.json b/package.json index ae069d9..4660340 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,12 @@ "gmtft": "./build/gmtft.js" }, "dependencies": { - "@babel/runtime": "^7.0.0-rc.1", + "@babel/runtime": "^7.4.5", "@google/maps": "^0.5.5", "cli-table3": "^0.5.1", - "commander": "^2.17.1", - "fuzzy": "^0.1.3", - "inquirer": "^6.1.0", - "inquirer-autocomplete-prompt": "^1.0.1", + "commander": "^2.20.0", + "enquirer": "^2.3.0", + "lodash.debounce": "^4.0.8", "striptags": "^3.1.1" }, "devDependencies": { diff --git a/src/GoogleMapsService.js b/src/GoogleMapsService.js deleted file mode 100644 index 5cd6633..0000000 --- a/src/GoogleMapsService.js +++ /dev/null @@ -1,38 +0,0 @@ - -import GoogleMapsClient from '@google/maps'; - -class GoogleMapsService { - constructor({ directionsAPIKey, geocodeAPIKey }) { - this.directionsAPIClient = GoogleMapsClient.createClient({ - key: directionsAPIKey, - Promise, - }); - this.geocodeAPIClient = GoogleMapsClient.createClient({ - key: geocodeAPIKey, - Promise, - }); - } - - // https://developers.google.com/maps/documentation/directions/intro - async getDirections({ - destination, - origin, - travelMode, - }) { - const query = { - destination, - origin, - mode: travelMode.value, - }; - - const { json } = await this.directionsAPIClient.directions(query).asPromise(); - return json; - } - - async getGeocode(address) { - const { json } = await this.geocodeAPIClient.geocode({ address }).asPromise(); - return json; - } -} - -export default GoogleMapsService; diff --git a/src/LocationSelector.js b/src/LocationSelector.js deleted file mode 100644 index 49d53b3..0000000 --- a/src/LocationSelector.js +++ /dev/null @@ -1,47 +0,0 @@ -import inquirer from 'inquirer'; -import inquirerAutocompletePrompt from 'inquirer-autocomplete-prompt'; - -inquirer.registerPrompt('autocomplete', inquirerAutocompletePrompt); - -class LocationSelector { - constructor(googleMapsService) { - this.googleMapsService = googleMapsService; - this.locations = {}; - } - - parseLocations(locations) { - const choices = []; - locations.results.forEach(({ geometry, formatted_address: formattedAddress }) => { - const location = { - latitude: geometry.location.lat, - longitude: geometry.location.lng, - }; - this.locations[formattedAddress] = location; - choices.push({ name: formattedAddress, short: formattedAddress }); - }); - return choices; - } - - async selectLocation(message) { - const { location } = await inquirer.prompt([ - { - message, - type: 'autocomplete', - name: 'location', - validate: value => value.trim().length > 0, - source: async (_, input) => { - if (input) { - const results = await this.googleMapsService.getGeocode(input); - const locations = this.parseLocations(results); - return Promise.resolve(locations); - } - - return Promise.resolve([]); - }, - }, - ]); - return this.locations[location]; - } -} - -export default LocationSelector; diff --git a/src/createDirectionsService.js b/src/createDirectionsService.js new file mode 100644 index 0000000..c7d24b2 --- /dev/null +++ b/src/createDirectionsService.js @@ -0,0 +1,27 @@ +import GoogleMapsClient from '@google/maps'; + +export default function createDirectionsService(apiKey) { + const client = GoogleMapsClient.createClient({ + key: apiKey, + Promise, + }); + + async function getDirections({ + destination, + origin, + travelMode, + }) { + const { + json, + } = await client.directions({ + destination, + origin, + mode: travelMode, + }).asPromise(); + return json; + } + + return { + getDirections, + }; +} diff --git a/src/createLocationsSearcher.js b/src/createLocationsSearcher.js new file mode 100644 index 0000000..ab5bfb2 --- /dev/null +++ b/src/createLocationsSearcher.js @@ -0,0 +1,19 @@ +import GoogleMapsClient from '@google/maps'; + +export default function createLocationsSearcher(apiKey) { + const client = GoogleMapsClient.createClient({ + key: apiKey, + Promise, + }); + + async function searchLocations(address) { + const { + json, + } = await client.geocode({ address }).asPromise(); + return json; + } + + return { + searchLocations, + }; +} diff --git a/src/gmtft.js b/src/gmtft.js index a4c9cc4..e444efe 100644 --- a/src/gmtft.js +++ b/src/gmtft.js @@ -1,5 +1,7 @@ #!/usr/bin/env node +/* eslint no-console: 0 */ + import execute from '..'; try { diff --git a/src/index.js b/src/index.js index 44a14c9..34031ef 100644 --- a/src/index.js +++ b/src/index.js @@ -1,29 +1,31 @@ +/* eslint no-console: 0 */ + import createRouteTable from './createRouteTable'; import { - GEOCODE_API_KEY, DIRECTIONS_API_KEY, } from './constants'; -import GoogleMapsService from './GoogleMapsService'; -import LocationSelector from './LocationSelector'; import selectTravelMode from './selectTravelMode'; import translateRoute from './translateRoute'; +import createDirectionsService from './createDirectionsService'; +import selectLocation from './selectLocation'; const execute = async () => { - const googleMapsService = new GoogleMapsService({ - directionsAPIKey: DIRECTIONS_API_KEY, - geocodeAPIKey: GEOCODE_API_KEY, - }); + const originSelector = selectLocation({ message: 'Select start location' }); + const originResult = await originSelector.run(); - const locationSelector = new LocationSelector(googleMapsService); - const origin = await locationSelector.selectLocation('Select start location'); - const destination = await locationSelector.selectLocation('Select end location'); + const destinationSelector = selectLocation({ message: 'Select end location' }); + const destinationResult = await destinationSelector.run(); - const travelMode = await selectTravelMode(); + const travelModeSelector = selectTravelMode({ message: 'Select travel mode' }); + const travelModeResult = await travelModeSelector.run(); - const { routes } = await googleMapsService.getDirections({ - origin, - destination, - travelMode, + const directionsService = createDirectionsService(DIRECTIONS_API_KEY); + const { + routes, + } = await directionsService.getDirections({ + origin: originResult.location, + destination: destinationResult.location, + travelMode: travelModeResult, }); routes diff --git a/src/searchLocations.js b/src/searchLocations.js new file mode 100644 index 0000000..02c0684 --- /dev/null +++ b/src/searchLocations.js @@ -0,0 +1,19 @@ +function parseLocations(locations) { + return locations.map((location) => { + const { + geometry, + formatted_address: formattedAddress, + } = location; + const parsedLocation = { + latitude: geometry.location.lat, + longitude: geometry.location.lng, + formattedAddress, + }; + return parsedLocation; + }); +} + +export default async function searchLocations({ input, locationsSearcher }) { + const searchResults = await locationsSearcher.searchLocations(input); + return parseLocations(searchResults.results); +} diff --git a/src/selectLocation.js b/src/selectLocation.js new file mode 100644 index 0000000..ae3f8f6 --- /dev/null +++ b/src/selectLocation.js @@ -0,0 +1,45 @@ +import { + AutoComplete, +} from 'enquirer'; +import debounce from 'lodash.debounce'; + +import { + GEOCODE_API_KEY, +} from './constants'; +import createLocationsSearcher from './createLocationsSearcher'; +import searchLocations from './searchLocations'; + +const searcher = createLocationsSearcher(GEOCODE_API_KEY); +const debouncedSearchLocations = debounce(searchLocations, 500, { leading: false, trailing: true }); + +async function generateSuggestions(input) { + const results = await debouncedSearchLocations({ input, locationsSearcher: searcher }); + if (results && results.length > 0) { + return results.map(location => ({ + name: location.formattedAddress, + message: location.formattedAddress, + value: location.formattedAddress, + location, + })); + } + return []; +} + +export default function selectLocation({ message }) { + return new AutoComplete({ + name: 'location', + limit: 5, + choices: [], + message, + suggest: generateSuggestions, + // override the default behavior of using number keys + // to select choices, so the user can enter a value for "address" + number(...args) { + return this.append(...args); + }, + // this will return the entire choice object + result(value) { + return this.choices.find(choice => choice.name === value); + }, + }); +} diff --git a/src/selectTravelMode.js b/src/selectTravelMode.js index 1ffb822..9ba7c5d 100644 --- a/src/selectTravelMode.js +++ b/src/selectTravelMode.js @@ -1,32 +1,21 @@ -import inquirer from 'inquirer'; -import inquirerAutocompletePrompt from 'inquirer-autocomplete-prompt'; -import fuzzy from 'fuzzy'; +import { + AutoComplete, +} from 'enquirer'; import { TRAVEL_MODE } from './constants'; -inquirer.registerPrompt('autocomplete', inquirerAutocompletePrompt); - const getTravelModeKey = mode => `${mode.emoji} (${mode.value})`; -const formattedTravelModesToValues = Object.freeze({ - [getTravelModeKey(TRAVEL_MODE.DRIVING)]: TRAVEL_MODE.DRIVING, - [getTravelModeKey(TRAVEL_MODE.WALKING)]: TRAVEL_MODE.WALKING, - [getTravelModeKey(TRAVEL_MODE.BICYCLING)]: TRAVEL_MODE.BICYCLING, - [getTravelModeKey(TRAVEL_MODE.TRANSIT)]: TRAVEL_MODE.TRANSIT, -}); - -const formattedTravelModes = Object.keys(formattedTravelModesToValues); - -const selectTravelMode = async () => { - const { travelMode } = await inquirer.prompt([ - { - type: 'autocomplete', - name: 'travelMode', - message: 'Select your travel mode', - source: (_, input) => Promise.resolve(fuzzy.filter(input || '', formattedTravelModes).map(match => match.original)), - }, - ]); - return formattedTravelModesToValues[travelMode]; -}; +const choices = Object.values(TRAVEL_MODE).map(mode => ({ + message: getTravelModeKey(mode), + name: getTravelModeKey(mode), + value: mode.value, +})); -export default selectTravelMode; +export default function selectTravelMode({ message }) { + return new AutoComplete({ + name: 'travelMode', + message, + choices, + }); +}