UNPKG

magen

Version:

Magen, generate react apps with module architecture

187 lines (164 loc) 5.1 kB
#!/usr/bin/env node import * as fs from "fs"; import { contextContent, formContent, formHookContent, hookContent, lowerFirstLetter, routerContent, schemaContent, snakeCase, viewContent, } from "./utils"; import { RouterSelectType } from "./types"; import { prompt } from "enquirer"; const main = async () => { console.log(` _____ ___ ___ ___ ___ | | .'| . | -_| | |_|_|_|__,|_ |___|_|_| |___| `); console.log("\nBy @mvrcoag\n"); const { moduleName }: { moduleName: string } = await prompt({ type: "input", name: "moduleName", message: "Module name in PascalCase (e.g. Auth) (required)", required: true, }); // get section name from user const { sectionName }: { sectionName: string } = await prompt({ type: "input", name: "sectionName", message: "Section name in PascalCase (e.g. Login)", }); const fullSectionName = moduleName + sectionName; const { withView }: { withView: string } = await prompt({ type: "confirm", name: "withView", message: "Section will have a view?", required: true, }); if (withView) { // get path from user const { path }: { path: string } = await prompt({ type: "input", name: "path", message: "Path to create the section (e.g. src/modules/auth/login)", initial: `src/modules/${snakeCase(moduleName)}/${snakeCase(sectionName)}`, required: true, }); // get if section will have a form const { withForm }: { withForm: string } = await prompt({ type: "confirm", name: "withForm", message: "Section will have a form?", required: true, }); // get if section will have a context const { withContext }: { withContext: string } = await prompt({ type: "confirm", name: "withContext", message: "Section will have a context?", required: true, }); // create section folder on components if not exists !fs.existsSync(path) && fs.mkdirSync(path, { recursive: true }); // define the standard files const files = [ { file: `/${fullSectionName}View.tsx`, content: viewContent(fullSectionName), }, { file: `/use${fullSectionName}.ts`, content: hookContent(fullSectionName), }, ]; // if section will have a form, add the form files if (withForm) { files.push({ file: `/${fullSectionName}Form.tsx`, content: formContent(fullSectionName), }); files.push({ file: `/use${fullSectionName}Form.ts`, content: formHookContent({ schemaPath: "./" + lowerFirstLetter(fullSectionName) + ".schema", sectionName: fullSectionName, }), }); files.push({ file: `/${lowerFirstLetter(fullSectionName)}.schema.ts`, content: schemaContent(fullSectionName), }); } // if section will have a context, add the context files if (withContext) { files.push({ file: `/${fullSectionName}Context.tsx`, content: contextContent(fullSectionName), }); } // create the files files.forEach((file) => { const filePath = `${path}${file.file}`; if (!fs.existsSync(filePath)) { fs.writeFileSync(filePath, file.content); } }); } const { withApiRouter }: { withApiRouter: string } = await prompt({ type: "confirm", name: "withApiRouter", message: "Section will have an api router?", required: true, }); if (withApiRouter) { const { routerType }: { routerType: RouterSelectType } = await prompt({ type: "select", name: "routerType", message: "What type of router you want to create?", choices: ["Axios", "React Query", "tRPC", "None of the above"], required: true, }); const { routerPath }: { routerPath: string } = await prompt({ type: "input", name: "routerPath", message: "Path to create the router (e.g. src/api/routers)", initial: `src/api/routers`, required: true, }); !fs.existsSync(routerPath) && fs.mkdirSync(routerPath + "/" + lowerFirstLetter(moduleName), { recursive: true }); // define the router file const routerFile = `${routerPath}/${lowerFirstLetter(moduleName)}/${lowerFirstLetter(moduleName)}.ts`; // create the router file if (!fs.existsSync(routerFile)) { fs.writeFileSync( routerFile, routerContent({ sectionName: moduleName, routerType: routerType, }) ); } } }; // execute the main function main() .then(() => { console.log(""); console.log("--------------------"); console.log("Section created successfully"); console.log("Remember to:"); console.log( "1. Add the router to the api root file (api/root.ts, server/root.ts, etc.)" ); console.log( "2. Add the view component to the pages router file (Pages, App, Navigation.tsx, etc.)" ); console.log("--------------------"); console.log(""); }) .catch((err) => console.error(err));