UNPKG

@liara/cli

Version:

The command line interface for Liara

233 lines (232 loc) 8.49 kB
import fs from 'fs'; import path from 'path'; import mime from 'mime'; import inquirer from 'inquirer'; import ora from 'ora'; import { Flags } from '@oclif/core'; import Command from '../../base.js'; import { createDebugLogger } from '../../utils/output.js'; import { MAIL_SERVICE_URL, DEV_MODE, MAIL_SERVICE_URL_DEV, } from '../../constants.js'; class SendMail extends Command { async setGotConfig(config) { await super.setGotConfig(config); this.got = this.got.extend({ prefixUrl: DEV_MODE ? MAIL_SERVICE_URL_DEV : MAIL_SERVICE_URL, }); } async run() { var _a, _b, _c, _d, _e; this.spinner = ora(); const { flags } = await this.parse(SendMail); const debug = createDebugLogger(flags.debug); await this.setGotConfig(flags); const { data } = await this.got('api/v1/mails').json(); const mailDomain = await this.promptMails(); const mailId = flags.mail || ((_a = data.mailServers.find((mail) => mail.domain === mailDomain)) === null || _a === void 0 ? void 0 : _a.id) || ''; const from = flags.from || (await this.promptFrom(mailId)); const to = flags.to || (await this.promptTo()); const mailRegex = new RegExp(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/g); const isValidDestination = mailRegex.test(to); if (!isValidDestination) { this.error(`Invalid destination email address.`); } const subject = flags.subject || (await this.promptSubject()); const text = flags.text || (await this.promptText()); const flagAttachments = flags.attachments ? this.getFlagFiles(flags.attachments) : undefined; const attachments = flagAttachments || (await this.promptFiles()); try { if (await this.confirm(to)) { await this.got.post(`api/v1/mails/${mailId}/messages`, { json: { from, to, subject, text, attachments }, }); this.log(`Mail has been sent to ${to}.`); } } catch (error) { debug(error.message); if (error.response && error.response.body) { debug(JSON.stringify(error.response.body)); } if (error.response && error.response.statusCode === 401) { this.error(`Missing authentication.`); } if (((_b = error.response) === null || _b === void 0 ? void 0 : _b.statusCode) === 404 && ((_c = error.response) === null || _c === void 0 ? void 0 : _c.body.message) === 'Account not found.') { this.error(`Account not found.`); } if (((_d = error.response) === null || _d === void 0 ? void 0 : _d.statusCode) === 404 && ((_e = error.response) === null || _e === void 0 ? void 0 : _e.body.message) === 'Mail Server not found.') { this.error(`Mail server not found.`); } this.log(error.response.body); this.error(`Could not send the email. Please try again.`); } } async promptMails() { this.spinner = ora(); this.spinner.start('Loading...'); try { const { data } = await this.got('api/v1/mails').json(); this.spinner.stop(); if (!data.mailServers.length) { this.warn('Please go to https://console.liara.ir/mail and create a mail server, first.'); this.exit(1); } const { mailDomain } = (await inquirer.prompt({ name: 'mailDomain', type: 'list', message: 'Please select a mail:', choices: [...data.mailServers.map((mail) => mail.domain)], validate: (input) => input.length > 2, })); return mailDomain; } catch (error) { this.spinner.stop(); throw error; } } async promptFrom(mailId) { this.spinner = ora(); this.spinner.start('Loading...'); try { const { data } = await this.got(`api/v1/mails/${mailId}/accounts`).json(); this.spinner.stop(); if (!data.accounts.length) { this.warn('Please go to https://console.liara.ir/mail and create a mail server account, first.'); this.exit(1); } const { from } = (await inquirer.prompt({ name: 'from', type: 'list', message: 'What address should it be sent from:', choices: [ ...data.accounts.map((account) => `${account.name}@${data.domain}`), ], validate: (input) => input.length > 2, })); return from; } catch (error) { this.spinner.stop(); throw error; } } async promptTo() { const { to } = (await inquirer.prompt({ name: 'to', type: 'input', message: 'Enter the destination address:', validate: (input) => input.length > 2, })); return to; } async promptSubject() { const { subject } = (await inquirer.prompt({ name: 'subject', type: 'input', message: 'The subject of your mail:', validate: (input) => input.length > 2, })); return subject; } async promptText() { const { text } = (await inquirer.prompt({ name: 'text', type: 'editor', message: 'The text of your mail:', validate: (input) => input.length > 2, })); return text; } getFlagFiles(flagFiles) { const files = []; for (const flagFile of flagFiles) { const file = path.join(process.cwd(), flagFile); if (!fs.statSync(file).isDirectory()) { const resultFile = { content_type: mime.getType(file) || '', data: `data:${mime.getType(file)};base64,${fs.readFileSync(file, { encoding: 'base64', })}`, name: file.split('/').pop() || '', }; files.push(resultFile); } } return files; } getFiles() { const files = []; const filesInCurrentDirectory = fs.readdirSync('./'); for (const file of filesInCurrentDirectory) { if (!fs.statSync(file).isDirectory()) { const resultFile = { content_type: mime.getType(file) || '', data: `data:${mime.getType(file)};base64,${fs.readFileSync(file, { encoding: 'base64', })}`, name: file || '', }; files.push(resultFile); } } return files; } async promptFiles() { const files = this.getFiles(); const { attachments } = (await inquirer.prompt({ name: 'attachments', type: 'checkbox', message: 'Select your attachments:', choices: files.map((file) => file.name), })); const filesResult = []; for (const attachment of attachments) { for (const file of files) { if (attachment === file.name) { filesResult.push(file); } } } return filesResult; } async confirm(dest) { const { confirmation } = (await inquirer.prompt({ name: 'confirmation', type: 'confirm', message: `Are you sure to send an e-mail to "${dest}"?`, default: false, })); return confirmation; } } SendMail.description = 'send an email'; SendMail.flags = { ...Command.flags, mail: Flags.string({ description: 'mail server id', }), from: Flags.string({ description: 'from', }), to: Flags.string({ description: 'to', }), subject: Flags.string({ description: 'subject', }), text: Flags.string({ description: 'text', }), attachments: Flags.string({ multiple: true, description: 'path of your attachments', }), }; SendMail.aliases = ['mail:send']; export default SendMail;