diff --git a/src/base.ts b/src/base.ts index 03cff769..5215b8d3 100644 --- a/src/base.ts +++ b/src/base.ts @@ -167,6 +167,19 @@ export interface IGetMailboxesResponse { }; } +export interface IMailPlan { + available: boolean; + maxAccount: number; + maxForwarder: number; + maxInbound: string; + maxInboundMailRetention: number; + maxOutboundMailRetention: number; + maxOutboundPerDay: number; + maxOutboundPerMonth: number; + name: string; + price: number; +} + export interface IGetMailsAccounts { name: string; createdAt: string; @@ -195,10 +208,10 @@ export default abstract class extends Command { 'api-token': Flags.string({ description: 'your api token to use for authentication', }), - region: Flags.string({ - description: 'the region you want to deploy your app to', - options: ['iran', 'germany'], - }), + // region: Flags.string({ + // description: 'the region you want to deploy your app to', + // options: ['iran', 'germany'], + // }), account: Flags.string({ description: 'temporarily switch to a different account', }), diff --git a/src/commands/app/create.ts b/src/commands/app/create.ts index ec8470f4..8602de62 100644 --- a/src/commands/app/create.ts +++ b/src/commands/app/create.ts @@ -51,13 +51,8 @@ export default class AppCreate extends Command { const name = flags.app || (await this.promptAppName()); - const account = await this.getCurrentAccount(); - await this.setGotConfig(flags); - ((account && account.region === 'germany') || flags.region === 'germany') && - this.error('We do not support germany any more.'); - const platform = flags.platform || (await this.promptPlatform()); if (!AVAILABLE_PLATFORMS.includes(platform)) { diff --git a/src/commands/bucket/create.ts b/src/commands/bucket/create.ts index 2c24a623..c3612e6c 100644 --- a/src/commands/bucket/create.ts +++ b/src/commands/bucket/create.ts @@ -33,7 +33,7 @@ export default class BucketCreate extends Command { async setGotConfig( config: IConfig, - isObjMode: boolean = true + isObjMode: boolean = true, ): Promise { if (isObjMode) { await super.setGotConfig(config); @@ -60,8 +60,7 @@ export default class BucketCreate extends Command { await this.setGotConfig(flags); - ((account && account.region === 'germany') || flags.region === 'germany') && - this.error('We do not support germany any more.'); + // (account && account.region === 'germany') || (flags.region === 'germany') && this.error('We do not support germany any more.'); const plan = flags.plan || (await this.promptPlan()); @@ -123,8 +122,8 @@ export default class BucketCreate extends Command { await this.setGotConfig(flags, false); try { - // TODO: Use proper type for plans const { plans } = await this.got('v1/me').json<{ plans: any }>(); + this.spinner.stop(); const { plan } = (await inquirer.prompt({ @@ -133,11 +132,7 @@ export default class BucketCreate extends Command { message: 'Please select a plan:', choices: [ ...Object.keys(plans.objectStorage) - .filter((plan) => { - if (plans.objectStorage[plan].available) { - return true; - } - }) + .filter((plan) => plans.objectStorage[plan].available) .map((plan) => { const availablePlan = plans.objectStorage[plan]; const price = availablePlan.price * 720; @@ -145,15 +140,7 @@ export default class BucketCreate extends Command { const storageClass = availablePlan.storageClass; return { value: plan, - name: `Space: ${space}${spacing( - 5, - space - )}GB, Storage Class: ${storageClass}${spacing( - 5, - storageClass - )}, Price: ${price.toLocaleString()}${ - price ? spacing(7, price) + 'Tomans/Month' : '' - }`, + name: `Plan: ${plan}, Space: ${space}GB, Storage class: ${storageClass}, Price: ${price.toLocaleString()} Tomans/Month`, }; }), ], diff --git a/src/commands/db/create.ts b/src/commands/db/create.ts index d0a16ceb..fd6045e2 100644 --- a/src/commands/db/create.ts +++ b/src/commands/db/create.ts @@ -52,10 +52,6 @@ export default class Create extends Command { const debug = createDebugLogger(flags.debug); await this.setGotConfig(flags); - const account = await this.getCurrentAccount(); - - ((account && account.region === 'germany') || flags.region === 'germany') && - this.error('We do not support germany any more.'); const hostname = flags.name || (await this.promptHostname()); const type = flags.type || (await this.promptType()); @@ -200,13 +196,15 @@ export default class Create extends Command { }) .map((bundlePlan) => { const planDetails = plans.databaseBundlePlans[bundlePlan]; - return Object.keys(planDetails).map((key) => { - const { displayPrice } = planDetails[key]; - return { - name: `Plan type: ${key}, Price: ${displayPrice.toLocaleString()} Tomans/Month`, - value: key, - }; - }); + return Object.keys(planDetails) + .filter((key) => planDetails[key].available) + .map((key) => { + const { displayPrice } = planDetails[key]; + return { + name: `Plan: ${key}, Price: ${displayPrice.toLocaleString()} Tomans/Month`, + value: key, + }; + }); }) .flat(), ], diff --git a/src/commands/db/resize.ts b/src/commands/db/resize.ts index 8b7c65c2..88634d20 100644 --- a/src/commands/db/resize.ts +++ b/src/commands/db/resize.ts @@ -9,8 +9,6 @@ import spacing from '../../utils/spacing.js'; export default class Resize extends Command { static description = 'resize a database'; - static PATH = 'v1/databases/{database-id}/resize'; - static flags = { ...Command.flags, name: Flags.string({ @@ -33,20 +31,16 @@ export default class Resize extends Command { const debug = createDebugLogger(flags.debug); await this.setGotConfig(flags); - const account = await this.getCurrentAccount(); - - ((account && account.region === 'germany') || flags.region === 'germany') && - this.error('We do not support germany any more.'); const hostname = flags.name || (await this.promptHostname()); const disk = flags.disk === 'y' ? true : flags.disk === 'n' - ? false - : (await this.promptDisk()) === 'y' - ? true - : false; + ? false + : (await this.promptDisk()) === 'y' + ? true + : false; try { const database = await this.getDatabaseByHostname(hostname); @@ -54,11 +48,15 @@ export default class Resize extends Command { this.log(`Database ${hostname} not found`); return; } + const planID = flags.plan || (await this.promptPlan(database.type)); + const databaseID = database._id; - await this.got.post(Resize.PATH.replace('{database-id}', databaseID), { + + const result = await this.got.post(`v1/databases/${databaseID}/resize`, { json: { planID: planID, disk: disk }, }); + this.log(`Database ${hostname} changed to plan ${planID}.`); } catch (error) { debug(error.message); @@ -82,9 +80,8 @@ export default class Resize extends Command { } async getDatabaseByHostname(hostname: string) { - const { databases } = await this.got( - 'v1/databases' - ).json(); + const { databases } = + await this.got('v1/databases').json(); if (!databases.length) { this.error(`Not found any database. @@ -92,13 +89,14 @@ Please open up https://console.liara.ir/databases and create the database, first } const database = databases.find( - (database) => database.hostname === hostname + (database) => database.hostname === hostname, ); return database; } async promptPlan(databaseType: string) { this.spinner.start('Loading...'); + try { const { plans } = await this.got('v1/me').json<{ plans: any }>(); this.spinner.stop(); @@ -111,6 +109,7 @@ Please open up https://console.liara.ir/databases and create the database, first ...Object.keys(plans.databases) .filter((plan) => { if ( + (plan === 'free' || plan.includes('g2')) && plans.databases[plan].available && plans.databases[plan].supports.includes(databaseType) ) { @@ -126,14 +125,9 @@ Please open up https://console.liara.ir/databases and create the database, first const storageClass = availablePlan.storageClass; return { value: plan, - name: `RAM: ${ram}${spacing(5, ram)}GB, CPU: ${cpu}${spacing( - 5, - cpu - )}Core, Disk: ${disk}${spacing(3, disk) + 'GB'}${ + name: `RAM: ${ram}GB, CPU: ${cpu} Core, Disk: ${disk}GB, ${ storageClass || 'SSD' - }, Price: ${price.toLocaleString()}${ - price ? spacing(7, price) + 'Tomans/Month' : '' - }`, + }, Price: ${price.toLocaleString()} Tomans/Month `, }; }), ], diff --git a/src/commands/mail/create.ts b/src/commands/mail/create.ts index f70c3278..cfa09db8 100644 --- a/src/commands/mail/create.ts +++ b/src/commands/mail/create.ts @@ -1,15 +1,16 @@ import ora, { Ora } from 'ora'; import inquirer from 'inquirer'; -import Command, { IConfig } from '../../base.js'; +import Command, { IConfig, IMailPlan } from '../../base.js'; import { Flags } from '@oclif/core'; import { MAIL_SERVICE_MODES, - MAIL_SERVICE_PLANS, MAIL_SERVICE_URL, + MAIL_SERVICE_PLANS, DEV_MODE, MAIL_SERVICE_URL_DEV, } from '../../constants.js'; import { createDebugLogger } from '../../utils/output.js'; +import { getMailPlanName } from '../../utils/get-mail-plan-names.js'; export default class MailCreate extends Command { static description = 'create a mail server'; @@ -33,9 +34,6 @@ export default class MailCreate extends Command { async setGotConfig(config: IConfig): Promise { await super.setGotConfig(config); - this.got = this.got.extend({ - prefixUrl: DEV_MODE ? MAIL_SERVICE_URL_DEV : MAIL_SERVICE_URL, - }); } async run() { @@ -47,13 +45,8 @@ export default class MailCreate extends Command { const domain = flags.domain || (await this.promptDomain()); - const account = await this.getCurrentAccount(); - await this.setGotConfig(flags); - ((account && account.region === 'germany') || flags.region === 'germany') && - this.error('We do not support germany any more.'); - const plan = flags.platform || (await this.promptPlan()); if (!MAIL_SERVICE_PLANS.includes(plan)) { @@ -67,7 +60,10 @@ export default class MailCreate extends Command { } try { - await this.got.post('api/v1/mails', { json: { domain, plan, mode } }); + await this.got.post('api/v1/mails', { + json: { domain, plan, mode }, + prefixUrl: MAIL_SERVICE_URL, + }); this.log(`Mail server ${domain} created.`); } catch (error) { debug(error.message); @@ -82,7 +78,7 @@ export default class MailCreate extends Command { if (error.response && error.response.statusCode === 409) { this.error( - `The mail server already exists. Please use a unique name for your mail server.` + `The mail server already exists. Please use a unique name for your mail server.`, ); } @@ -92,7 +88,7 @@ export default class MailCreate extends Command { error.response.body ) { this.error( - `You are allowed to create only one Mail Server on the free plan.` + `You are allowed to create only one Mail Server on the free plan.`, ); } @@ -115,13 +111,29 @@ export default class MailCreate extends Command { this.spinner.start('Loading...'); try { + const { plans } = await this.got('v1/me').json<{ plans: any }>(); + this.spinner.stop(); const { plan } = (await inquirer.prompt({ name: 'plan', type: 'list', - message: 'Please select the plan you want:', - choices: [...MAIL_SERVICE_PLANS.map((plan) => plan)], + message: 'Please select a plan:', + choices: [ + ...Object.keys(plans.mail) + .filter((plan) => plans.mail[plan].available) + .map((plan) => { + const availablePlan = plans.mail[plan]; + const maxAccount = availablePlan.maxAccount; + const maxOutboundPerDay = availablePlan.maxOutboundPerDay; + const maxOutboundPerMonth = availablePlan.maxOutboundPerMonth; + const price = availablePlan.price; + return { + value: plan, + name: `Plan: ${getMailPlanName(plan)}, Max outbound per day: ${maxOutboundPerDay}, Max outbound per month: ${maxOutboundPerMonth}, Max account: ${maxAccount}, Price: ${price}`, + }; + }), + ], })) as { plan: string }; return plan; diff --git a/src/commands/zone/check.ts b/src/commands/zone/check.ts index f4a32a74..5a7c5c02 100644 --- a/src/commands/zone/check.ts +++ b/src/commands/zone/check.ts @@ -30,10 +30,6 @@ export default class Check extends Command { const debug = createDebugLogger(flags.debug); await this.setGotConfig(flags); - const account = await this.getCurrentAccount(); - - ((account && account.region === 'germany') || flags.region === 'germany') && - this.error('We do not support germany any more.'); const zone = flags.zone || (await this.promptZone()); @@ -54,7 +50,7 @@ export default class Check extends Command { } if (error.response && error.response.statusCode === 404) { - this.error(`The zone does not exist.`); + this.error(`Zone does not exists or its status is not pending.`); } if (error.response && error.response.statusCode === 406) { diff --git a/src/constants.ts b/src/constants.ts index 3a37c8c7..dd6ceedf 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -14,7 +14,7 @@ export const REGIONS_API_URL: { [key: string]: string } = { export const MAIL_SERVICE_URL = 'https://mail-service.iran.liara.ir'; -export const MAIL_SERVICE_URL_DEV = 'http://localhost:3002'; +export const MAIL_SERVICE_URL_DEV = 'http://localhost:6336'; export const OBJECT_STORAGE_API_URL = 'https://storage-service.iran.liara.ir'; @@ -42,6 +42,15 @@ export const AVAILABLE_PLATFORMS = [ ]; export const OBJ_PERMISSION = ['public', 'private']; -export const MAIL_SERVICE_PLANS = ['free-included', 'premium']; +export const MAIL_SERVICE_PLANS = [ + 'm1', + 'm2', + 'm3', + 'm4', + 'm5', + 'm6', + 'm7', + 'm8', +]; export const MAIL_SERVICE_MODES = ['DEV', 'LIVE']; diff --git a/src/utils/get-mail-plan-names.ts b/src/utils/get-mail-plan-names.ts new file mode 100644 index 00000000..712eeb9e --- /dev/null +++ b/src/utils/get-mail-plan-names.ts @@ -0,0 +1,14 @@ +export const getMailPlanName = (plan: string): string | undefined => { + const planNames: Record = { + m1: 'Amber', + m2: 'Opal', + m3: 'Jadeite', + m4: 'Marble', + m5: 'Turquoise', + m6: 'Emerald', + m7: 'Ruby', + m8: 'Diamond', + }; + + return planNames[plan]; +};