@sap/cli-core
Version:
Command-Line Interface (CLI) Core Module
95 lines (94 loc) • 4.7 kB
JavaScript
import { init } from "../../discovery/index.js";
import { get } from "../../logger/index.js";
import { OPTION_HOST } from "../../constants.js";
import { createFetchHandler, createMandatoryOptionsHandler, createNextHandler, createParseArgumentsHandler, createAuthenticationHandler, createOptionsHandler, } from "../handler/index.js";
import { buildCommand } from "../../utils/commands.js";
import { getDescriptionForCommand, getSchema, handleDeprecationNotice, handleForceOption, handleParameters, handleReadPathHandler, handleRequestBody, handleResponses, updatePath, } from "./utils.js";
const getLogger = () => get("commands.openAPI");
const getCommandDescription = (document, segments, index) => {
const segment = segments
.slice(0, index + 1)
.reduce((prev, curr) => (prev !== "" ? `${prev} ${curr}` : curr), "");
return document.tags.find((t) => t.name === segment)?.description ?? "";
};
const addCommandToArray = (document, commands, segments, index) => {
const segment = segments[index];
let command = commands.find((c) => c.command === segment);
if (command?.type === "topCommand") {
return addCommandToArray(document, command.subCommands, segments, index + 1);
}
if (index + 1 < segments.length) {
command = {
type: "topCommand",
description: getCommandDescription(document, segments, index),
command: segment,
subCommands: [],
options: [OPTION_HOST],
};
commands.push(command);
return addCommandToArray(document, command.subCommands, segments, index + 1);
}
// @ts-expect-error ts(2322) handler is missing - OK
command = {
type: "command",
description: getCommandDescription(document, segments, index),
command: segment,
options: [],
};
// @ts-expect-error ts(2345) handler is missing - OK
commands.push(command);
// @ts-expect-error ts(2345) handler is missing - OK
return { command, remove: () => commands.splice(commands.length - 1, 1) };
};
const setHandler = (command, method, path, parameterMappings, readPathResponseHandler, ...handler) => {
// eslint-disable-next-line no-param-reassign
command.handler = createNextHandler("openAPI.command", createParseArgumentsHandler(), createMandatoryOptionsHandler(), createAuthenticationHandler(), ...handler, createFetchHandler(method, path, parameterMappings, readPathResponseHandler));
};
export const addCommands = async (program) => {
const { error, debug, trace } = getLogger();
try {
const doc = await init();
const commands = [];
for (const path of Object.keys(doc.paths)) {
const pathItem = doc.paths[path];
for (const method of Object.keys(pathItem).filter((i) => i !== "parameters")) {
const handler = [];
let remove;
try {
const parameterMappings = [];
const operation = pathItem[method];
const cmd = addCommandToArray(doc, commands, operation.operationId.split(" "), 0);
remove = cmd.remove;
const { command } = cmd;
command.description = getDescriptionForCommand(command, operation);
handleRequestBody(operation, handler, doc, parameterMappings, command);
handleForceOption(operation, handler);
handleResponses(operation, command);
handleParameters(operation, doc, parameterMappings, command, getSchema(pathItem.parameters || [], doc));
handleDeprecationNotice(operation, command);
const readPathResponseHandler = handleReadPathHandler(doc, operation);
setHandler(command, method, updatePath(doc, path), parameterMappings, readPathResponseHandler, ...[createOptionsHandler(command.options), ...handler]);
delete command.options;
}
catch (err) {
error("cannot add command", err.stack);
remove();
}
}
}
for (const command of commands) {
trace("adding command %s", JSON.stringify(command));
try {
// eslint-disable-next-line no-await-in-loop
await buildCommand(program, command);
}
catch (err) {
error("error while adding command %s", JSON.stringify(command, null, 2), err.stack);
}
}
}
catch (err) {
debug("error while initializing discovery", err.stack);
throw err;
}
};