@cto.ai/ops
Version:
š» CTO.ai - The CLI built for Teams š
174 lines (173 loc) ⢠8.47 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 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");
const validate_1 = require("../utils/validate");
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 { ops = [] } = (0, utils_1.parseYaml)(manifest);
const localCommands = ops.map(ops => (Object.assign(Object.assign({}, ops), { local: true })));
return Object.assign(Object.assign({}, inputs), { opResults: [...inputs.opResults, ...localCommands] });
}
catch (_a) {
return Object.assign({}, inputs);
}
};
// Currently not used; pipelines = workflows
this.filterOutWorkflows = (inputs) => {
const opResults = inputs.opResults.filter(input => input.type !== opConfig_1.WORKFLOW_TYPE);
this.opResults = opResults;
return Object.assign(Object.assign({}, inputs), { opResults });
};
this.filterOutGlueCodes = (inputs) => {
const opResults = inputs.opResults.filter(input => input.type !== opConfig_1.GLUECODE_TYPE);
this.opResults = opResults;
return Object.assign(Object.assign({}, inputs), { opResults });
};
this.filterOutPipelineJobs = (inputs) => {
const opResults = inputs.opResults.filter(input => {
return !(0, validate_1.validateOpIsJob)(input);
});
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('ā It looks like you have not published anything yet. \n' +
'š Check out our documentation to get started: https://cto.ai/docs'));
process.exit();
}
const { reset, multiBlue, multiOrange, multiPurple, white, callOutCyan, secondary, } = this.ux.colors;
const { config: { team: { name }, }, } = inputs;
const commandText = multiBlue('\u2022 Command');
const pipelineText = multiOrange('\u2022 Pipeline');
const serviceText = multiPurple('\u2022 Service');
const teamText = secondary(`@${name}`);
const subHeader = reset.dim('š = Public Registry š = Private Registry š„ = Local š Search:');
const { selectedOp } = await this.ux.prompt({
type: 'autocomplete',
name: 'selectedOp',
pageSize: 5,
message: `\nListing workflows for team ${teamText}${callOutCyan(`. Select a ${commandText}, ${pipelineText} or ${serviceText} 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, multiPurple } = 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}`)}`;
switch (op.type) {
case opConfig_1.WORKFLOW_TYPE:
return `${reset(multiOrange('\u2022'))} ${this._formatOpOrWorkflowEmoji(op)} ${name}`;
case opConfig_1.SERVICE_TYPE:
return `${reset(multiPurple('\u2022'))} ${this._formatOpOrWorkflowEmoji(op)} ${name}`;
default:
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 workflow. ${local
? "(This points to the relative path where the 'ops.yml' file lives)"
: ''}\n`);
return inputs;
};
this.sendAnalytics = async (inputs) => {
const { config, opResults, selectedOp } = inputs;
this.services.analytics.track('Ops CLI List', {
username: config.user.username,
results: opResults.length,
selectedOp: `${selectedOp.teamName}/${selectedOp.name}:${selectedOp.version}`,
}, config);
return inputs;
};
this.startSpinner = async (inputs) => {
this.ux.spinner.start(`š ${this.ux.colors.white('Searching for')} ${this.ux.colors.callOutCyan(`all ${(0, utils_1.pluralize)(opConfig_1.WORKFLOW)}`)} ${this.ux.colors.white('on your team')}`);
return inputs;
};
this.stopSpinner = async (inputs) => {
this.ux.spinner.stop(`${this.ux.colors.successGreen('Done')}`);
return inputs;
};
}
async run() {
try {
await this.isLoggedIn();
const { config } = this.state;
const listPipeline = (0, utils_1.asyncPipe)(this.startSpinner, this.getApiOps, this.getLocalOps, this.filterOutGlueCodes, this.filterOutPipelineJobs, 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 Workflows you have in your team.';
List.flags = {
help: base_1.flags.help({ char: 'h' }),
};