1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const fuzzy_1 = tslib_1.__importDefault(require("fuzzy"));
|
5 | const base_1 = tslib_1.__importStar(require("../base"));
|
6 | const fs = tslib_1.__importStar(require("fs-extra"));
|
7 | const path = tslib_1.__importStar(require("path"));
|
8 | const CustomErrors_1 = require("../errors/CustomErrors");
|
9 | const opConfig_1 = require("../constants/opConfig");
|
10 | const utils_1 = require("../utils");
|
11 | class List extends base_1.default {
|
12 | constructor() {
|
13 | super(...arguments);
|
14 | this.opResults = [];
|
15 | this.getApiOps = async (inputs) => {
|
16 | try {
|
17 | const { data: opResults } = await this.services.api.find(`/private/teams/${inputs.config.team.name}/ops`, {
|
18 | headers: {
|
19 | Authorization: this.accessToken,
|
20 | },
|
21 | });
|
22 | this.opResults = opResults;
|
23 | return Object.assign(Object.assign({}, inputs), { opResults });
|
24 | }
|
25 | catch (err) {
|
26 | this.debug('%0', err);
|
27 | throw new CustomErrors_1.APIError(err);
|
28 | }
|
29 | };
|
30 | this.getLocalOps = async (inputs) => {
|
31 | try {
|
32 | const manifest = await fs.readFile(path.join(process.cwd(), opConfig_1.OP_FILE), 'utf8');
|
33 | if (!manifest)
|
34 | return inputs;
|
35 | const { workflows = [], ops = [] } = utils_1.parseYaml(manifest);
|
36 | const localWorkflows = workflows.map(workflow => (Object.assign(Object.assign({}, workflow), { local: true })));
|
37 | const localCommands = ops.map(ops => (Object.assign(Object.assign({}, ops), { local: true })));
|
38 | return Object.assign(Object.assign({}, inputs), { opResults: [...inputs.opResults, ...localWorkflows, ...localCommands] });
|
39 | }
|
40 | catch (_a) {
|
41 | return Object.assign({}, inputs);
|
42 | }
|
43 | };
|
44 | this.filterOutGlueCodes = (inputs) => {
|
45 | const opResults = inputs.opResults.filter(input => input.type !== 'glue_code');
|
46 | this.opResults = opResults;
|
47 | return Object.assign(Object.assign({}, inputs), { opResults });
|
48 | };
|
49 | this.promptOps = async (inputs) => {
|
50 | if (inputs.opResults.length == 0) {
|
51 | 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'));
|
52 | process.exit();
|
53 | }
|
54 | const { reset, multiBlue, multiOrange, white, callOutCyan, secondary, } = this.ux.colors;
|
55 | const { config: { team: { name }, }, } = inputs;
|
56 | const commandText = multiBlue('\u2022Command');
|
57 | const workflowText = multiOrange('\u2022Workflow');
|
58 | const teamText = secondary(`@${name}`);
|
59 | const subHeader = reset.dim('š = Public š = Private š„ = Local š Search:');
|
60 | const { selectedOp } = await this.ux.prompt({
|
61 | type: 'autocomplete',
|
62 | name: 'selectedOp',
|
63 | pageSize: 5,
|
64 | message: `\nListing ops for team ${teamText}${callOutCyan(`. Select a ${commandText} or ${workflowText} to continue ${reset.green('ā')}\n${subHeader} `)}`,
|
65 | source: this._autocompleteSearch.bind(this),
|
66 | bottomContent: `\n \n${white(`Or, run ${callOutCyan('ops help')} for usage information.`)}`,
|
67 | });
|
68 | return Object.assign(Object.assign({}, inputs), { selectedOp });
|
69 | };
|
70 | this._autocompleteSearch = async (_, input = '') => {
|
71 | const { list, options } = this._fuzzyFilterParams();
|
72 | const fuzzyResult = fuzzy_1.default.filter(input, list, options);
|
73 | return fuzzyResult.map(result => result.original);
|
74 | };
|
75 | this._fuzzyFilterParams = () => {
|
76 | const list = this.opResults.map(op => {
|
77 | const name = this._formatOpOrWorkflowName(op);
|
78 | return {
|
79 | name: `${name} - ${op.description || op.publishDescription}`,
|
80 | value: op,
|
81 | };
|
82 | });
|
83 | const options = { extract: el => el.name };
|
84 | return { list, options };
|
85 | };
|
86 | this._formatOpOrWorkflowName = (op) => {
|
87 | const { reset, multiOrange, multiBlue } = this.ux.colors;
|
88 | const teamName = op.teamName ? `@${op.teamName}/` : '';
|
89 | const opVersion = op.version ? `(${op.version})` : '';
|
90 | const name = `${reset.white(`${teamName}${op.name}`)} ${reset.dim(`${opVersion}`)}`;
|
91 | if (op.type === opConfig_1.WORKFLOW_TYPE) {
|
92 | return `${reset(multiOrange('\u2022'))} ${this._formatOpOrWorkflowEmoji(op)} ${name}`;
|
93 | }
|
94 | else {
|
95 | return `${reset(multiBlue('\u2022'))} ${this._formatOpOrWorkflowEmoji(op)} ${name}`;
|
96 | }
|
97 | };
|
98 | this._formatOpOrWorkflowEmoji = (opOrWorkflow) => {
|
99 | if (opOrWorkflow.local) {
|
100 | return 'š„ ';
|
101 | }
|
102 | else if (opOrWorkflow.isPublic == false) {
|
103 | return 'š ';
|
104 | }
|
105 | else {
|
106 | return 'š ';
|
107 | }
|
108 | };
|
109 | this.showRunMessage = (inputs) => {
|
110 | const { selectedOp: { name, local, version, teamName }, } = inputs;
|
111 | let runCmd = 'ops run .';
|
112 | if (!local) {
|
113 | runCmd = `ops run @${teamName}/${name}:${version}`;
|
114 | }
|
115 | this.log(`\nš» Run ${this.ux.colors.green('$')} ${this.ux.colors.italic.dim(runCmd)} to test your op. ${local
|
116 | ? "(This points to the relative path where the 'ops.yml' file lives)"
|
117 | : ''}\n`);
|
118 | return inputs;
|
119 | };
|
120 | this.sendAnalytics = async (inputs) => {
|
121 | this.services.analytics.track({
|
122 | userId: this.user.email,
|
123 | teamId: this.team.id,
|
124 | cliEvent: 'Ops CLI List',
|
125 | event: 'Ops CLI List',
|
126 | properties: {
|
127 | email: this.user.email,
|
128 | },
|
129 | }, this.accessToken);
|
130 | return inputs;
|
131 | };
|
132 | this.startSpinner = async (inputs) => {
|
133 | 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')}`);
|
134 | return inputs;
|
135 | };
|
136 | this.stopSpinner = async (inputs) => {
|
137 | await this.ux.spinner.stop(`${this.ux.colors.successGreen('Done')}`);
|
138 | return inputs;
|
139 | };
|
140 | }
|
141 | async run() {
|
142 | try {
|
143 | await this.isLoggedIn();
|
144 | const { config } = this.state;
|
145 | const listPipeline = utils_1.asyncPipe(this.startSpinner, this.getApiOps, this.getLocalOps, this.filterOutGlueCodes, this.stopSpinner, this.promptOps, this.sendAnalytics, this.showRunMessage);
|
146 | await listPipeline({ config });
|
147 | }
|
148 | catch (err) {
|
149 | this.ux.spinner.stop(`${this.ux.colors.errorRed('Failed')}`);
|
150 | this.debug('%0', err);
|
151 | this.config.runHook('error', { err, accessToken: this.accessToken });
|
152 | }
|
153 | }
|
154 | }
|
155 | exports.default = List;
|
156 | List.description = 'Lists the Ops you have in your team.';
|
157 | List.flags = {
|
158 | help: base_1.flags.help({ char: 'h' }),
|
159 | };
|