@constructor-io/constructorio-connect-cli
Version:
CLI tool to enable users to interface with the Constructor Connect Ecosystem
160 lines (159 loc) • 8.33 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Execute = exports.executePromptMessages = void 0;
const core_1 = require("@oclif/core");
const errors_1 = require("@oclif/core/errors");
const file_loaders_1 = require("../helpers/file-loaders");
const get_connections_request_1 = require("../http/get-connections-request");
const send_template_execute_request_1 = require("../http/send-template-execute-request");
const filter_connections_by_template_1 = require("../prompt-data/filter-connections-by-template");
const get_candidate_fixtures_1 = require("../prompt-data/get-candidate-fixtures");
const get_external_data_files_1 = require("../prompt-data/get-external-data-files");
const get_template_files_1 = require("../prompt-data/get-template-files");
const render_prompt_1 = require("../prompt-data/render-prompt");
const render_repeat_input_1 = require("../rendering/render-repeat-input");
const render_template_result_1 = require("../rendering/render-template-result");
const path_1 = require("../customer/path");
const config_1 = require("../customer/config");
const template_source_code_1 = require("../customer/template-source-code");
const ux_action_1 = require("../helpers/ux-action");
const print_warnings_1 = require("../helpers/print-warnings");
const extract_template_type_1 = require("../helpers/extract-template-type");
const refresh_connections_command_1 = require("./refresh-connections-command");
exports.executePromptMessages = {
template: "Select a template to execute",
fixture: "Select a catalog fixture to run the template against",
external: "Select external data to run the template against",
connection: "Select a connection to execute templates against",
};
class Execute extends refresh_connections_command_1.RefreshConnectionsCommand {
static flags = {
"template-path": core_1.Flags.string({
description: "The path to the template to execute. Must be in the 'src/templates' directory.",
}),
"fixture-path": core_1.Flags.string({
description: "The path to the fixture to execute the template against. Must be in the 'src/fixtures' directory.",
}),
"external-data-path": core_1.Flags.string({
description: "The path to the external data to execute the template against. Must be in the 'src/fixtures/external_data' directory.",
}),
"connection-id": core_1.Flags.string({
description: "The ID of the connection to execute the template against.",
}),
};
static description = "Execute a template against a connection and fixture to see the resulting transformed data. Each value not provided as a flag will be prompted for when the command is executed.";
static examples = [
"$ <%= config.bin %> execute",
"$ <%= config.bin %> execute --template-path=item/item.jsonata",
"$ <%= config.bin %> execute --template-path=variation/variation.jsonata",
"$ <%= config.bin %> execute --template-path=item_group/item_group.jsonata --fixture-path=item_group.json",
"$ <%= config.bin %> execute --template-path=grouping/grouping.jsonata --connection-id=example-connection-id",
"$ <%= config.bin %> execute --template-path=mapping/mapping.jsonata",
];
input = {};
async runCommand() {
try {
const templateInput = await this.getTemplateExecInput();
const config = await (0, ux_action_1.uxAction)("📡 Reading your config", async () => {
return await (0, config_1.getRepositoryConfigFile)();
})();
const result = await (0, send_template_execute_request_1.sendTemplateExecuteRequest)({
template: (0, file_loaders_1.getJSONataTemplate)(templateInput.templatePath).toString(),
helpers: (await (0, template_source_code_1.getHelpersSourceCode)(config.helpers)) ?? "",
data: (0, file_loaders_1.getCatalogFixture)(templateInput.fixturePath),
external: templateInput.externalPath
? (0, file_loaders_1.getExternalFixture)(templateInput.externalPath)
: {},
connectionId: templateInput.connectionId,
templateType: (0, extract_template_type_1.extractTemplateType)(templateInput.templatePath),
});
(0, render_template_result_1.renderTemplateResult)(result);
if (result.warnings.length > 0) {
(0, print_warnings_1.printExecutionWarnings)({
warnings: result.warnings,
});
}
if (!result?.success) {
this.exit(1);
}
}
finally {
(0, render_repeat_input_1.renderRepeatInput)(this, this.input);
}
}
async parseFlags() {
const { flags } = await this.parse(Execute);
if (flags["template-path"]) {
this.input["template-path"] = (0, path_1.cleanupPath)(flags["template-path"]);
}
if (flags["fixture-path"]) {
this.input["fixture-path"] = (0, path_1.cleanupPath)(flags["fixture-path"]);
}
if (flags["external-data-path"]) {
this.input["external-data-path"] = (0, path_1.cleanupPath)(flags["external-data-path"]);
}
if (flags["connection-id"]) {
this.input["connection-id"] = flags["connection-id"];
}
}
async getTemplateExecInput() {
const allConnections = await (0, get_connections_request_1.getConnections)({
showLogs: true,
});
await this.parseFlags();
if (!this.input["template-path"]) {
this.input["template-path"] = await (0, render_prompt_1.renderPrompt)({
choices: await (0, get_template_files_1.getTemplateFiles)(),
promptMessage: exports.executePromptMessages.template,
emptyMessage: "No templates found",
});
}
if (!this.input["fixture-path"]) {
this.input["fixture-path"] = await (0, render_prompt_1.renderPrompt)({
choices: (0, get_candidate_fixtures_1.getCandidateFixtures)(this.input["template-path"]),
promptMessage: exports.executePromptMessages.fixture,
emptyMessage: "No fixtures found for this template",
});
}
if (!this.input["external-data-path"]) {
const choices = (0, get_external_data_files_1.getExternalFiles)();
if (choices.length) {
this.input["external-data-path"] = await (0, render_prompt_1.renderPrompt)({
choices,
promptMessage: exports.executePromptMessages.external,
emptyMessage: "No external data found",
});
}
}
const connectionId = await this.validateAndGetConnection(allConnections, this.input["template-path"]);
// Let's make sure to re-set the input value since the user might
// have just chosen one
this.input["connection-id"] = connectionId;
return {
templatePath: this.input["template-path"],
fixturePath: this.input["fixture-path"],
externalPath: this.input["external-data-path"] ?? "",
connectionId,
};
}
async validateAndGetConnection(allConnections, templatePath) {
let connection = allConnections.find((c) => c.id === this.input["connection-id"]);
if (this.input["connection-id"] && !connection) {
throw new errors_1.CLIError(`Connection with ID ${this.input["connection-id"]} not found`, {
suggestions: ["Check that the connectionId is correct"],
});
}
if (!connection) {
connection = await this.getConnectionForTemplate(templatePath, allConnections);
}
return connection.id;
}
async getConnectionForTemplate(templatePath, allConnections) {
const choices = await (0, filter_connections_by_template_1.filterConnectionsByTemplate)(templatePath, allConnections);
if (choices.length === 0) {
throw new errors_1.CLIError(`No mapped connections found for this template`);
}
return choices[0];
}
}
exports.Execute = Execute;