UNPKG

nope-js-browser

Version:

NoPE Runtime for the Browser. For nodejs please use nope-js-node

267 lines (266 loc) 9.32 kB
/** * @author Martin Karkowski * @email m.karkowski@zema.de */ import { ArgumentParser } from "argparse"; import { join, resolve } from "path"; import "reflect-metadata"; import { convertPathToOsPath, createFile } from "../helpers/fileMethods"; import { getCentralDecoratedContainer, stringifyWithFunctions, } from "../index.browser"; import { listFunctions, listPackages } from "../index.nodejs"; import { readFile } from "node:fs/promises"; import { getNopeLogger } from "../index.browser"; import * as superagent from "superagent"; /** * Helper Function to write a default configuration. */ export async function writeUiFile(options = { dir: "./dist", filename: join(resolve(process.cwd()), "config", "ui.json"), }) { var _a; const uiFile = { functions: {}, classes: {}, }; const logger = getNopeLogger("ui-scanner"); // This call makes shure, that every function is loaded const functions = await listFunctions(options.dir); const packages = await listPackages(options.dir); const CONTAINER = getCentralDecoratedContainer(); // Determine all Packages for (const item of packages) { // Iterate over the classes. try { for (const cls of item.package.providedClasses) { const itemToAdd = { ui: cls.ui, // Define the Methods elements methods: {}, }; // The Service const services = ((_a = CONTAINER.classes.get(cls.description.name)) === null || _a === void 0 ? void 0 : _a._markedElements) || []; for (const srv of services) { if (srv.type === "method" && srv.options.ui) { itemToAdd.methods[srv.accessor] = srv.options.ui; } } if (itemToAdd.ui || Object.getOwnPropertyNames(itemToAdd.methods).length > 0) { // If an ui definition exists, we want // to export it and store it in our file. const ui = itemToAdd.ui || {}; const methods = itemToAdd.methods || {}; uiFile.classes[cls.description.name] = { ui, methods, }; } } // Iterate over the functions and provide their uis. item.package.providedServices.map((funcs) => { if (funcs.options.ui) { // Store the UI definition in the config file. uiFile.functions[funcs.options.id] = { id: funcs.options.id, ui: funcs.options.ui, schema: funcs.options.schema, }; } }); } catch (e) { logger.error("Failed to consider file", item.path); logger.error(e); } } for (const [id, data] of CONTAINER.services.entries()) { if (data.options.ui) { uiFile.functions[id] = { id, ui: data.options.ui, schema: data.options.schema, }; } } await createFile(options.filename, stringifyWithFunctions(uiFile, 4)); } /** * Helper to extract the Arguments for the `writeUiFile` function @see writeUiFile * * @author M.Karkowski * @export * @param additionalArguments Arguments added by the nope.cli * @return {*} The Arguments */ export function readInWriteUiFileArgs(additionalArguments = []) { const parser = new ArgumentParser({ // version: "1.0.0", add_help: true, description: "Command Line interface, determines the available Packages.", }); for (const arg of additionalArguments) { parser.add_argument(arg.name, { help: arg.help, default: arg.defaultValue, type: arg.type, }); } parser.add_argument("-f", "--file", { help: "Filename for the configuration.", default: "./config/ui.json", type: "str", dest: "filename", }); parser.add_argument("-d", "--dir", { help: "Directory to search for the ui definitions", default: "./modules", type: "str", dest: "dir", }); const args = parser.parse_args(); return args; } const VALID_MODES = ["replace", "merge"]; export const DEFAULT_SETTINGS = { file: "./config/ui.json", uri: "http://localhost:5001", mode: "merge", }; /** * Helper Function to Read-In the Arguments used by the * cli-tool * * @return {*} */ export async function readInArgs(additionalArguments = [], forcedArgs = {}) { const parser = new ArgumentParser({ // version: "1.0.0", add_help: true, description: "Command Line interface, to upload ui files", }); for (const arg of additionalArguments) { parser.add_argument(arg.name, { help: arg.help, default: arg.defaultValue, type: arg.type, }); } parser.add_argument("-f", "--file", { help: "File containing containing the package definitions. Defaults to '" + DEFAULT_SETTINGS.file + "'", default: DEFAULT_SETTINGS.file, type: "str", dest: "file", }); parser.add_argument("-m", "--mode", { help: "The mode, how to handle the ui defintion: " + // Display all Options: VALID_MODES.map((item) => { return '"' + item + '"'; }).join(", ") + '. Deaults to "' + DEFAULT_SETTINGS.mode + '"', default: DEFAULT_SETTINGS.mode, type: "str", dest: "mode", }); parser.add_argument("-u", "--uri", { help: "The URI of the Server. Defaults to '" + DEFAULT_SETTINGS.uri + ",", default: DEFAULT_SETTINGS.uri, type: "str", dest: "params", }); const args = parser.parse_args(); return Object.assign(args, forcedArgs); } export async function uploadUi(args) { const settingsToUse = Object.assign(DEFAULT_SETTINGS, args); let localContent = {}; const logger = getNopeLogger("ui-uploader-cli"); try { // Try to read in the default config file. logger.info(`Trying to read file ${settingsToUse.file}`); localContent = JSON.parse(await readFile(settingsToUse.file, { encoding: "utf-8", })); } catch (error) { logger.error("Failed to read File."); logger.error(error); } if (Object.keys(settingsToUse).length == 0) { logger.info("No Data contained. Goodbye!"); return; } async function getFiles(query = () => true, scope = {}) { const params = { query: stringifyWithFunctions(query), scope, }; const result = (await superagent.post(settingsToUse.uri + "/storage/query").send(params)).body; return result; } async function getContentOfNewestFile() { // Get all Possible Files const _files = await getFiles((item, scope) => { return item.identifier === "ui-definition"; }); let newest = null; _files.map((item) => { if (item.date > item.date) { newest = item; } else if (newest == null) { newest = item; } }); if (newest) { try { const _file = join(convertPathToOsPath(settingsToUse.uri), convertPathToOsPath(newest.path)); return (await superagent.get(_file)).body; } catch (e) { logger.error("Failed getting Data"); logger.error(e); } } return { functions: {}, classes: {}, }; } logger.info(`Uploading file '${settingsToUse.file}' to '${settingsToUse.uri}'`); let contentToUpload = localContent; if (settingsToUse.mode === "merge") { const currentContent = await getContentOfNewestFile(); contentToUpload.functions = Object.assign(currentContent.functions, localContent.functions); contentToUpload.classes = Object.assign(currentContent.classes, localContent.classes); } const params = { name: "ui", keywords: "ui-definition;", identifier: "ui-definition", data: contentToUpload, }; const result = await superagent .post(settingsToUse.uri + "/storage/upload-data") .send(params); logger.info("sucessfully uploaded the file."); } /** * Main Function. * * @export */ export async function main(additionalArguments = [], forcedArgs = {}) { const args = await readInArgs(additionalArguments, forcedArgs); return await uploadUi(args); } export default uploadUi; // If requested As Main => Perform the Operation. if (require.main === module) { main(); }