copykitku/src/cli/account.ts
2021-02-15 00:36:13 +01:00

166 lines
4.5 KiB
TypeScript

import { Command, flags } from '@oclif/command';
import assert from 'assert';
import child from 'child_process';
import inquirer from 'inquirer';
import {
CopykitkuProfile,
CopykitkuProfileBase,
Vendor,
VENDOR_TYPE,
CopykitkuVendorConfig,
} from '../types';
import { getConfig, getConfigPath, setConfig } from '../utils';
export default class Account extends Command {
static description = 'manage accounts used by copykitku';
static flags = {
help: flags.help({ char: 'h' }),
};
static args = [
{
name: 'subcommand',
required: true,
options: ['get', 'list', 'edit', 'create'],
description: 'the action to run with the accounts',
},
{
name: 'name',
description: 'account name (for "get" subcommand)',
},
];
static strict = true;
protected getPrintableAccountInfo(account: CopykitkuProfile) {
return `
Name:\t${account.name}
Vendor:\t${account.vendor.type}
Domain:\t${account.config.domain}
`
.trim()
.split('\n')
.map((l) => l.trim())
.join('\n');
}
async run() {
const { args } = this.parse(Account);
const config = getConfig();
const { vendorConfigs } = config;
switch (args.subcommand) {
case 'list':
console.log(vendorConfigs.map(this.getPrintableAccountInfo).join('\n---\n'));
break;
case 'get':
const account = vendorConfigs.find((con) => con.name === args.name);
if (account) {
console.log(this.getPrintableAccountInfo(account));
} else {
console.log('Account not found');
}
break;
case 'edit':
child.spawn(process.env.EDITOR || 'micro', [getConfigPath()]);
break;
case 'create':
const answers = (await inquirer.prompt([
{
type: 'list',
name: 'type',
message: 'Vendor type',
choices: Object.values(VENDOR_TYPE),
},
{
type: 'input',
name: 'domain',
message: 'Vendor domain',
default: ({ type }: { type: VENDOR_TYPE }) => {
if (type === VENDOR_TYPE.GITHUB) {
return 'github.com';
}
return null;
},
validate: (val: string) => {
try {
const url = new URL('https://' + val);
assert(url.pathname === '/');
return true;
} catch (e) {
return 'Enter valid domain name';
}
},
},
{
type: 'password',
name: 'token',
message: ({ type, domain }: { type: VENDOR_TYPE; domain: string }) => {
let tokenGettingURL: string | null = null;
let scopes: string = '[unknown]';
if (type === VENDOR_TYPE.GITHUB) {
tokenGettingURL = `https://${domain}/settings/tokens/new`;
scopes = 'repo or public_repo';
} else if (type === VENDOR_TYPE.GITLAB) {
tokenGettingURL = `https://${domain}/-/profile/personal_access_tokens`;
scopes = 'api';
}
return (
'Authentication token' +
(tokenGettingURL
? ` (you can get a one here: ${tokenGettingURL} , required scopes are: ${scopes})`
: '')
);
},
validate: (val: string) => {
if (!val) {
return 'Enter a token';
}
return true;
},
mask: '*',
},
{
type: 'input',
name: 'name',
message: 'Choose a name for your account to reference to it',
validate: (val: string) => {
if (!val) {
return 'Enter a name';
}
if (config.vendorConfigs.find((v) => v.name === val)) {
return 'Account name must be unique';
}
return true;
},
},
])) as {
type: VENDOR_TYPE;
domain: string;
token: string;
name: string;
};
config.vendorConfigs.push({
vendor: {
type: answers.type,
domain: answers.domain,
},
config: {
domain: answers.domain,
token: answers.token,
},
name: answers.name,
} as CopykitkuProfile);
setConfig(config);
break;
}
}
}