From 3d47eebf22c06fbb29514a0df2b4e892fc19ce63 Mon Sep 17 00:00:00 2001 From: Christian Clausen Date: Tue, 17 Oct 2023 13:40:19 +0200 Subject: [PATCH] Add back status to queue and time option --- executors.js | 47 ++++++++++++++++++- executors.ts | 60 +++++++++++++++++++++++++ package.json | 2 +- prompt.js | 11 ++--- prompt.ts | 13 +++--- questions.js | 110 +++++++++++++++++++++++++++++++-------------- questions.ts | 124 +++++++++++++++++++++++++++++++++++++++------------ 7 files changed, 293 insertions(+), 74 deletions(-) diff --git a/executors.js b/executors.js index b0239a7..e589b7e 100644 --- a/executors.js +++ b/executors.js @@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.do_cron = exports.do_envvar = exports.do_key = exports.do_inspect = exports.do_build = exports.do_redeploy = exports.do_deploy = exports.generateNewKey = exports.useExistingKey = exports.do_register = exports.do_duplicate = exports.fetch_template = exports.createService = exports.createServiceGroup = exports.createOrganization = exports.do_clone = exports.do_fetch = void 0; +exports.do_queue_time = exports.printTableHeader = exports.alignLeft = exports.alignRight = exports.do_cron = exports.do_envvar = exports.do_key = exports.do_inspect = exports.do_build = exports.do_redeploy = exports.do_deploy = exports.generateNewKey = exports.useExistingKey = exports.do_register = exports.do_duplicate = exports.fetch_template = exports.createService = exports.createServiceGroup = exports.createOrganization = exports.do_clone = exports.do_fetch = void 0; const fs_1 = __importDefault(require("fs")); const os_1 = __importDefault(require("os")); const utils_1 = require("./utils"); @@ -396,3 +396,48 @@ function do_cron(org, name, overwrite, event, expr) { }); } exports.do_cron = do_cron; +function alignRight(str, width) { + return str.length > width + ? str.substring(0, width - 3) + "..." + : str.padStart(width, " "); +} +exports.alignRight = alignRight; +function alignLeft(str, width) { + return str.length > width + ? str.substring(0, width - 3) + "..." + : str.padEnd(width, " "); +} +exports.alignLeft = alignLeft; +function printTableHeader(prefix, widths) { + let header = prefix + + Object.keys(widths) + .map((k) => k.trim().padEnd(widths[k])) + .join(" │ "); + (0, utils_1.output2)(header); + let divider = prefix + + Object.keys(widths) + .map((k) => "─".repeat(widths[k])) + .join("─┼─"); + (0, utils_1.output2)(divider); +} +exports.printTableHeader = printTableHeader; +function do_queue_time(org, time) { + return __awaiter(this, void 0, void 0, function* () { + try { + let resp = yield (0, utils_1.sshReq)(`queue`, `--org`, org, `--time`, "" + time); + let queue = JSON.parse(resp); + printTableHeader("", { + Id: 6, + River: 12, + Event: 12, + Status: 7, + "Queue time": 20, + }); + queue.forEach((x) => (0, utils_1.output2)(`${x.id} │ ${alignRight(x.r, 12)} │ ${alignLeft(x.e, 12)} │ ${alignLeft(x.s, 7)} │ ${new Date(x.q).toLocaleString()}`)); + } + catch (e) { + throw e; + } + }); +} +exports.do_queue_time = do_queue_time; diff --git a/executors.ts b/executors.ts index ff1732f..e44a617 100644 --- a/executors.ts +++ b/executors.ts @@ -449,3 +449,63 @@ export async function do_cron( throw e; } } + +export function alignRight(str: string, width: number) { + return str.length > width + ? str.substring(0, width - 3) + "..." + : str.padStart(width, " "); +} + +export function alignLeft(str: string, width: number) { + return str.length > width + ? str.substring(0, width - 3) + "..." + : str.padEnd(width, " "); +} + +export function printTableHeader( + prefix: string, + widths: { [key: string]: number } +) { + let header = + prefix + + Object.keys(widths) + .map((k) => k.trim().padEnd(widths[k])) + .join(" │ "); + output2(header); + let divider = + prefix + + Object.keys(widths) + .map((k) => "─".repeat(widths[k])) + .join("─┼─"); + output2(divider); +} + +export async function do_queue_time(org: string, time: number) { + try { + let resp = await sshReq(`queue`, `--org`, org, `--time`, "" + time); + let queue: { + id: string; + q: string; + e: string; + r: string; + s: string; + }[] = JSON.parse(resp); + printTableHeader("", { + Id: 6, + River: 12, + Event: 12, + Status: 7, + "Queue time": 20, + }); + queue.forEach((x) => + output2( + `${x.id} │ ${alignRight(x.r, 12)} │ ${alignLeft(x.e, 12)} │ ${alignLeft( + x.s, + 7 + )} │ ${new Date(x.q).toLocaleString()}` + ) + ); + } catch (e) { + throw e; + } +} diff --git a/package.json b/package.json index 127bdda..992927e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@merrymake/cli", - "version": "1.4.0", + "version": "1.5.0", "description": "", "main": "index.js", "scripts": { diff --git a/prompt.js b/prompt.js index 737f538..d561973 100644 --- a/prompt.js +++ b/prompt.js @@ -82,7 +82,8 @@ function makeSelectionInternal(option, extra) { function makeSelection(option) { return makeSelectionInternal(option, () => { output("\n"); - output((command += " " + option.long)); + output((command += + " " + (option.long.includes(" ") ? `'${option.long}'` : option.long))); output("\n"); }); } @@ -96,7 +97,7 @@ function cleanup() { output(exports.NORMAL_COLOR); output(exports.SHOW_CURSOR); } -function choice(options, invertedQuiet = true, def = 0) { +function choice(options, invertedQuiet = { cmd: false, select: true }, def = 0) { return new Promise((resolve) => { let quick = {}; let str = []; @@ -116,7 +117,7 @@ function choice(options, invertedQuiet = true, def = 0) { const o = options[i]; if ((0, args_1.getArgs)()[0] === o.long || (0, args_1.getArgs)()[0] === `-${o.short}`) { (0, args_1.getArgs)().splice(0, 1); - resolve(invertedQuiet ? makeSelectionQuietly(o) : makeSelection(o)); + resolve(invertedQuiet.cmd ? makeSelection(o) : makeSelectionQuietly(o)); return; } if (o.short) @@ -154,7 +155,7 @@ function choice(options, invertedQuiet = true, def = 0) { // stdout.write("" + yOffset); // moveCursor(-("" + yOffset).length, -options.length + pos); if (k === exports.ENTER) { - resolve(invertedQuiet + resolve(invertedQuiet.select ? makeSelection(options[pos]) : makeSelectionQuietly(options[pos])); return; @@ -291,7 +292,7 @@ function shortText(prompt, description, defaultValue) { output(beforeCursor + afterCursor); moveCursor(-afterCursor.length, 0); } - else if (/^[A-Za-z0-9@_.-/:;#=&?]$/.test(k)) { + else if (/^[A-Za-z0-9@_, .-/:;#=&?]$/.test(k)) { moveCursor(-beforeCursor.length, 0); beforeCursor += k; node_process_1.stdout.clearLine(1); diff --git a/prompt.ts b/prompt.ts index 564a2a2..fa27897 100644 --- a/prompt.ts +++ b/prompt.ts @@ -90,7 +90,10 @@ function makeSelectionInternal(option: Option, extra: () => void) { function makeSelection(option: Option) { return makeSelectionInternal(option, () => { output("\n"); - output((command += " " + option.long)); + output( + (command += + " " + (option.long.includes(" ") ? `'${option.long}'` : option.long)) + ); output("\n"); }); } @@ -116,7 +119,7 @@ export type Option = { export function choice( options: Option[], - invertedQuiet = true, + invertedQuiet = { cmd: false, select: true }, def: number = 0 ) { return new Promise((resolve) => { @@ -137,7 +140,7 @@ export function choice( const o = options[i]; if (getArgs()[0] === o.long || getArgs()[0] === `-${o.short}`) { getArgs().splice(0, 1); - resolve(invertedQuiet ? makeSelectionQuietly(o) : makeSelection(o)); + resolve(invertedQuiet.cmd ? makeSelection(o) : makeSelectionQuietly(o)); return; } if (o.short) quick[o.short] = o; @@ -180,7 +183,7 @@ export function choice( // moveCursor(-("" + yOffset).length, -options.length + pos); if (k === ENTER) { resolve( - invertedQuiet + invertedQuiet.select ? makeSelection(options[pos]) : makeSelectionQuietly(options[pos]) ); @@ -310,7 +313,7 @@ export function shortText( stdout.clearLine(1); output(beforeCursor + afterCursor); moveCursor(-afterCursor.length, 0); - } else if (/^[A-Za-z0-9@_.-/:;#=&?]$/.test(k)) { + } else if (/^[A-Za-z0-9@_, .-/:;#=&?]$/.test(k)) { moveCursor(-beforeCursor.length, 0); beforeCursor += k; stdout.clearLine(1); diff --git a/questions.js b/questions.js index d82c9da..3ee094b 100644 --- a/questions.js +++ b/questions.js @@ -69,12 +69,10 @@ function service_template(pathToService, template) { }); } function duplicate_service_deploy(pathToService, org, group, service, deploy) { - return __awaiter(this, void 0, void 0, function* () { - (0, utils_1.addToExecuteQueue)(() => (0, executors_1.do_duplicate)(pathToService, org, group, service)); - if (deploy) - (0, utils_1.addToExecuteQueue)(() => (0, executors_1.do_deploy)(pathToService)); - return (0, utils_1.finish)(); - }); + (0, utils_1.addToExecuteQueue)(() => (0, executors_1.do_duplicate)(pathToService, org, group, service)); + if (deploy) + (0, utils_1.addToExecuteQueue)(() => (0, executors_1.do_deploy)(pathToService)); + return (0, utils_1.finish)(); } function duplicate_service(pathToService, org, group, service) { return (0, prompt_1.choice)([ @@ -205,7 +203,7 @@ function register() { text: "Setup new key specifically for Merrymake", action: () => register_key(executors_1.generateNewKey), }); - return yield (0, prompt_1.choice)(keys, true, keys.length - 1).then((x) => x); + return yield (0, prompt_1.choice)(keys, { cmd: false, select: true }, keys.length - 1).then((x) => x); } catch (e) { throw e; @@ -238,28 +236,80 @@ function checkout() { } let cache_queue; function queue_id(org, id) { + (0, executors_1.printTableHeader)(" ", { + River: 12, + Event: 12, + Status: 7, + "Queue time": 20, + }); return (0, prompt_1.choice)(cache_queue .filter((x) => x.id === id) .map((x) => ({ long: x.r, - text: `${alignRight(x.r, 12)} │ ${alignLeft(x.e, 12)} │ ${new Date(x.q).toLocaleString()}`, + text: `${(0, executors_1.alignRight)(x.r, 12)} │ ${(0, executors_1.alignLeft)(x.e, 12)} │ ${(0, executors_1.alignLeft)(x.s, 7)} │ ${new Date(x.q).toLocaleString()}`, action: () => queue_event(org, x.id, x.r), - })), false).then((x) => x); + })), { cmd: true, select: true }).then((x) => x); +} +function queue_time_value(org, time) { + (0, utils_1.addToExecuteQueue)(() => (0, executors_1.do_queue_time)(org, time)); + return (0, utils_1.finish)(); +} +function queue_time(org) { + return __awaiter(this, void 0, void 0, function* () { + try { + let d = new Date(yield (0, prompt_1.shortText)("Time", "Displays events _around_ specified time.", "1995-12-17T03:24:00")).getTime(); + while (isNaN(d)) { + (0, utils_1.output2)("Invalid date, please try again."); + d = new Date(yield (0, prompt_1.shortText)("Time", "Displays events _around_ specified time.", "1995-12-17T03:24:00")).getTime(); + } + return queue_time_value(org, d); + } + catch (e) { + throw e; + } + }); } -function queue(org) { +const QUEUE_COUNT = 15; +function queue(org, offset) { return __awaiter(this, void 0, void 0, function* () { try { - let resp = yield (0, utils_1.sshReq)(`queue`, `--org`, org); - cache_queue = JSON.parse(resp); - return yield (0, prompt_1.choice)(cache_queue.map((x) => ({ - long: x.id, - text: `${x.id} │ ${alignRight(x.r, 12)} │ ${alignLeft(x.e, 12)} │ ${new Date(x.q).toLocaleString()}`, - action: () => { - if ((0, args_1.getArgs)().length === 0) - (0, args_1.initializeArgs)([x.r]); - return queue_id(org, x.id); - }, - })), false).then((x) => x); + let options; + if (["time", "next"].includes((0, args_1.getArgs)()[0])) { + options = []; + } + else { + let resp = yield (0, utils_1.sshReq)(`queue`, `--org`, org, "--count", "" + QUEUE_COUNT, "--offset", "" + offset); + cache_queue = JSON.parse(resp); + (0, executors_1.printTableHeader)(" ", { + Id: 6, + River: 12, + Event: 12, + Status: 7, + "Queue time": 20, + }); + options = cache_queue.map((x) => ({ + long: x.id, + text: `${x.id} │ ${(0, executors_1.alignRight)(x.r, 12)} │ ${(0, executors_1.alignLeft)(x.e, 12)} │ ${(0, executors_1.alignLeft)(x.s, 7)} │ ${new Date(x.q).toLocaleString()}`, + action: () => { + if ((0, args_1.getArgs)().length === 0) + (0, args_1.initializeArgs)([x.r]); + return queue_id(org, x.id); + }, + })); + } + options.push({ + long: `next`, + short: `n`, + text: `next page`, + action: () => queue(org, offset + QUEUE_COUNT), + }); + options.push({ + long: `time`, + short: `t`, + text: `specify time`, + action: () => queue_time(org), + }); + return yield (0, prompt_1.choice)(options, { cmd: false, select: false }).then((x) => x); } catch (e) { throw e; @@ -348,16 +398,6 @@ function envvar_key(org, group, overwrite, key, currentValue) { } }); } -function alignRight(str, width) { - return str.length > width - ? str.substring(0, width - 3) + "..." - : str.padStart(width, " "); -} -function alignLeft(str, width) { - return str.length > width - ? str.substring(0, width - 3) + "..." - : str.padEnd(width, " "); -} function keys(org) { return __awaiter(this, void 0, void 0, function* () { try { @@ -371,7 +411,7 @@ function keys(org) { let n = x.name || ""; return { long: x.key, - text: `${x.key} │ ${alignLeft(n, 12)} │ ${ds}`, + text: `${x.key} │ ${(0, executors_1.alignLeft)(n, 12)} │ ${ds}`, action: () => keys_key(org, x.key, x.name), }; }); @@ -381,6 +421,7 @@ function keys(org) { text: `add a new apikey`, action: () => keys_key(org, null, ""), }); + (0, executors_1.printTableHeader)(" ", { Key: 36, Name: 12, "Expiry time": 20 }); return yield (0, prompt_1.choice)(options).then((x) => x); } catch (e) { @@ -477,7 +518,7 @@ function cron(org) { let orgs = JSON.parse(resp); let options = orgs.map((x) => ({ long: x.name, - text: `${alignRight(x.name, 10)} │ ${alignRight(x.event, 10)} │ ${x.expression}`, + text: `${(0, executors_1.alignRight)(x.name, 10)} │ ${(0, executors_1.alignRight)(x.event, 10)} │ ${x.expression}`, action: () => cron_name(org, x.name, x.event, x.expression), })); options.push({ @@ -486,6 +527,7 @@ function cron(org) { text: `setup a new cron job`, action: () => cron_new(org), }); + (0, executors_1.printTableHeader)(" ", { Name: 10, Event: 10, Expression: 20 }); return yield (0, prompt_1.choice)(options).then((x) => x); } catch (e) { @@ -557,7 +599,7 @@ function start() { long: "queue", short: "q", text: "display the message queues or events", - action: () => queue(orgName), + action: () => queue(orgName, 0), }); if (fs_1.default.existsSync("mist.json") || fs_1.default.existsSync("merrymake.json")) { // Inside a service diff --git a/questions.ts b/questions.ts index b35a23e..e94487a 100644 --- a/questions.ts +++ b/questions.ts @@ -16,6 +16,7 @@ import { finish, getCache, getFiles, + output2, sshReq, } from "./utils"; import { Option } from "./prompt"; @@ -38,6 +39,10 @@ import { do_envvar, do_cron, do_duplicate, + do_queue_time, + printTableHeader, + alignRight, + alignLeft, } from "./executors"; import { VERSION_CMD, type ProjectType } from "@merrymake/detect-project-type"; import { execSync } from "child_process"; @@ -106,7 +111,7 @@ async function service_template(pathToService: Path, template: string) { } } -async function duplicate_service_deploy( +function duplicate_service_deploy( pathToService: Path, org: string, group: string, @@ -267,7 +272,11 @@ async function register() { text: "Setup new key specifically for Merrymake", action: () => register_key(generateNewKey), }); - return await choice(keys, true, keys.length - 1).then((x) => x); + return await choice( + keys, + { cmd: false, select: true }, + keys.length - 1 + ).then((x) => x); } catch (e) { throw e; } @@ -304,41 +313,110 @@ let cache_queue: { q: string; e: string; r: string; + s: string; }[]; function queue_id(org: string, id: string) { + printTableHeader(" ", { + River: 12, + Event: 12, + Status: 7, + "Queue time": 20, + }); return choice( cache_queue .filter((x) => x.id === id) .map((x) => ({ long: x.r, - text: `${alignRight(x.r, 12)} │ ${alignLeft(x.e, 12)} │ ${new Date( - x.q - ).toLocaleString()}`, + text: `${alignRight(x.r, 12)} │ ${alignLeft(x.e, 12)} │ ${alignLeft( + x.s, + 7 + )} │ ${new Date(x.q).toLocaleString()}`, action: () => queue_event(org, x.id, x.r), })), - false + { cmd: true, select: true } ).then((x) => x); } -async function queue(org: string) { +function queue_time_value(org: string, time: number) { + addToExecuteQueue(() => do_queue_time(org, time)); + return finish(); +} + +async function queue_time(org: string) { try { - let resp = await sshReq(`queue`, `--org`, org); - cache_queue = JSON.parse(resp); - return await choice( - cache_queue.map((x) => ({ + let d = new Date( + await shortText( + "Time", + "Displays events _around_ specified time.", + "1995-12-17T03:24:00" + ) + ).getTime(); + while (isNaN(d)) { + output2("Invalid date, please try again."); + d = new Date( + await shortText( + "Time", + "Displays events _around_ specified time.", + "1995-12-17T03:24:00" + ) + ).getTime(); + } + return queue_time_value(org, d); + } catch (e) { + throw e; + } +} + +const QUEUE_COUNT = 15; +async function queue(org: string, offset: number) { + try { + let options: Option[]; + if (["time", "next"].includes(getArgs()[0])) { + options = []; + } else { + let resp = await sshReq( + `queue`, + `--org`, + org, + "--count", + "" + QUEUE_COUNT, + "--offset", + "" + offset + ); + cache_queue = JSON.parse(resp); + printTableHeader(" ", { + Id: 6, + River: 12, + Event: 12, + Status: 7, + "Queue time": 20, + }); + options = cache_queue.map((x) => ({ long: x.id, text: `${x.id} │ ${alignRight(x.r, 12)} │ ${alignLeft( x.e, 12 - )} │ ${new Date(x.q).toLocaleString()}`, + )} │ ${alignLeft(x.s, 7)} │ ${new Date(x.q).toLocaleString()}`, action: () => { if (getArgs().length === 0) initializeArgs([x.r]); return queue_id(org, x.id); }, - })), - false - ).then((x) => x); + })); + } + options.push({ + long: `next`, + short: `n`, + text: `next page`, + action: () => queue(org, offset + QUEUE_COUNT), + }); + options.push({ + long: `time`, + short: `t`, + text: `specify time`, + action: () => queue_time(org), + }); + return await choice(options, { cmd: false, select: false }).then((x) => x); } catch (e) { throw e; } @@ -487,18 +565,6 @@ async function envvar_key( } } -function alignRight(str: string, width: number) { - return str.length > width - ? str.substring(0, width - 3) + "..." - : str.padStart(width, " "); -} - -function alignLeft(str: string, width: number) { - return str.length > width - ? str.substring(0, width - 3) + "..." - : str.padEnd(width, " "); -} - async function keys(org: string) { try { let resp = await sshReq(`list-keys`, `--org`, org); @@ -522,6 +588,7 @@ async function keys(org: string) { text: `add a new apikey`, action: () => keys_key(org, null, ""), }); + printTableHeader(" ", { Key: 36, Name: 12, "Expiry time": 20 }); return await choice(options).then((x) => x); } catch (e) { throw e; @@ -651,6 +718,7 @@ async function cron(org: string) { text: `setup a new cron job`, action: () => cron_new(org), }); + printTableHeader(" ", { Name: 10, Event: 10, Expression: 20 }); return await choice(options).then((x) => x); } catch (e) { throw e; @@ -727,7 +795,7 @@ export async function start() { long: "queue", short: "q", text: "display the message queues or events", - action: () => queue(orgName), + action: () => queue(orgName, 0), }); if (fs.existsSync("mist.json") || fs.existsSync("merrymake.json")) { // Inside a service