account management cli command
This commit is contained in:
parent
3f20cfde24
commit
d19a3653a9
|
@ -46,6 +46,7 @@
|
|||
"fs-extra": "^9.1.0",
|
||||
"got": "^11.8.1",
|
||||
"graphql": "^15.5.0",
|
||||
"inquirer": "^7.3.3",
|
||||
"simple-git": "^2.31.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -55,6 +56,8 @@
|
|||
"@oclif/dev-cli": "^1.26.0",
|
||||
"@types/fs-extra": "^9.0.6",
|
||||
"@types/iarna__toml": "^2.0.1",
|
||||
"@types/inquirer": "^7.3.1",
|
||||
"@types/node": "^14.14.25",
|
||||
"eslint": "^7.19.0",
|
||||
"eslint-config-airbnb-typescript": "^12.0.0",
|
||||
"eslint-config-prettier": "^7.2.0",
|
||||
|
|
165
src/cli/account.ts
Normal file
165
src/cli/account.ts
Normal file
|
@ -0,0 +1,165 @@
|
|||
import { Command, flags } from '@oclif/command';
|
||||
import assert from 'assert';
|
||||
import child from 'child_process';
|
||||
import inquirer from 'inquirer';
|
||||
import {
|
||||
CopycatProfile,
|
||||
CopycatProfileBase,
|
||||
Vendor,
|
||||
VENDOR_TYPE,
|
||||
CopycatVendorConfig,
|
||||
} from '../types';
|
||||
import { getConfig, getConfigPath, setConfig } from '../utils';
|
||||
|
||||
export default class Account extends Command {
|
||||
static description = 'manage accounts used by copycat';
|
||||
|
||||
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: CopycatProfile) {
|
||||
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 CopycatProfile);
|
||||
|
||||
setConfig(config);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
27
yarn.lock
27
yarn.lock
|
@ -1218,6 +1218,14 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/inquirer@^7.3.1":
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-7.3.1.tgz#1f231224e7df11ccfaf4cf9acbcc3b935fea292d"
|
||||
integrity sha512-osD38QVIfcdgsPCT0V3lD7eH0OFurX71Jft18bZrsVQWVRt6TuxRzlr0GJLrxoHZR2V5ph7/qP8se/dcnI7o0g==
|
||||
dependencies:
|
||||
"@types/through" "*"
|
||||
rxjs "^6.4.0"
|
||||
|
||||
"@types/js-yaml@^3.12.5":
|
||||
version "3.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.5.tgz#136d5e6a57a931e1cce6f9d8126aa98a9c92a6bb"
|
||||
|
@ -1257,6 +1265,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.27.tgz#a151873af5a5e851b51b3b065c9e63390a9e0eb1"
|
||||
integrity sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==
|
||||
|
||||
"@types/node@^14.14.25":
|
||||
version "14.14.25"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.25.tgz#15967a7b577ff81383f9b888aa6705d43fbbae93"
|
||||
integrity sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ==
|
||||
|
||||
"@types/parse-json@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
||||
|
@ -1269,6 +1282,13 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/through@*":
|
||||
version "0.0.30"
|
||||
resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895"
|
||||
integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/websocket@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.1.tgz#039272c196c2c0e4868a0d8a1a27bbb86e9e9138"
|
||||
|
@ -4971,6 +4991,13 @@ rxjs@^6.3.3, rxjs@^6.6.0:
|
|||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
rxjs@^6.4.0:
|
||||
version "6.6.3"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552"
|
||||
integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@~5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
|
|
Loading…
Reference in a new issue