@sprucelabs/spruce-cli
Version:
Command line interface for building Spruce skills.
124 lines • 5.16 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const spruce_event_utils_1 = require("@sprucelabs/spruce-event-utils");
const merge_1 = __importDefault(require("lodash/merge"));
const SpruceError_1 = __importDefault(require("../errors/SpruceError"));
const action_utility_1 = __importDefault(require("../utilities/action.utility"));
const ActionQuestionAsker_1 = __importDefault(require("./ActionQuestionAsker"));
class ActionExecuter {
emitter;
ui;
actions;
featureInstallerFactory;
shouldAutoHandleDependencies;
shouldThrowOnListenerError;
constructor(options) {
this.featureInstallerFactory = options.featureInstallerFactory;
this.emitter = options.emitter;
this.ui = options.ui;
this.actions = options.actionFactory;
this.shouldAutoHandleDependencies =
options.shouldAutoHandleDependencies ?? true;
this.shouldThrowOnListenerError = !!options.shouldThrowOnListenerError;
}
getFeatureInstaller() {
return this.featureInstallerFactory();
}
async execute(options) {
const { featureCode, actionCode, action, originalExecute, options: actionOptions, } = options;
const installer = this.getFeatureInstaller();
const isInstalled = await installer.isInstalled(featureCode);
if (!isInstalled && !this.shouldAutoHandleDependencies) {
throw new SpruceError_1.default({
code: 'FEATURE_NOT_INSTALLED',
featureCode,
friendlyMessage: `You need to install the \`${featureCode}\` feature.`,
});
}
const willExecuteResults = await this.emitter.emit('feature.will-execute', {
featureCode,
actionCode,
options: actionOptions,
});
const { payloads: willExecutePayloads, errors } = spruce_event_utils_1.eventResponseUtil.getAllResponsePayloadsAndErrors(willExecuteResults, SpruceError_1.default);
if (errors?.length ?? 0 > 0) {
if (this.shouldThrowOnListenerError) {
//@ts-ignore
throw errors[0];
}
return { errors };
}
action_utility_1.default.assertNoErrorsInResponse(willExecuteResults);
const feature = installer.getFeature(featureCode);
const asker = ActionQuestionAsker_1.default.Asker({
featureInstaller: installer,
feature,
actionCode,
shouldAutoHandleDependencies: this.shouldAutoHandleDependencies,
ui: this.ui,
});
let response = (await asker.installOrMarkAsSkippedMissingDependencies()) ?? {};
const installOptions = (await asker.askAboutMissingFeatureOptionsIfFeatureIsNotInstalled(isInstalled, actionOptions)) ??
actionOptions ??
{};
let answers = (await asker.askAboutMissingActionOptions(action, installOptions)) ?? installOptions;
if (!isInstalled) {
const ourFeatureResults = (await asker.installOurFeature(installOptions)) ?? {};
response = (0, merge_1.default)(response, ourFeatureResults);
}
let executeResults = {};
try {
executeResults = await originalExecute({
...answers,
});
}
catch (err) {
executeResults.errors = [err];
}
response = (0, merge_1.default)(response, executeResults);
const didExecuteResults = await this.emitter.emit('feature.did-execute', {
results: response,
featureCode,
actionCode,
options: actionOptions,
});
const { payloads, errors: didExecuteErrors } = spruce_event_utils_1.eventResponseUtil.getAllResponsePayloadsAndErrors(didExecuteResults, SpruceError_1.default);
if ((this.shouldThrowOnListenerError && didExecuteErrors?.length) ??
0 > 0) {
//@ts-ignore
throw didExecuteErrors[0];
}
response = action_utility_1.default.mergeActionResults(response, ...willExecutePayloads, ...payloads);
if (didExecuteErrors) {
response = action_utility_1.default.mergeActionResults(response, {
errors: didExecuteErrors,
});
}
return response;
}
Action(featureCode, actionCode) {
const featureInstaller = this.getFeatureInstaller();
const action = this.actions.Action({
featureCode,
actionCode,
actionExecuter: this,
featureInstaller,
});
const originalExecute = action.execute.bind(action);
action.execute = async (options) => {
return this.execute({
featureCode,
actionCode,
action,
originalExecute,
options,
});
};
return action;
}
}
exports.default = ActionExecuter;
//# sourceMappingURL=ActionExecuter.js.map