UNPKG

@controlplane/cli

Version:

Control Plane Corporation CLI

264 lines 9.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Spy = exports.Command = void 0; const client_1 = require("../session/client"); const session_1 = require("../session/session"); const logger_1 = require("../util/logger"); const resolver_1 = require("../commands/resolver"); const resultFetcher_1 = require("../rest/resultFetcher"); const functions_1 = require("../util/functions"); class Command { with(opts) { this.formatHints = opts.formatHints; this.prepare = opts.prepare; return this; } toYargs() { const interceptingHandler = async (args) => { if (!args._env) { // used only for parsing, not execution return; } // set up the "this" this.env = args._env; // session is a lazy property of the command let session; Object.defineProperty(this, 'session', { enumerable: true, get: () => { if (!session) { session = (0, session_1.newDefaultSession)(args._env, args); } if (this.formatHints) { session.format._hints = this.formatHints; } return session; }, }); let client; Object.defineProperty(this, 'client', { enumerable: true, get: () => { if (!client) { client = (0, client_1.makeSessionClient)(this.session); } return client; }, }); // if terminal, turn off coloring no matter what if (this.env.out === process.stdout && !process.stdout.isTTY) { args.color = false; } if (this.env.err === process.stderr && !process.stderr.isTTY) { args.color = false; } if (this.prepare) { await this.prepare.call(this); } return this.handle(args); }; const interceptingBuilder = (yargs) => { if (!this.describe || !yargs['_command_stack']) { // hidden command or yargs is not spying // just group options under a "Command options:" group const origMethod = yargs.options; yargs.options = function (opts, ...more) { if (typeof opts === 'string') { //@ts-ignore return origMethod(opts, ...more); } const overridable = []; for (let prop in opts) { const item = opts[prop]; if (!item.group) { item.group = 'Command options:'; } if (!item.multiple) { overridable.push(prop); } } if (overridable.length > 0) { pickLast(...overridable)(yargs); } //@ts-ignore return origMethod(opts, ...more); }; return this.builder(yargs); } const stack = yargs['_command_stack']; const cm = { name: guessName(this.command), description: this.describe, options: [], commands: [ { name: 'help', description: 'Show help', }, ], positional: [], }; stack.push(cm); const spy = new Spy(yargs, cm); spy.start(); const res = this.builder(yargs); spy.restore(); return res; }; return { command: this.command, aliases: this.aliases, describe: this.describe, deprecated: this.deprecated, builder: interceptingBuilder.bind(this), handler: interceptingHandler.bind(this), }; } async ensureDeletion(link, maxRetries = 10) { logger_1.logger.debug(`Ensuring the deletion of ${link}`); await (0, functions_1.retryFn)(async () => { var _a; try { await this.client.get(link); throw new Error('Object is found'); } catch (e) { if (((_a = e.response) === null || _a === void 0 ? void 0 : _a.status) == 404) { logger_1.logger.debug(`Resource ${link} has been deleted and NO longer exists!`); return; } throw e; } }, { onFailure() { logger_1.logger.debug(`Timed out, the resource ${link} still exists.`); }, intervalSec: 0.5, repeatTimes: maxRetries, }); } async listAndDelete(kind, context) { const resolver = (0, resolver_1.kindResolver)(kind); const resourceLinks = []; // Getting all items of kind in gvc const listLink = resolver.parentLink(context); const listRes = await this.client.get(listLink); // Fetch all items await (0, resultFetcher_1.fetchPages)(this.client, -1, listRes); // Deleting each item for (const item of listRes.items) { const selfLink = resolver.resourceLink(item.name, context); await this.client.axios.delete(selfLink); this.session.out(`Deleted ${item.kind} '${item.name}'`); resourceLinks.push(selfLink); } // Ensure the deletion of these kinds of resources if (kind == 'volumeset' || kind == 'workload') { await Promise.all(resourceLinks.map((link) => this.ensureDeletion(link))); } } requireOrg() { if (!this.session.context.org) { this.session.abort({ message: 'ERROR: An organization is required. Please, specify one using the --org option.' }); } } } exports.Command = Command; function guessName(s) { var _a; return (_a = s.split(' ')[0]) !== null && _a !== void 0 ? _a : s; } function toString(obj) { if (!obj) { return undefined; } return '' + obj; } function toArray(obj) { if (typeof obj === 'string') { return [obj]; } if (Array.isArray(obj)) { return obj; } return undefined; } class Spy { constructor(yargs, model) { this.yargs = yargs; this.model = model; this.methods = {}; } start() { const command = (this.methods.command = this.yargs.command); const positional = (this.methods.positional = this.yargs.positional); const options = (this.methods.options = this.yargs.options); const that = this; // collect subcommands // @ts-ignore this.yargs.command = function (mod) { if (mod.describe) { // only record described/public command that.model.commands.push({ name: guessName(mod.command), description: mod.describe, }); } return command(mod); }; // collect positional args // @ts-ignore this.yargs.positional = function (name, opts) { that.model.positional.push({ name: name, description: opts.describe, }); return positional(name, opts); }; // @ts-ignore this.yargs.options = function (opts, ...more) { if (typeof opts === 'string') { // the original options method calls itself multiple times if not invoked with an object // @ts-ignore return options(opts, ...more); } //console.log('xx=' ,Object.getOwnPropertyNames(opts)) for (let prop in opts) { const item = opts[prop]; that.model.options.push({ name: prop, alias: toArray(item.alias), choices: item.choices, description: item.description, default: toString(item.default), boolean: item.boolean, completions: item.completions, paths: item.paths, }); } return options(opts); }; } restore() { this.yargs.command = this.methods.command; this.yargs.positional = this.methods.positional; this.yargs.options = this.methods.options; } } exports.Spy = Spy; function pickLast(...opts) { return (yargs) => { yargs.check((argv) => { for (let opt of opts) { let value = argv[opt]; if (value && Array.isArray(value)) { value = value[value.length - 1]; argv[opt] = value; } } return true; }); return yargs; }; } //# sourceMappingURL=command.js.map