@bodheesh/create-bodhi-node-app
Version:
Create a production-ready Node.js REST API with zero configuration
234 lines (203 loc) • 5.7 kB
JavaScript
const fs = require('fs').promises;
const path = require('path');
async function generatePostgresAPI(schema, outputDir, type) {
if (type === 'rest') {
await generateRESTAPI(schema, outputDir);
} else if (type === 'graphql') {
await generateGraphQLAPI(schema, outputDir);
}
}
async function generateRESTAPI(schema, outputDir) {
// Generate model
const modelContent = generateModelContent(schema);
await fs.writeFile(
path.join(outputDir, `${schema.name}.model.js`),
modelContent
);
// Generate controller
const controllerContent = generateControllerContent(schema);
await fs.writeFile(
path.join(outputDir, `${schema.name}.controller.js`),
controllerContent
);
// Generate routes
const routesContent = generateRoutesContent(schema);
await fs.writeFile(
path.join(outputDir, `${schema.name}.routes.js`),
routesContent
);
// Generate migration
const migrationContent = generateMigrationContent(schema);
await fs.writeFile(
path.join(outputDir, `${Date.now()}_create_${schema.name.toLowerCase()}.js`),
migrationContent
);
}
function generateModelContent(schema) {
return `
const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class ${schema.name} extends Model {}
${schema.name}.init(
${generateSequelizeSchema(schema.fields)},
{
sequelize,
modelName: '${schema.name}',
timestamps: true,
}
);
module.exports = ${schema.name};
`;
}
function generateSequelizeSchema(fields) {
const schemaFields = Object.entries(fields).map(([fieldName, field]) => {
const type = mapToSequelizeType(field.type);
const options = {
type,
allowNull: !field.required,
unique: field.unique || false,
};
return `${fieldName}: ${JSON.stringify(options)}`;
});
return `{\n ${schemaFields.join(',\n ')}\n}`;
}
function mapToSequelizeType(type) {
const typeMap = {
'String': 'DataTypes.STRING',
'Number': 'DataTypes.FLOAT',
'Integer': 'DataTypes.INTEGER',
'Boolean': 'DataTypes.BOOLEAN',
'Date': 'DataTypes.DATE',
'Object': 'DataTypes.JSONB',
'Array': 'DataTypes.ARRAY(DataTypes.STRING)',
};
return typeMap[type] || 'DataTypes.STRING';
}
function generateControllerContent(schema) {
return `
const ${schema.name} = require('./${schema.name}.model');
// Create
exports.create = async (req, res) => {
try {
const new${schema.name} = await ${schema.name}.create(req.body);
res.status(201).json(new${schema.name});
} catch (error) {
res.status(400).json({ message: error.message });
}
};
// Read all
exports.findAll = async (req, res) => {
try {
const { page = 1, limit = 10 } = req.query;
const offset = (page - 1) * limit;
const items = await ${schema.name}.findAndCountAll({
limit: parseInt(limit),
offset: parseInt(offset),
order: [['createdAt', 'DESC']]
});
res.json({
items: items.rows,
totalPages: Math.ceil(items.count / limit),
currentPage: page
});
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Read one
exports.findOne = async (req, res) => {
try {
const item = await ${schema.name}.findByPk(req.params.id);
if (!item) {
return res.status(404).json({ message: 'Item not found' });
}
res.json(item);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Update
exports.update = async (req, res) => {
try {
const [updated] = await ${schema.name}.update(req.body, {
where: { id: req.params.id }
});
if (!updated) {
return res.status(404).json({ message: 'Item not found' });
}
const updatedItem = await ${schema.name}.findByPk(req.params.id);
res.json(updatedItem);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
// Delete
exports.delete = async (req, res) => {
try {
const deleted = await ${schema.name}.destroy({
where: { id: req.params.id }
});
if (!deleted) {
return res.status(404).json({ message: 'Item not found' });
}
res.json({ message: 'Item deleted successfully' });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
`;
}
function generateRoutesContent(schema) {
return `
const express = require('express');
const router = express.Router();
const ${schema.name}Controller = require('./${schema.name}.controller');
// Create
router.post('/', ${schema.name}Controller.create);
// Read all
router.get('/', ${schema.name}Controller.findAll);
// Read one
router.get('/:id', ${schema.name}Controller.findOne);
// Update
router.put('/:id', ${schema.name}Controller.update);
// Delete
router.delete('/:id', ${schema.name}Controller.delete);
module.exports = router;
`;
}
function generateMigrationContent(schema) {
return `
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('${schema.name}s', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
${Object.entries(schema.fields).map(([fieldName, field]) => `
${fieldName}: {
type: ${mapToSequelizeType(field.type)},
allowNull: ${!field.required},
unique: ${field.unique || false}
}`).join(',')},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('${schema.name}s');
}
};
`;
}
module.exports = {
generatePostgresAPI
};