UNPKG

@cto.ai/ops

Version:

šŸ’» CTO.ai - The CLI built for Teams šŸš€

155 lines (154 loc) • 7.36 kB
"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' }), };