UNPKG

nope-js-browser

Version:

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

256 lines (255 loc) 10.3 kB
/** * Helper file to perform all releated task to create a project, * add services and modules to it. */ import { FOLDER_SPLIT, listFiles, createPath, createFile, replaceAll, insert, underscore, camelize, } from "../helpers/index.nodejs"; import { copyFile, readFile } from "fs/promises"; import { readFileSync } from "fs"; import { join, relative, resolve } from "path"; import * as handlebars from "handlebars"; import { existsSync } from "fs"; import { getNopeLogger } from "../index.browser"; import { simpleGit } from "simple-git"; const dirName = join(__dirname, "..", "..", "lib", "templates"); const INSERT_MARKER = " !! Insert-Marker: Don't remove this line !!"; const packageDirName = join(__dirname, "..", ".."); const packageJson = JSON.parse(readFileSync(join(packageDirName, "package.json")).toString("utf-8")); const currentNopeVersion = packageJson.version; function firstup(str) { str = camelize(str); return str[0].toUpperCase() + str.slice(1); } function toService(str) { str = firstup(str); if (str.endsWith("Service")) { return str; } return str + "Service"; } function toModule(str) { str = firstup(str); if (str.endsWith("Module")) { return str; } return str + "Module"; } function toInterface(str) { str = toModule(str); return "I" + str; } handlebars.registerHelper("underscore", function (str) { return underscore(str, true); }); handlebars.registerHelper("firstup", firstup); handlebars.registerHelper("now", function () { const now = new Date(); return (now.getDay().toString() + "." + now.getMonth().toString() + "." + now.getFullYear().toString()); }); handlebars.registerHelper("toService", toService); handlebars.registerHelper("toModule", toModule); handlebars.registerHelper("toInterface", toInterface); export function generateDefaultProject() { return { type: "python", version: "1.0", name: "name", dirName: "", path: "", modules: [], services: [], description: "", author: { forename: "", surename: "", mail: "", }, depencies: [], currentNopeVersion: currentNopeVersion, }; } /** * Helper to define the relevant project files. * @returns */ async function _getProjectTemplates(type) { const files = await listFiles(join(dirName, "projects", type), ".handlebars"); return files; } async function _getProjectFilesToCopy(type) { const files = await listFiles(join(dirName, "projects", type)); const filesToCopy = files.filter((item) => { const isTemplate = item.includes(".handlebars"); return !isTemplate; }); return filesToCopy; } function _relativePath(settings, type, path, dataForTemplate) { const templatePath = dirName + FOLDER_SPLIT + type + FOLDER_SPLIT + settings.type; const file = path.slice(templatePath.length); const fileTemplate = replaceAll(file, FOLDER_SPLIT, "__FOLDER_SPLITTING_CHAR__"); const render = handlebars.compile(fileTemplate); const result = render(dataForTemplate); const ret = replaceAll(result, "__FOLDER_SPLITTING_CHAR__", FOLDER_SPLIT); return ret; } async function _writeTemplate(path, templateFile, projectSettings, type, dataForTemplate, logger = null) { const render = handlebars.compile(await readFile(templateFile, { encoding: "utf-8" })); let filePath = path + _relativePath(projectSettings, type, templateFile, dataForTemplate); if (templateFile.endsWith(".extend.handlebars")) { filePath = filePath.slice(0, filePath.length - ".extend".length); } filePath = filePath.slice(0, filePath.length - ".handlebars".length); const content = render(dataForTemplate); if (templateFile.endsWith(".extend.handlebars") && existsSync(filePath)) { const text = await readFile(filePath, { encoding: "utf-8" }); const idxToInsert = text.includes(INSERT_MARKER) ? text.indexOf(INSERT_MARKER) + INSERT_MARKER.length : text.length; const contentToStore = insert(text, idxToInsert, "\n".repeat(1) + content); await createFile(filePath, contentToStore); if (logger) logger.info("updated\t", filePath); } else { await createFile(join(filePath), content); if (logger) logger.info("created\t", filePath); } } export async function createProject(projectSettings, dir, logger = null) { var _a; const path = await createPath(join(dir, projectSettings.name)); const filesToCopy = await _getProjectFilesToCopy(projectSettings.type); const promises = filesToCopy.map(async (file) => { const dest = await createFile(path + _relativePath(projectSettings, "projects", file, projectSettings), ""); await copyFile(file, dest); if (logger) logger.info("created\t", dest); }); await promises; // now we render the files. for (const templateFile of await _getProjectTemplates(projectSettings.type)) { await _writeTemplate(path, templateFile, projectSettings, "projects", projectSettings, logger); } projectSettings.path = resolve(process.cwd(), path); await createFile(join(path, "nope.json"), JSON.stringify(projectSettings, undefined, 4)); const git = simpleGit(path); // or await each step individually await git.init(); const files = await listFiles(path); const filesToCommit = files .filter((file) => !file.includes(FOLDER_SPLIT + ".git" + FOLDER_SPLIT)) .map((file) => relative(path, file)); // await git.add(files); await git.add(filesToCommit); await git.commit("initial commit"); if ((_a = projectSettings.git) === null || _a === void 0 ? void 0 : _a.repo) { await git.addRemote("origin", projectSettings.git.repo); } if (logger) logger.info("created\t", join(path, "nope.json")); } export async function addServiceToProject(projectSettings, service, logger = null) { let path = join(projectSettings.path, projectSettings.name); // List the relevant templates. const templates = await listFiles(join(dirName, "services", projectSettings.type), ".handlebars"); const settings = Object.assign({}, service, { project: projectSettings }); for (const templateFile of templates) { await _writeTemplate(path, templateFile, projectSettings, "services", settings, logger); } const files = await listFiles(join(dirName, "services", projectSettings.type)); const filesToCopy = files.filter((item) => { const isTemplate = item.includes(".handlebars"); return !isTemplate; }); const promises = filesToCopy.map(async (file) => { const dest = await createFile(path + _relativePath(projectSettings, "services", file, settings), ""); await copyFile(file, dest); if (logger) logger.info("created\t", dest); }); await promises; projectSettings.services.push(service); await createFile(join(projectSettings.path, "nope.json"), JSON.stringify(projectSettings, undefined, 4)); } export async function addModuleToProject(projectSettings, module, logger = null) { let path = join(projectSettings.path, projectSettings.name); // List the relevant templates. const templates = await listFiles(join(dirName, "modules", projectSettings.type), ".handlebars"); const settings = Object.assign({}, module, { project: projectSettings, }); for (const templateFile of templates) { await _writeTemplate(path, templateFile, projectSettings, "modules", settings, logger); } const files = await listFiles(join(dirName, "modules", projectSettings.type)); const filesToCopy = files.filter((item) => { const isTemplate = item.includes(".handlebars"); return !isTemplate; }); const promises = filesToCopy.map(async (file) => { const dest = await createFile(path + _relativePath(projectSettings, "modules", file, settings), ""); await copyFile(file, dest); if (logger) logger.info("created\t", dest); }); await promises; projectSettings.modules.push(module); await createFile(join(projectSettings.path, "nope.json"), JSON.stringify(projectSettings, undefined, 4)); } if (require.main === module) { const logger = getNopeLogger("tool"); async function main() { const settings = { author: { mail: "m.karkowski@zema.de", forename: "Martin", surename: "Karkowski", }, depencies: [], description: "Minimal Description for the Test", modules: [], path: "./temp/", services: [ { name: "createDatabase", }, ], name: "testPython", dirName: "test_python", version: "1.0", type: "python", currentNopeVersion: currentNopeVersion, }; await createProject(settings, "../temp", logger); await addServiceToProject(settings, { name: "deleteDatabase", }, logger); await addModuleToProject(settings, { methods: ["sayHello", "getTime"], name: "HelloWorld", events: [], properties: ["lastGreetingMessage"], }, logger); // Now create a Typescript folder: settings.type = "typescript"; settings.name = "testNodejs"; settings.name = "testNodejs"; settings.path = "./temp/"; await createProject(settings, "./temp", logger); await addServiceToProject(settings, { name: "deleteDatabase", }, logger); await addModuleToProject(settings, { methods: ["sayHello", "getTime"], name: "HelloWorld", events: [], properties: ["lastGreetingMessage"], }, logger); } main().catch(console.error); }