mirror of
https://github.com/graphql-hive/console
synced 2026-05-24 09:38:26 +00:00
178 lines
4.4 KiB
TypeScript
178 lines
4.4 KiB
TypeScript
import colors from 'colors';
|
|
import { ClientError, GraphQLClient } from 'graphql-request';
|
|
import symbols from 'log-symbols';
|
|
import { Command, Errors, Config as OclifConfig } from '@oclif/core';
|
|
import { Config } from './helpers/config';
|
|
import { getSdk } from './sdk';
|
|
|
|
export default abstract class extends Command {
|
|
protected _userConfig: Config;
|
|
|
|
protected constructor(argv: string[], config: OclifConfig) {
|
|
super(argv, config);
|
|
|
|
this._userConfig = new Config({
|
|
// eslint-disable-next-line no-process-env
|
|
filepath: process.env.HIVE_CONFIG,
|
|
rootDir: process.cwd(),
|
|
});
|
|
}
|
|
|
|
success(...args: any[]) {
|
|
this.log(colors.green(symbols.success), ...args);
|
|
}
|
|
|
|
fail(...args: any[]) {
|
|
this.log(colors.red(symbols.error), ...args);
|
|
}
|
|
|
|
info(...args: any[]) {
|
|
this.log(colors.yellow(symbols.info), ...args);
|
|
}
|
|
|
|
bolderize(msg: string) {
|
|
const findSingleQuotes = /'([^']+)'/gim;
|
|
const findDoubleQuotes = /"([^"]+)"/gim;
|
|
|
|
return msg
|
|
.replace(findSingleQuotes, (_: string, value: string) => colors.bold(value))
|
|
.replace(findDoubleQuotes, (_: string, value: string) => colors.bold(value));
|
|
}
|
|
|
|
/**
|
|
* Get a value from arguments or flags first, then from env variables,
|
|
* then fallback to config.
|
|
* Throw when there's no value.
|
|
*
|
|
* @param key
|
|
* @param args all arguments or flags
|
|
* @param defaultValue default value
|
|
* @param message custom error message in case of no value
|
|
* @param env an env var name
|
|
*/
|
|
ensure<
|
|
TArgs extends {
|
|
[key: string]: any;
|
|
},
|
|
TKey extends keyof TArgs,
|
|
>({
|
|
key,
|
|
args,
|
|
defaultValue,
|
|
message,
|
|
env,
|
|
}: {
|
|
key: TKey;
|
|
args: TArgs;
|
|
defaultValue?: TArgs[TKey] | null;
|
|
message?: string;
|
|
env?: string;
|
|
}): NonNullable<TArgs[TKey]> | never {
|
|
if (args[key]) {
|
|
return args[key];
|
|
}
|
|
|
|
// eslint-disable-next-line no-process-env
|
|
if (env && process.env[env]) {
|
|
// eslint-disable-next-line no-process-env
|
|
return process.env[env] as TArgs[TKey];
|
|
}
|
|
|
|
if (this._userConfig.has(key as string)) {
|
|
return this._userConfig.get(key as string);
|
|
}
|
|
|
|
if (defaultValue) {
|
|
return defaultValue;
|
|
}
|
|
|
|
if (message) {
|
|
throw new Errors.CLIError(message);
|
|
}
|
|
|
|
throw new Errors.CLIError(`Missing "${String(key)}"`);
|
|
}
|
|
|
|
/**
|
|
* Get a value from arguments or flags first, then fallback to config.
|
|
* Do NOT throw when there's no value.
|
|
*
|
|
* @param key
|
|
* @param args all arguments or flags
|
|
*/
|
|
maybe<
|
|
TArgs extends {
|
|
[key: string]: any;
|
|
},
|
|
TKey extends keyof TArgs,
|
|
>(key: TKey, args: TArgs): TArgs[TKey] | undefined {
|
|
if (args[key]) {
|
|
return args[key];
|
|
}
|
|
|
|
if (this._userConfig.has(key as string)) {
|
|
return this._userConfig.get(key as string);
|
|
}
|
|
}
|
|
|
|
cleanRequestId(requestId?: string | null) {
|
|
return requestId ? requestId.split(',')[0].trim() : undefined;
|
|
}
|
|
|
|
registryApi(registry: string, token: string) {
|
|
return getSdk(
|
|
new GraphQLClient(registry, {
|
|
headers: {
|
|
Accept: 'application/json',
|
|
'User-Agent': `hive-cli/${this.config.version}`,
|
|
Authorization: `Bearer ${token}`,
|
|
'graphql-client-name': 'Hive CLI',
|
|
'graphql-client-version': this.config.version,
|
|
},
|
|
}),
|
|
);
|
|
}
|
|
|
|
handleFetchError(error: unknown): never {
|
|
if (typeof error === 'string') {
|
|
return this.error(error);
|
|
}
|
|
|
|
if (error instanceof Error) {
|
|
if (isClientError(error)) {
|
|
const errors = error.response?.errors;
|
|
|
|
if (Array.isArray(errors) && errors.length > 0) {
|
|
return this.error(errors[0].message, {
|
|
ref: this.cleanRequestId(error.response?.headers?.get('x-request-id')),
|
|
});
|
|
}
|
|
|
|
return this.error(error.message, {
|
|
ref: this.cleanRequestId(error.response?.headers?.get('x-request-id')),
|
|
});
|
|
}
|
|
|
|
return this.error(error);
|
|
}
|
|
|
|
return this.error(JSON.stringify(error));
|
|
}
|
|
|
|
async require<
|
|
TFlags extends {
|
|
require: string[];
|
|
[key: string]: any;
|
|
},
|
|
>(flags: TFlags) {
|
|
if (flags.require && flags.require.length > 0) {
|
|
await Promise.all(
|
|
flags.require.map(mod => import(require.resolve(mod, { paths: [process.cwd()] }))),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
function isClientError(error: Error): error is ClientError {
|
|
return 'response' in error;
|
|
}
|