diff --git a/.npmignore b/.npmignore index c797844..c96d669 100644 --- a/.npmignore +++ b/.npmignore @@ -18,6 +18,7 @@ template/ .github/ .vscode/ .releaserc.json +LICENSE # for 2.4.5 release bin/format/ \ No newline at end of file diff --git a/README.md b/README.md index 76f6753..46deaeb 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ Universal Box Logo +

Universal-Box



@@ -12,6 +13,7 @@ NPM Version NPM Downloads + License Snyk @@ -20,7 +22,7 @@ - 📚 Read the docs + 📚 Read the docs 💬 Join our Discord @@ -33,7 +35,7 @@ -# Universal-Box + **Universal-Box** is a powerful tool designed to streamline your development process with a collection of starter templates and projects. It provides a fast and structured way to kickstart your development journey, allowing you to set up new projects with ease and efficiency. @@ -77,7 +79,7 @@ universal-box get https://github.com/username/repo/tree/ ## Documentation -For more details and advanced usage, visit the [Universal-Box Documentation](https://universal-box.co/). +For more details and advanced usage, visit the [Universal-Box Documentation](https://universal-box.dev/). ## License diff --git a/bin/generate/codePopulate.js b/bin/generate/codePopulate.js new file mode 100644 index 0000000..4747a30 --- /dev/null +++ b/bin/generate/codePopulate.js @@ -0,0 +1,50 @@ +module.exports = { + modelsContent: function (item) { + return ` +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const ${item}Schema = new Schema({}); // Write your schema here + +const ${item} = mongoose.model('${item}', ${item}Schema); + +module.exports = ${item}; + `; + }, + + viewsContent: function (item) { + return ` + + + + + + + ${item} + + + + + +`; + }, + + controllerContent: function (functions_array) { + return `module.exports = {\n${functions_array + .map((item) => `${item}: function() {}, // Add function logic here`) + .join("\n")}\n};`; + }, + + routesContent: function (config) { + let base_content = `const router = require('express').Router();\n\n`; + + Object.entries(config).forEach(([type, routes]) => { + routes.forEach((route) => { + base_content += `router.${type}('${route}', (req, res) => {}); // Add your route logic here\n`; + }); + }); + + base_content += `\nmodule.exports = router;`; + return base_content; + }, +}; diff --git a/bin/generate/fileGenerators.js b/bin/generate/fileGenerators.js new file mode 100644 index 0000000..23ee633 --- /dev/null +++ b/bin/generate/fileGenerators.js @@ -0,0 +1,97 @@ +const fs = require("fs"); +const util = require("util"); + +const fsWritePromisified = util.promisify(fs.writeFile); + +const errorHandler = (err) => console.log("\x1b[31m", err); +const successHandler = (fileName) => () => + console.log("\x1b[32m", `Generated file ${fileName}`); + +module.exports = { + makeModels: function (models) { + return models.map((item) => + fsWritePromisified( + `./models/${item}.js`, + ` +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const ${item}Schema = new Schema({}); // Write your schema here + +const ${item} = mongoose.model('${item}', ${item}Schema); + +module.exports = ${item}; + ` + ) + .then(successHandler(`${item}.js`)) + .catch(errorHandler) + ); + }, + + makeViews: function (views) { + return views.map((item) => + fsWritePromisified( + `./views/${item}.html`, + ` + + + + + + + ${item} + + + + + + ` + ) + .then(successHandler(`${item}.html`)) + .catch(errorHandler) + ); + }, + + makeControllers: function (controllers) { + return Object.entries(controllers).map(([fileName, methods]) => + fsWritePromisified( + `./controllers/${fileName}.js`, + ` +module.exports = { +${methods + .map((method) => `${method}: function() {}, // Add function logic here`) + .join("\n")} +}; + ` + ) + .then(successHandler(`${fileName}.js`)) + .catch(errorHandler) + ); + }, + + makeRoutes: function (routes) { + return Object.entries(routes).map(([fileName, methods]) => + fsWritePromisified( + `./routes/${fileName}.js`, + ` +const router = require('express').Router(); + +${Object.entries(methods) + .map(([methodType, paths]) => + paths + .map( + (path) => + `router.${methodType}('${path}', (req, res) => {}); // Add your route logic here` + ) + .join("\n") + ) + .join("\n")} + +module.exports = router; + ` + ) + .then(successHandler(`${fileName}.js`)) + .catch(errorHandler) + ); + }, +}; diff --git a/bin/generate/generate-from-config.js b/bin/generate/generate-from-config.js new file mode 100644 index 0000000..a4e1d83 --- /dev/null +++ b/bin/generate/generate-from-config.js @@ -0,0 +1,152 @@ +const fs = require("fs"); +const yaml = require("js-yaml"); +const utils = require("./utils"); +const chalk = require("chalk"); + +function generateFromConfig(configFileName) { + const configPath = `${process.cwd()}/${configFileName}`; + + // Check if the config file exists + if (!fs.existsSync(configPath)) { + console.error(`Configuration file "${configFileName}" not found.`); + process.exit(1); + } + + let config; + try { + const fileContents = fs.readFileSync(configPath, "utf8"); + config = yaml.load(fileContents); + } catch (e) { + console.error(`Error reading or parsing "${configFileName}": ${e.message}`); + process.exit(1); + } + + createProjectStructure(config); + + console.log( + chalk.blue("\n------ Happy Coding with Universal-Box 🚀 ------\n") + ); +} + +function createProjectStructure(config) { + const { models, controllers, views, routes } = config; + console.log(chalk.blue("Creating project structure...")); + if (models) { + utils + .makeFolders(["models"]) + .then(() => { + return Promise.all( + models.map((model) => { + return fs.promises.writeFile( + `models/${model}.js`, + ` +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const ${model}Schema = new Schema({}); // Write your schema here + +const ${model} = mongoose.model('${model}', ${model}Schema); + +module.exports = ${model}; + ` + ); + }) + ); + }) + .then(() => + console.log(chalk.yellow("\x1b[32m", "✅ Models generated")) + ) + .catch((err) => console.error(err)); + } + + if (views) { + utils + .makeFolders(["views"]) + .then(() => { + return Promise.all( + views.map((view) => { + return fs.promises.writeFile( + `views/${view}.html`, + ` + + + + + + + ${view} + + + + + + ` + ); + }) + ); + }) + .then(() => + console.log(chalk.yellow("\x1b[32m", "✅ Views generated")) + ) + .catch((err) => console.error(err)); + } + + if (controllers) { + utils + .makeFolders(["controllers"]) + .then(() => { + return Promise.all( + Object.entries(controllers).map(([fileName, methods]) => { + const content = ` +module.exports = { +${methods + .map((method) => `${method}: function() {}, // Add function logic here`) + .join("\n")} +}; + `; + return fs.promises.writeFile(`controllers/${fileName}.js`, content); + }) + ); + }) + .then(() => + console.log( + chalk.yellow("\x1b[32m", "✅ Controllers generated") + ) + ) + .catch((err) => console.error(err)); + } + + if (routes) { + utils + .makeFolders(["routes"]) + .then(() => { + return Promise.all( + Object.entries(routes).map(([fileName, methods]) => { + const content = ` +const router = require('express').Router(); + +${Object.entries(methods) + .map(([methodType, paths]) => + paths + .map( + (path) => + `router.${methodType}('${path}', (req, res) => {}); // Add your route logic here` + ) + .join("\n") + ) + .join("\n")} + +module.exports = router; + `; + return fs.promises.writeFile(`routes/${fileName}.js`, content); + }) + ); + }) + .then(() => + console.log(chalk.yellow("\x1b[32m", "✅ Routes generated")) + ) + .catch((err) => console.error(err)); + } +} + +module.exports = { generateFromConfig }; diff --git a/bin/generate/utils.js b/bin/generate/utils.js new file mode 100644 index 0000000..d984235 --- /dev/null +++ b/bin/generate/utils.js @@ -0,0 +1,28 @@ +const fs = require("fs"); +var exec = require("child_process").exec; +const chalk = require("chalk"); + +module.exports = { + makeFolders: function (array_list) { + const supportedFolders = ["models", "views", "controllers", "routes"]; + + return new Promise((resolve, reject) => { + array_list.forEach((folder) => { + if (supportedFolders.includes(folder)) { + if (!fs.existsSync(`./${folder}`)) { + fs.mkdirSync(`./${folder}`); + console.log(chalk.yellow(`Directory Created -> ./${folder}`)); + } + } else { + console.log("\x1b[31m", `NO SUPPORT FOR DIRECTORY ./${folder}`); + reject({ + success: false, + message: "No support for entered directory!", + }); + } + }); + + resolve({ success: true, message: "Created folders successfully" }); + }); + }, +}; diff --git a/bin/universal-box.js b/bin/universal-box.js index 8300076..e1966d4 100644 --- a/bin/universal-box.js +++ b/bin/universal-box.js @@ -6,6 +6,7 @@ const path = require("path"); const chalk = require("chalk"); const cloneRepository1 = require("./get/clone-dir.js"); +const { generateFromConfig } = require("./generate/generate-from-config.js"); // Scaffold directory is maintained as a mirror version of the templates directory. Maintained by maintainers. const scaffoldDir = path.resolve(__dirname, "../scaffold"); @@ -37,7 +38,15 @@ switch (command) { } cloneRepository1(repoUrl, "universal-box"); break; - + case "generate": + const configFileName = args[0]; + if (!configFileName) { + console.error("Please provide a configuration file name (e.g., idea.yml)."); + process.exit(1); + } + generateFromConfig(configFileName); + break; + default: console.log( chalk.red( @@ -91,11 +100,19 @@ function initProject() { console.log(chalk.yellow("\nNext steps:")); console.log(chalk.yellow(`1. Change to your new project directory:`)); console.log(chalk.cyan(` cd ${projectName}`)); - console.log(chalk.yellow("2. Install dependencies (if required):")); - console.log(chalk.cyan(" npm install") + " or " + chalk.cyan("yarn")); console.log( chalk.yellow( - "3. Start your development server (check package.json for specific commands)" + "2. Refer to the README.md file for installation and running commands." + ) + ); + console.log( + chalk.yellow( + " This file contains all necessary instructions specific to your project type." + ) + ); + console.log( + chalk.yellow( + "3. Start your development server (check package.json or README.md for specific commands)" ) ); console.log( @@ -108,7 +125,7 @@ function initProject() { ); console.log( chalk.gray( - "Need help? Visit our documentation: https://universal-box.co/" + "Need help? Visit our documentation: https://universal-box.dev/" ) ); } catch (error) { @@ -135,19 +152,21 @@ ${chalk.bold("Commands:")} ${chalk.cyan("deploy")} ${chalk.dim( "Trigger build and deployment pipeline" )} + ${chalk.cyan("generate")} ${chalk.dim("Generate project from a configuration file")} ${chalk.cyan("--help")} ${chalk.dim("Display this help message")} ${chalk.bold("Examples:")} ${chalk.green("universal-box --help")} ${chalk.green("universal-box init")} ${chalk.green("universal-box deploy")} + ${chalk.green("universal-box generate ")} ${chalk.green("universal-box get https://github.com/username/repo")} ${chalk.green( "universal-box get https://github.com/username/repo/tree/" )} ${chalk.gray("Need help? Visit our documentation:")} ${chalk.underline.blue( - "https://universal-box.co/" + "https://universal-box.dev/" )} `); } diff --git a/package-lock.json b/package-lock.json index 05f5206..6d016fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "fs-extra": "^11.2.0", "http-proxy": "^1.18.1", "inquirer": "^8.2.6", + "js-yaml": "^4.1.0", "progress": "^2.0.3" }, "bin": { @@ -1530,8 +1531,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/argv-formatter": { "version": "1.0.0", @@ -3400,7 +3400,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, diff --git a/package.json b/package.json index 8d3f458..ce4dad5 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "fs-extra": "^11.2.0", "http-proxy": "^1.18.1", "inquirer": "^8.2.6", + "js-yaml": "^4.1.0", "progress": "^2.0.3" } }