@ahurein/travel-explorer
Version:
CLI utility to easily browse attractions in every country/city
186 lines (185 loc) • 9.69 kB
JavaScript
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;
}
}),
};