UNPKG

nope-js-node

Version:

NoPE Runtime for Nodejs. For Browser-Support please use nope-browser

227 lines (226 loc) 10.5 kB
"use strict"; /** * @author Martin Karkowski * @email m.karkowski@zema.de * @create date 2021-11-11 11:36:37 * @modify date 2021-11-11 11:36:37 * @desc [description] */ Object.defineProperty(exports, "__esModule", { value: true }); exports.parseFunctionToOpenAPI = exports.parseModuleToOpenAPI = void 0; const promises_1 = require("fs/promises"); const handlebars = require("handlebars"); const path_1 = require("path"); const fileMethods_1 = require("../../helpers/fileMethods"); const objectMethods_1 = require("../../helpers/objectMethods"); const stringMethods_1 = require("../../helpers/stringMethods"); /** * Helper function to merge the Parameters into 1 description. * @param elements */ function _unifySchema(elements, options) { const ret = { type: "object", properties: {}, required: [], }; for (const item of elements) { if (options.sharedDefinitions) { item.schema.definitions = undefined; item.schema.$schema = undefined; } // Assign the Schema ret.properties[item.name] = item.schema; // If the Element is Optional, if (!item.optional) { ret.required.push(item.name); } } return ret; } /** * Function, to parse a description to an Open-API Element. * @param description * @param options */ async function parseModuleToOpenAPI(description, options) { const _description = (0, objectMethods_1.deepClone)(description); // load the Template. const template = await (0, promises_1.readFile)((0, path_1.join)(process.cwd(), "lib", "parsers", "open-api", "templates", "method." + options.mode + ".handlebars"), { encoding: "utf-8", }); // Renderfuncting const renderAPI = handlebars.compile(template); await (0, fileMethods_1.createPath)((0, path_1.join)(options.outputDir)); // Now iterate over the Methods of the Module and find parsable Methods. for (const [idx, method] of _description.methods.entries()) { // Test if the Method contains some functions in the input / Output: const parsedInputs = JSON.stringify(method.schema.inputs); const parsedOutput = JSON.stringify(method.schema.outputs); if (!parsedInputs.includes('"function"') && !parsedOutput.includes('"function"')) { // The Method should be parseable. // 1. Specify the Mode (No Params = GET, else POST) method.mode = method.schema.inputs.length > 0 ? "POST" : "GET"; method.required = method.schema.inputs .filter((param) => { return !param.optional; }) .map((param) => param.name); method.hasInput = method.schema.inputs.length > 0; // Now adapt the Schema of the Method. // Iterate over the Inputs, add a Description if not provided // And determine whehter the Parameters are required or not. method.schema.inputs = method.schema.inputs.map((param) => { // Provide a Description. (If not provided) param.description = param.description || "Not provided"; if (options.sharedDefinitions) { param.schema.definitions = undefined; param.schema.$schema = undefined; } // Parse the Schema in here. param.parsedSchema = JSON.stringify(param.schema); return param; }); // Make shure the Return type isnt an array method.schema.outputs = Array.isArray(method.schema.outputs) ? _unifySchema(method.schema.outputs, options) : method.schema.outputs; if (options.sharedDefinitions) { method.schema.outputs.definitions = undefined; method.schema.outputs.$schema = undefined; } // Add an Description to the result. method.resultDescription = method.schema.outputs.description || "Not Provided"; // And add a Schema for the Return type. method.parsedOutput = JSON.stringify(method.schema.outputs); method.parsedInput = JSON.stringify(_unifySchema(method.schema.inputs, options)); method.hasInput = method.schema.inputs.length > 0; method.tag = description.name; // Determine the Filename. const fileDir = (0, path_1.join)(options.outputDir, _description.name, "{instance}", "methods"); const fileName = (0, path_1.join)(fileDir, method.id + "." + options.mode); // Determine the Import Pathes. const imports = [ { dir: (0, path_1.join)(process.cwd(), "lib", "types", "nope"), fileName: "nopeDispatcher.interface", name: "pathOfDispatcher", }, { dir: (0, path_1.join)(process.cwd(), "lib", "helpers"), fileName: "dispatcherPathes", name: "pathOfHelper", }, ]; for (const imp of imports) { const relativDir = (0, path_1.relative)(fileDir, imp.dir); method[imp.name] = (0, path_1.join)((0, fileMethods_1.convertPathToOsPath)(relativDir), (0, fileMethods_1.convertPathToOsPath)(imp.fileName)); } // Write down the Schema: await (0, fileMethods_1.createFile)( // Generate the Path. fileName, renderAPI(method)); if (options.logger) { options.logger.info("Generated -> " + fileName); } } else if (options.logger) { options.logger.warn('parser can not convert: "' + description.name + "." + method.id + '". The Function contains functions as parameters'); } } } exports.parseModuleToOpenAPI = parseModuleToOpenAPI; /** * Function, to parse a description to an Open-API Element. * @param description * @param options */ async function parseFunctionToOpenAPI(description, options) { const _description = (0, objectMethods_1.deepClone)(description); // load the Template. const template = await (0, promises_1.readFile)((0, path_1.join)(process.cwd(), "lib", "parsers", "open-api", "templates", "function." + options.mode + ".handlebars"), { encoding: "utf-8", }); // Renderfuncting const renderAPI = handlebars.compile(template); await (0, fileMethods_1.createPath)((0, path_1.join)(options.outputDir)); // Now iterate over the Methods of the Module and find parsable Methods. // Test if the Method contains some functions in the input / Output: const parsedInputs = JSON.stringify(_description.schema.inputs); const parsedOutput = JSON.stringify(_description.schema.outputs); if (!parsedInputs.includes('"function"') && !parsedOutput.includes('"function"')) { // The Method should be parseable. // 1. Specify the Mode (No Params = GET, else POST) _description.mode = _description.schema.inputs.length > 0 ? "POST" : "GET"; // Now adapt the Schema of the Method. // Iterate over the Inputs, add a Description if not provided // And determine whehter the Parameters are required or not. _description.schema.inputs = _description.schema.inputs.map((param) => { // Provide a Description. (If not provided) param.description = param.description || "Not provided"; if (options.sharedDefinitions) { param.schema.definitions = undefined; param.schema.$schema = undefined; } // Parse the Schema in here. param.parsedSchema = JSON.stringify(param.schema); return param; }); // Make shure the Return type isnt an array _description.schema.outputs = Array.isArray(_description.schema.outputs) ? _unifySchema(_description.schema.outputs, options) : _description.schema.outputs; if (options.sharedDefinitions) { _description.schema.outputs.definitions = undefined; _description.schema.outputs.$schema = undefined; } // Add an Description to the result. _description.resultDescription = _description.schema.outputs.description || "Not Provided"; // And add a Schema for the Return type. _description.parsedOutput = JSON.stringify(_description.schema.outputs); _description.tag = "generic-services"; _description.parsedInput = JSON.stringify(_unifySchema(_description.schema.inputs, options)); _description.hasInput = _description.schema.inputs.length > 0; _description.required = _description.schema.inputs .filter((param) => !param.optional) .map((param) => param.name); _description.name = _description.id; // Determine the Filename. const fileDir = (0, path_1.join)(options.outputDir, "generic-services"); const fileName = (0, path_1.join)(fileDir, _description.id + "." + options.mode); // Determine the Import Pathes. const imports = [ { dir: (0, path_1.join)(process.cwd(), "lib", "types", "nope"), fileName: "nopeDispatcher.interface", name: "pathOfDispatcher", }, ]; for (const imp of imports) { const relativDir = (0, path_1.relative)(fileDir, imp.dir); _description[imp.name] = (0, stringMethods_1.replaceAll)((0, path_1.join)(relativDir, imp.fileName), "\\", "/"); } // Write down the Schema: await (0, fileMethods_1.createFile)( // Generate the Path. fileName, renderAPI(_description)); if (options.logger) { options.logger.info("Generated -> " + fileName); } } else if (options.logger) { options.logger.warn('parser can not convert: "' + _description.id + '". The Function contains functions as parameters'); } } exports.parseFunctionToOpenAPI = parseFunctionToOpenAPI;