UNPKG

@ahurein/travel-explorer

Version:

CLI utility to easily browse attractions in every country/city

186 lines (185 loc) 9.69 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { Command } from "commander"; import { input, confirm, rawlist } from "@inquirer/prompts"; import { capitalizeWords, customTable, getUserContinent, getUserCountry } from "../helpers/helper.js"; import chalk from "chalk"; import { getAttractionsNearYou, getContinentTodo, getCountryTodo } from "../attractionsApi.js"; import ora from 'ora'; import { displayLocationAttractions } from "../helpers/display.js"; const spinner = ora('Loading unicorns'); const log = console.log; export const attractionsCommand = new Command("attractions"); attractionsCommand .description("Fetch attractions based on the user query") .option("-t, --city <city name>", "specify the city to search for") .option("-c, --country <country name>", "specify the country to search for") .option("-n, --continent <continent name>", "filter results by continent") .action((options) => __awaiter(void 0, void 0, void 0, function* () { if (Object.keys(options).length) { const { country, city, continent } = options; let userCountry, userContinent; if (continent) { userContinent = yield getUserContinent(continent); yield displayLocationAttractions(userContinent, "continent" /* LocationType.CONTINENT */); } else if (city && !country || city && country) { userCountry = yield getUserCountry(country); yield displayLocationAttractions(userCountry, "city" /* LocationType.CITY */, city); } else if (country) { userCountry = yield getUserCountry(country); yield displayLocationAttractions(userCountry, "country" /* LocationType.COUNTRY */); } } else { const searchByChoices = [ { name: "country", value: "countryFilter", }, { name: "continent", value: "continentFilter", }, { name: "city", value: "cityFilter", }, { name: "Things to do", value: "activityFilter", }, { name: "Near you", value: "nearFilter", }, ]; const searchBy = yield rawlist({ message: "Select what you want to search by: ", choices: searchByChoices }); searchByFunctions[searchBy](); } })); const searchByFunctions = { countryFilter: () => __awaiter(void 0, void 0, void 0, function* () { const userCountry = yield getUserCountry(); yield displayLocationAttractions(userCountry, "country" /* LocationType.COUNTRY */); }), continentFilter: () => __awaiter(void 0, void 0, void 0, function* () { const userContinent = yield getUserContinent(); yield displayLocationAttractions(userContinent, "continent" /* LocationType.CONTINENT */); }), cityFilter: () => __awaiter(void 0, void 0, void 0, function* () { const userCountry = yield getUserCountry(); const city = yield input({ message: "Enter the city name: " }); yield displayLocationAttractions(userCountry, "city" /* LocationType.CITY */, city); }), activityFilter: () => __awaiter(void 0, void 0, void 0, function* () { // perform action for filtering by things to do const choices = [ { name: 'country', value: "country" }, { name: 'continent', value: "continent" } ]; const filter = yield rawlist({ message: "Filter activities by: ", choices }); let count = 0, page = 1, userCountry = "", userContinent = "", attractions = [], askUserLocation = true; const thingsToDoTable = customTable(["No", "Title", "Location", "Things to do", "Price (USD)", "Cancellation", "Overall Rating", "Image", "Reviews", "Overview", "URL"]); while (true) { switch (filter) { case "country": { if (askUserLocation) userCountry = yield getUserCountry(); spinner.start(); attractions = yield getCountryTodo(userCountry, page); spinner.stop(); if (attractions.message) return log(chalk.red(attractions.message)); break; } case "continent": { if (askUserLocation) userContinent = yield getUserContinent(); spinner.start(); attractions = yield getContinentTodo(userContinent, page); spinner.stop(); if (attractions.message) return log(chalk.red(attractions.message)); break; } } if (!(attractions === null || attractions === void 0 ? void 0 : attractions.total)) return log(chalk.red(`Sorry, We do not have any attractions on ${filter}`)); if (filter === "country") { log(`Things to do grouped by cities in ${capitalizeWords(userCountry)}: ${chalk.bold.green(attractions === null || attractions === void 0 ? void 0 : attractions.total)}`); } else { log(`Things to do grouped by countries in ${capitalizeWords(userContinent)}: ${chalk.bold.green(attractions === null || attractions === void 0 ? void 0 : attractions.total)}`); } attractions.attractions.forEach((attractionObj) => { const { total, attraction } = attractionObj; const overview = `${attraction.overview}`.substring(0, 60) + "..."; let review = ""; count += 1; if (Number(attraction.total_reviews) && attraction.reviews[0].body) { review = `${attraction.reviews[0].body}`.substring(0, 60) + "..."; } const { title, city, price, cancellation, country, overall_rating, main_image, url } = attraction; thingsToDoTable.push([count, title, `${city},\n${country}`, total, price, cancellation, overall_rating, { content: chalk.yellow("View image"), href: main_image }, review, overview, { content: chalk.yellow("Book attraction"), href: url }]); }); log(thingsToDoTable.toString()); if (!attractions.hasMore) return log(chalk.green("No more data!")); const fetchMore = yield confirm({ message: "Do you want to fetch more attractions: " }); if (!fetchMore) return; page += 1; askUserLocation = false; } }), nearFilter: () => __awaiter(void 0, void 0, void 0, function* () { // perform action for searching near you const userCountry = yield getUserCountry(); const thingsToDoTable = customTable(["No", "Title", "Location", "Things to do", "Price (USD)", "Cancellation", "Overall Rating", "Image", "Reviews", "Overview", "URL"]); let count = 0, page = 1; while (true) { spinner.start(); let attractions = yield getAttractionsNearYou(userCountry, page); attractions = attractions.length > 0 ? attractions[0] : []; spinner.stop(); if (attractions.message) return log(chalk.red(attractions.message)); if (!(attractions === null || attractions === void 0 ? void 0 : attractions.total)) return log(chalk.red(`Sorry, We do not have any attractions on ${userCountry}`)); log(`Attractions ${userCountry} found: ${chalk.bold.green(attractions === null || attractions === void 0 ? void 0 : attractions.total)}`); attractions.attractions.forEach((attractionObj) => { const { total, attraction } = attractionObj; const overview = `${attraction.overview}`.substring(0, 60) + "..."; let review = ""; count += 1; if (Number(attraction.total_reviews) && attraction.reviews[0].body) { review = `${attraction.reviews[0].body}`.substring(0, 60) + "..."; } const { title, city, price, cancellation, country, overall_rating, main_image, url } = attraction; thingsToDoTable.push([count, title, `${city},\n${country}`, total, price, cancellation, overall_rating, { content: chalk.yellow("View image"), href: main_image }, review, overview, { content: chalk.yellow("Book attraction"), href: url }]); }); log(thingsToDoTable.toString()); if (!attractions.hasMore) return log(chalk.green("No more data!")); const fetchMore = yield confirm({ message: "Do you want to fetch more attractions: " }); if (!fetchMore) return; page += 1; } }), };