UNPKG

4bnode

Version:

4bnode is a CLI-powered backend development platform with a built-in visual dashboard to generate, manage, and test Node.js/Express APIs faster.

120 lines (102 loc) 3.15 kB
#!/usr/bin/env node import path from "path"; import { select } from "@inquirer/prompts"; import { toPascalCase } from "./lib/names.js"; import { listRoutes, listModels, getModelSchema } from "./lib/project.js"; import { getRouteFilePath, addImportToRoute, insertCodeIntoRoute, } from "./lib/routeFile.js"; import { showHeader, showTaskDone, showError, showFileAction, } from "./lib/ui.js"; async function main() { showHeader("add-mongo-read", "Add data read route"); const routeFiles = listRoutes(); if (routeFiles.length === 0) { showError("No route files found in src/routes."); process.exit(1); } const modelFiles = listModels(); if (modelFiles.length === 0) { showError("No model files found in src/models."); process.exit(1); } const selectedRoute = await select({ message: "Select route file to modify:", choices: routeFiles.map((f) => ({ name: f, value: f })), }); const selectedModelFile = await select({ message: "Select model file to use:", choices: modelFiles.map((f) => ({ name: f, value: f })), }); const modelName = path.basename(selectedModelFile, ".js"); const pascalName = toPascalCase(modelName); const fields = getModelSchema(modelName, { includeId: true }); const readType = await select({ message: "How to fetch data?", choices: [ { name: "Fetch all data", value: "all" }, { name: "Fetch by specific field", value: "field" }, ], }); console.log(); const routeFilePath = getRouteFilePath(selectedRoute); addImportToRoute( routeFilePath, `import ${pascalName} from '../models/${modelName}.js';` ); let readCode; let routeDetail; if (readType === "all") { readCode = ` router.get('/', async (req, res) => { try { const documents = await ${pascalName}.find(); res.json({ data: documents }); } catch (err) { console.error(err); res.status(500).json({ message: 'Server error' }); } });`; routeDetail = "GET / (fetch all)"; } else { if (fields.length === 0) { showError("No fields found in the selected model."); process.exit(1); } const selectedField = await select({ message: "Select field to filter by:", choices: fields.map((f) => ({ name: f, value: f })), }); readCode = ` router.get('/', async (req, res) => { try { const documents = await ${pascalName}.find({ ${selectedField}: req.query.${selectedField} }); if (documents.length === 0) { return res.status(404).json({ message: 'No matching documents found' }); } res.json({ data: documents }); } catch (err) { console.error(err); res.status(500).json({ message: 'Server error' }); } });`; routeDetail = `GET /?${selectedField}=... (filter by ${selectedField})`; } insertCodeIntoRoute(routeFilePath, readCode); showFileAction("updated", `src/routes/${selectedRoute}`); showTaskDone("Read route added", [ `Route: ${routeDetail} in ${selectedRoute}`, `Model: ${modelName}`, ]); } main().catch((err) => { if (err.name === "ExitPromptError") process.exit(0); showError(err.message); process.exit(1); });