#!/usr/bin/env node const { prompt } = require('enquirer'); const program = require('commander'); const pkg = require("./package.json"); const fs = require("fs"); const validUrl = require("valid-url"); const ora = require("ora"); const ttmsh = require("./index.js"); const fileBytes = require("file-bytes"); const chalk = require("chalk"); // configure program with version, description and commands program.version(pkg.version) .description(pkg.description) .command("shorten [url]", { isDefault: true }) .action(shorten); program .command("upload [path]") .option("-f, --force", "force an upload (disable file size checks)") .action(upload); // if any command isn't handled, this is run program.on("command:*", () => { console.error(chalk.red.bold("Invalid command: %s\nSee --help for a list of available commands.", program.args.join(" "))); process.exit(1); }); // pass the arguments to the program to be parsed program.parse(process.argv); // this function is ran when the upload command is used // 'path' is passed in from the program and *should* be a valid filename async function upload(path, cmd) { if (cmd.force) { console.warn(chalk.yellow("Forcing upload. Expect problems!")); } // if we don't have a path set or the path doesn't exist if (!path || !fs.existsSync(path)) { // ask the user to (re)type a path const response = await prompt([ { type: 'input', name: 'path', message: 'Which file would you like to upload?', hint: "Type a file path (e.g file.txt, ../file.txt)", // check that the file exists before we allow the user to submit validate: (input) => fs.existsSync(input) ? true : "Invalid file path" } ]); // set the path variable to be the response that we just got path = response.path; } fileBytes(path).then(size => { var sizeMib = size / 1048576; var ret = ttmsh.retention(sizeMib); if (ret === -1 && !cmd.force) { console.error(chalk.red.bold(`This file is ~${sizeMib.toFixed(2)} MiB, which is over the limit of ${ttmsh.config.max_size} MiB!`)); return; } else if (ret === -1 && cmd.force) { console.warn(chalk.yellow.bold(`This file is ~${sizeMib.toFixed(2)} MiB, which is over the limit of ${ttmsh.config.max_size} MiB!`)); console.warn(chalk.yellow("Attempting upload anyway...")); } else { console.log(chalk.cyan(`This file is ~${sizeMib.toFixed(2)} MiB and last ~${ret} days.`)); } // run the action, i.e upload the file doAction("upload", path); }); } // this function is ran when the shorten command is used // 'url' is passed in from the program and *should* be a valid url async function shorten(url) { // if we don't have a url set or the url isn't really a url if (!url || !validUrl.isWebUri(url)) { // ask the user to (re)type a url const response = await prompt([ { type: 'input', name: 'url', message: 'Which URL would you like to shorten?', hint: "Type a URL (e.g http://tilde.team)", // check that the url is valid before we allow the user to submit validate: (input) => validUrl.isWebUri(input) ? true : "Invalid URL" } ]); // set the url variable to be the response that we just got url = response.url; } // run the action, i.e shorten the url doAction("shorten", url); } // this is run when we need to contact ttm.sh (via the module index.js) function doAction(action, data) { // create an spinner to show that we are trying to upload const spinner = ora(chalk.blue(`${action}ing...`)).start(); // use the ttmsh module to run the action with the data ttmsh.do(action, data).then((result) => { // if we were successful, display our result (i.e the url) spinner.succeed(chalk.greenBright.bold(result)); }).catch((e) => { // if something went wrong, display an message with the error spinner.fail(`${chalk.red.bold("Whoops! There was a problem while completing your request -")} ${chalk.red(e.message)}`); }); }