@cto.ai/ops
Version:
š» CTO.ai - The CLI built for Teams š
155 lines (154 loc) ⢠7.36 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const fuzzy_1 = tslib_1.__importDefault(require("fuzzy"));
const base_1 = tslib_1.__importStar(require("./../base"));
const CustomErrors_1 = require("./../errors/CustomErrors");
const opConfig_1 = require("./../constants/opConfig");
const utils_1 = require("./../utils");
class Search extends base_1.default {
constructor() {
super(...arguments);
this.opsAndWorkflows = [];
this.getApiOpsAndWorkflows = async (inputs) => {
try {
const findResponse = await this.services.api.find(`/private/ops`, {
headers: {
Authorization: this.accessToken,
},
});
let { data: apiOps } = findResponse;
return Object.assign(Object.assign({}, inputs), { apiOps });
}
catch (err) {
this.debug('error: %O', err);
throw new CustomErrors_1.APIError(err);
}
};
// Currently not used; pipelines = workflows
this.filterOutWorkflows = (inputs) => {
const apiOps = inputs.apiOps.filter(input => input.type !== opConfig_1.WORKFLOW_TYPE);
return Object.assign(Object.assign({}, inputs), { apiOps });
};
this.filterOutGlueCodes = (inputs) => {
const apiOps = inputs.apiOps.filter(input => input.type !== opConfig_1.GLUECODE_TYPE);
return Object.assign(Object.assign({}, inputs), { apiOps });
};
this.filterOutPipelineJobs = (inputs) => {
const apiOps = inputs.apiOps.filter(input => input.type !== opConfig_1.JOB_TYPE);
return Object.assign(Object.assign({}, inputs), { apiOps });
};
this.filterByNameOrDescription = (inputs) => {
const apiOps = inputs.apiOps.filter(op => op.name.includes(inputs.filter) ||
op.description.includes(inputs.filter));
return Object.assign(Object.assign({}, inputs), { apiOps });
};
this.checkData = async (inputs) => {
this.opsAndWorkflows = inputs.apiOps;
if (!this.opsAndWorkflows.length) {
this.log(`\nš No matching workflows found in our registry.\nš To create your own, use: ${this.ux.colors.successGreen('$')} ${this.ux.colors.callOutCyan('ops init')} \n`);
process.exit();
}
return inputs;
};
this.selectOpPrompt = async (inputs) => {
const { reset, multiOrange, multiBlue, white, callOutCyan, multiPurple, } = this.ux.colors;
const commandText = multiBlue('\u2022 Command');
const pipelineText = multiOrange('\u2022 Pipeline');
const serviceText = multiPurple('\u2022 Service');
const { selectedOp } = await this.ux.prompt({
type: 'autocomplete',
name: 'selectedOp',
pageSize: 5,
message: `\nSelect a public ${commandText}, ${pipelineText} or ${serviceText} to continue ${reset.green('ā')}\n${reset.dim('š Search:')} `,
source: this._autocompleteSearch.bind(this),
bottomContent: `\n \n${white(`Or, run ${callOutCyan('ops help')} for usage information.`)}`,
});
return Object.assign(Object.assign({}, inputs), { selectedOp });
};
this.showRunMessage = (inputs) => {
const { selectedOp: { name, teamName }, } = inputs;
this.log(`\nš» Run ${this.ux.colors.green('$')} ${this.ux.colors.italic.dim('ops run @' + teamName + '/' + name)} to test your workflow. \n`);
return inputs;
};
this.sendAnalytics = async (inputs) => {
const { selectedOp: { name, teamName, version }, filter, config, } = inputs;
try {
this.services.analytics.track('Ops CLI Search', {
username: config.user.username,
selectedOp: `@${teamName}/${name}:${version}`,
results: this.opsAndWorkflows.length,
filter,
}, config);
}
catch (err) {
this.debug('%O', err);
throw new CustomErrors_1.AnalyticsError(err);
}
};
this._autocompleteSearch = async (_, input = '') => {
const { list, options } = this.fuzzyFilterParams();
const fuzzyResult = fuzzy_1.default.filter(input, list, options);
return fuzzyResult.map(result => result.original);
};
this.fuzzyFilterParams = () => {
const list = this.opsAndWorkflows.map(opOrWorkflow => {
const name = this._formatOpOrWorkflowName(opOrWorkflow);
return {
name: `${name} - ${opOrWorkflow.description}`,
value: opOrWorkflow,
};
});
const options = { extract: el => el.name };
return { list, options };
};
this._formatOpOrWorkflowName = (opOrWorkflow) => {
const { reset, multiOrange, multiBlue, multiPurple } = this.ux.colors;
const teamName = opOrWorkflow.teamName ? `@${opOrWorkflow.teamName}/` : '';
const name = `${reset.white(`${teamName}${opOrWorkflow.name}`)} ${reset.dim(`(${opOrWorkflow.version})`)}`;
switch (opOrWorkflow.type) {
case opConfig_1.WORKFLOW_TYPE:
return `${reset(multiOrange('\u2022'))} ${name}`;
case opConfig_1.SERVICE_TYPE:
return `${reset(multiPurple('\u2022'))} ${name}`;
default:
return `${reset(multiBlue('\u2022'))} ${name}`;
}
};
this.startSpinner = async (inputs) => {
this.ux.spinner.start(`š ${this.ux.colors.white('Searching')} ${this.ux.colors.callOutCyan(`all ${(0, utils_1.pluralize)(opConfig_1.WORKFLOW)}`)}`);
return inputs;
};
this.stopSpinner = async (inputs) => {
this.ux.spinner.stop(`${this.ux.colors.successGreen('Done')}`);
return inputs;
};
}
async run() {
const { args: { filter = '' }, } = this.parse(Search);
const config = await this.isLoggedIn();
try {
const searchPipeline = (0, utils_1.asyncPipe)(this.startSpinner, this.getApiOpsAndWorkflows, this.filterByNameOrDescription, this.filterOutGlueCodes, this.filterOutPipelineJobs, this.checkData, this.stopSpinner, this.selectOpPrompt, this.showRunMessage, this.sendAnalytics);
await searchPipeline({ filter, config });
}
catch (err) {
this.ux.spinner.stop(`${this.ux.colors.errorRed('Failed')}`);
this.debug('%O', err);
this.config.runHook('error', {
err,
accessToken: config.tokens.accessToken,
});
}
}
}
exports.default = Search;
Search.description = 'Search for workflows in our registry.';
Search.args = [
{
name: 'filter',
description: 'Filter results by workflow name or description.',
},
];
Search.flags = {
help: base_1.flags.help({ char: 'h' }),
};