// eslint-disable-next-line no-unused-vars const { Interpreter, Command, CommandType, InMemoryConnectionData, DelegatesCache } = require('../../..') const AbstractHandler = require('./AbstractHandler') /** * PassDelegateHandler class responsible for processing a command to create a delegate. */ class PassDelegateHandler extends AbstractHandler { constructor() { super() /** * Minimum required parameters count for the command. * @type {number} */ this.requiredParametersCount = 1 this.interpreter = new Interpreter() } /** * Processes the given command to create and compile a delegate. * @param {Command} command - The command to process. * @returns {Function} The compiled delegate function. */ process(command) { this.validateCommand(command) const delegateGuid = command.payload[0] const delegate = DelegatesCache.getDelegate(delegateGuid) return delegate } /** * Validates the command to ensure it has enough parameters. * @param {Command} command - The command to validate. */ validateCommand(command) { if (command.payload.length < this.requiredParametersCount) { throw new Error('PassDelegateHandler parameters mismatch') } } /** * Retrieves the arguments from the command payload. * @param {Command} command - The command containing the payload. * @returns {Array} The extracted arguments. */ getArguments(command) { return command.payload.length > 2 ? command.payload.slice(2) : [] } /** * Extracts argument types from the arguments array. * @param {Array} args - The arguments array. * @returns {Array} The argument types. */ getArgumentTypes(args) { return args.slice(0, -1).map((arg) => arg.constructor) } /** * Retrieves the return type from the arguments array. * @param {Array} args - The arguments array. * @returns {Function} The return type. */ getReturnType(args) { return args[args.length - 1].constructor } /** * Creates parameter expressions from argument types. * @param {Array} argsTypes - The argument types. * @returns {Array} The parameter expressions. */ createParameters(argsTypes) { return argsTypes.map((type, index) => ({ name: `arg${index}`, type })) } /** * Creates an array of arguments for the delegate. * @param {string} delegateGuid - The delegate identifier. * @param {Array} parameters - The parameter expressions. * @returns {Array} The arguments array. */ createArgsArray(delegateGuid, parameters) { return [delegateGuid, ...parameters.map((param) => param.name)] } /** * Creates a command expression. * @param {string} callingRuntimeName - The runtime name. * @param {Array} payload - The arguments array. * @returns {Object} The command object. */ createCommand(callingRuntimeName, payload) { return { runtimeName: callingRuntimeName, type: CommandType.InvokeDelegate, payload, } } /** * Creates a method call to execute the command. * @param {Command} command - The command object. * @returns {Object} The response object. */ createExecuteCall(command) { return this.interpreter.execute(command, new InMemoryConnectionData()) } /** * Retrieves the response payload from the execution call. * @param {Object} executeCall - The execution call. * @returns {Array} The response payload. */ getResponse(executeCall) { return executeCall.payload } /** * Converts the first element of the response to the return type. * @param {Array} response - The response payload. * @param {Function} returnType - The return type. * @returns {*} The converted first element. */ convertFirstElement(response, returnType) { return returnType(response[0]) } /** * Creates a block of expressions for the delegate. * @param {Function} returnType - The return type. * @param {*} convertedFirstElement - The converted first element. * @returns {Object} The block expression. */ createBlock(returnType, convertedFirstElement) { return { returnType, body: convertedFirstElement } } /** * Creates a delegate type. * @param {Array} parameters - The parameter expressions. * @param {Function} returnType - The return type. * @returns {Function} The delegate type. */ createDelegateType(parameters, returnType) { return (...args) => { if (args.length !== parameters.length) { throw new Error('Invalid argument count.') } return returnType } } } module.exports = new PassDelegateHandler()