UNPKG

@cto.ai/ops

Version:

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

160 lines (159 loc) • 7.57 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 fs = tslib_1.__importStar(require("fs-extra")); const path = tslib_1.__importStar(require("path")); const CustomErrors_1 = require("../errors/CustomErrors"); const opConfig_1 = require("../constants/opConfig"); const utils_1 = require("../utils"); class List extends base_1.default { constructor() { super(...arguments); this.opResults = []; this.getApiOps = async (inputs) => { try { const { data: opResults } = await this.services.api.find(`/private/teams/${inputs.config.team.name}/ops`, { headers: { Authorization: this.accessToken, }, }); this.opResults = opResults; return Object.assign(Object.assign({}, inputs), { opResults }); } catch (err) { this.debug('%0', err); throw new CustomErrors_1.APIError(err); } }; this.getLocalOps = async (inputs) => { try { const manifest = await fs.readFile(path.join(process.cwd(), opConfig_1.OP_FILE), 'utf8'); if (!manifest) return inputs; const { workflows = [], ops = [] } = utils_1.parseYaml(manifest); const localWorkflows = workflows.map(workflow => (Object.assign(Object.assign({}, workflow), { local: true }))); const localCommands = ops.map(ops => (Object.assign(Object.assign({}, ops), { local: true }))); return Object.assign(Object.assign({}, inputs), { opResults: [...inputs.opResults, ...localWorkflows, ...localCommands] }); } catch (_a) { return Object.assign({}, inputs); } }; this.filterOutGlueCodes = (inputs) => { const opResults = inputs.opResults.filter(input => input.type !== 'glue_code'); this.opResults = opResults; return Object.assign(Object.assign({}, inputs), { opResults }); }; this.promptOps = async (inputs) => { if (inputs.opResults.length == 0) { this.log(this.ux.colors.whiteBright('ā— Sorry you have no ops yet! If you want help with creating one, please go to: https://cto.ai/docs/getting-started')); process.exit(); } const { reset, multiBlue, multiOrange, white, callOutCyan, secondary, } = this.ux.colors; const { config: { team: { name }, }, } = inputs; const commandText = multiBlue('\u2022Command'); const workflowText = multiOrange('\u2022Workflow'); const teamText = secondary(`@${name}`); const subHeader = reset.dim('šŸŒŽ = Public šŸ”‘ = Private šŸ–„ = Local šŸ” Search:'); const { selectedOp } = await this.ux.prompt({ type: 'autocomplete', name: 'selectedOp', pageSize: 5, message: `\nListing ops for team ${teamText}${callOutCyan(`. Select a ${commandText} or ${workflowText} to continue ${reset.green('→')}\n${subHeader} `)}`, 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._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.opResults.map(op => { const name = this._formatOpOrWorkflowName(op); return { name: `${name} - ${op.description || op.publishDescription}`, value: op, }; }); const options = { extract: el => el.name }; return { list, options }; }; this._formatOpOrWorkflowName = (op) => { const { reset, multiOrange, multiBlue } = this.ux.colors; const teamName = op.teamName ? `@${op.teamName}/` : ''; const opVersion = op.version ? `(${op.version})` : ''; const name = `${reset.white(`${teamName}${op.name}`)} ${reset.dim(`${opVersion}`)}`; if (op.type === opConfig_1.WORKFLOW_TYPE) { return `${reset(multiOrange('\u2022'))} ${this._formatOpOrWorkflowEmoji(op)} ${name}`; } else { return `${reset(multiBlue('\u2022'))} ${this._formatOpOrWorkflowEmoji(op)} ${name}`; } }; this._formatOpOrWorkflowEmoji = (opOrWorkflow) => { if (opOrWorkflow.local) { return 'šŸ–„ '; } else if (opOrWorkflow.isPublic == false) { return 'šŸ”‘ '; } else { return 'šŸŒŽ '; } }; this.showRunMessage = (inputs) => { const { selectedOp: { name, local, version, teamName }, } = inputs; let runCmd = 'ops run .'; if (!local) { runCmd = `ops run @${teamName}/${name}:${version}`; } this.log(`\nšŸ’» Run ${this.ux.colors.green('$')} ${this.ux.colors.italic.dim(runCmd)} to test your op. ${local ? "(This points to the relative path where the 'ops.yml' file lives)" : ''}\n`); return inputs; }; this.sendAnalytics = async (inputs) => { this.services.analytics.track({ userId: this.user.email, teamId: this.team.id, cliEvent: 'Ops CLI List', event: 'Ops CLI List', properties: { email: this.user.email, }, }, this.accessToken); return inputs; }; this.startSpinner = async (inputs) => { await this.ux.spinner.start(`šŸ” ${this.ux.colors.white('Searching for')} ${this.ux.colors.callOutCyan(`all ${utils_1.pluralize(opConfig_1.COMMAND)} and ${utils_1.pluralize(opConfig_1.WORKFLOW)}`)} ${this.ux.colors.white('on your team')}`); return inputs; }; this.stopSpinner = async (inputs) => { await this.ux.spinner.stop(`${this.ux.colors.successGreen('Done')}`); return inputs; }; } async run() { try { await this.isLoggedIn(); const { config } = this.state; const listPipeline = utils_1.asyncPipe(this.startSpinner, this.getApiOps, this.getLocalOps, this.filterOutGlueCodes, this.stopSpinner, this.promptOps, this.sendAnalytics, this.showRunMessage); await listPipeline({ config }); } catch (err) { this.ux.spinner.stop(`${this.ux.colors.errorRed('Failed')}`); this.debug('%0', err); this.config.runHook('error', { err, accessToken: this.accessToken }); } } } exports.default = List; List.description = 'Lists the Ops you have in your team.'; List.flags = { help: base_1.flags.help({ char: 'h' }), };