166 lines
4.5 KiB
TypeScript
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;
|
|
}
|
|
}
|
|
}
|