crudora
v0.1.0-alpha.4
Published
TypeScript framework for automated CRUD API generation with Prisma and Express
Maintainers
Readme
Crudora
Automatic CRUD API generator for TypeScript with Prisma - Build REST APIs in minutes, not hours.
✨ Features
- 🚀 Zero Configuration: Generate CRUD APIs instantly
- 🎯 Type-Safe: Full TypeScript support with Prisma integration
- 🔧 Flexible: Support for both decorator and inheritance patterns
- 📊 Auto Pagination: Built-in pagination and filtering
- 🛡️ Validation: Automatic request validation with Zod
- 🔌 Extensible: Custom routes and middleware support
- 📖 Schema Generation: Auto-generate Prisma schemas from models
- 🗄️ Repository Pattern: Built-in repository for database operations
- 🔄 Lifecycle Hooks: beforeCreate, afterCreate, beforeUpdate, afterUpdate, beforeDelete, afterDelete, beforeFind, afterFind
- 🔒 Field Security: Hidden fields support with automatic filtering
- 🎛️ Dynamic Selection: Smart field selection based on fillable and hidden properties
- ⚡ Auto Setup: Intelligent postinstall script for quick project initialization
- 🔄 TypeScript First: Native TypeScript support with ESM modules
- 🖥️ CLI Tool: Command-line interface for project initialization and scaffolding
Installation
npm install crudora prisma @prisma/client
# or
yarn add crudora prisma @prisma/clientNote: After installation, Crudora automatically sets up your project with:
- Prisma schema template
- Environment configuration (.env)
- Basic server setup (server.ts)
- Useful npm scripts
CLI Usage
Crudora comes with a built-in CLI tool for quick project initialization and database management:
# Initialize a new Crudora project in the current directory
npx crudora init
# Start Prisma Studio for database management
npx crudora studio
# Generate Prisma Client
npx crudora generate
# Push Prisma schema to database
npx crudora push
# Run Prisma migrations
npx crudora migrateCLI Commands
init- Initialize a new Crudora project with necessary files (schema.prisma, .env, server.ts, tsconfig.json)studio- Start Prisma Studio for visual database managementgenerate- Generate Prisma Client based on your schemapush- Push Prisma schema to your database without migrationsmigrate- Run Prisma migrations for schema changes
Quick Start
Basic Usage
import { CrudoraServer, Model } from "crudora";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
class User extends Model {
static tableName = "users";
static primaryKey = "id";
static timestamps = true;
static fillable = ["name", "email", "password"];
static hidden = ["password"];
// Lifecycle hooks
static async beforeCreate(data: any): Promise<any> {
data.password = await hashPassword(data.password);
return data;
}
static async afterCreate(data: any, result: any): Promise<any> {
console.log(`User created: ${result.email}`);
return result;
}
}
class Post extends Model {
static tableName = "posts";
static fillable = ["title", "content", "authorId"];
static hidden = ["deletedAt"];
}
const server = new CrudoraServer({
port: 3000,
prisma: prisma,
});
server
.registerModel(User, Post)
.generateRoutes()
.listen(() => {
console.log("Server running on port 3000");
});Generated API Endpoints
For each registered model, Crudora automatically generates:
GET /api/{tableName}- List all records with pagination and filteringGET /api/{tableName}/:id- Get record by IDPOST /api/{tableName}- Create new recordPUT /api/{tableName}/:id- Update recordDELETE /api/{tableName}/:id- Delete record
Query Parameters
skip- Number of records to skip (pagination)take- Number of records to take (pagination)orderBy- Sort order (e.g.,createdAt:desc)where- Filter conditions
Advanced Usage
Lifecycle Hooks
Crudora supports comprehensive lifecycle hooks for all CRUD operations:
class User extends Model {
static tableName = "users";
static fillable = ["name", "email", "password"];
static hidden = ["password"];
// Create hooks
static async beforeCreate(data: any): Promise<any> {
data.password = await hashPassword(data.password);
data.createdAt = new Date();
return data;
}
static async afterCreate(data: any, result: any): Promise<any> {
await sendWelcomeEmail(result.email);
await logUserCreation(result.id);
return result;
}
// Update hooks
static async beforeUpdate(id: string, data: any): Promise<any> {
data.updatedAt = new Date();
return data;
}
static async afterUpdate(id: string, data: any, result: any): Promise<any> {
await logUserUpdate(id, data);
return result;
}
// Delete hooks
static async beforeDelete(id: string): Promise<void> {
await archiveUserData(id);
}
static async afterDelete(id: string, result: any): Promise<any> {
await logUserDeletion(id);
return result;
}
// Find hooks
static async beforeFind(options: any): Promise<any> {
// Add default filters
options.where = { ...options.where, active: true };
return options;
}
static async afterFind(result: any): Promise<any> {
// Transform result
if (Array.isArray(result)) {
return result.map((user) => ({ ...user, displayName: user.name }));
}
return { ...result, displayName: result.name };
}
}Field Security and Dynamic Selection
Crudora automatically handles field security and dynamic selection:
class User extends Model {
static tableName = "users";
static fillable = ["name", "email", "bio"]; // Only these fields can be mass-assigned
static hidden = ["password", "secret"]; // These fields are automatically excluded from responses
}
// API responses automatically exclude hidden fields
// Only fillable fields are included in select queries for better performanceUsing Repositories
const crudora = server.getCrudora();
const userRepo = crudora.getRepository(User);
// Create user (triggers beforeCreate and afterCreate hooks)
const user = await userRepo.create({
name: "John Doe",
email: "[email protected]",
password: "plaintext", // Will be hashed by beforeCreate hook
});
// Response excludes password due to hidden field
// Find users (triggers beforeFind and afterFind hooks)
const users = await userRepo.findAll({
skip: 0,
take: 10,
where: { active: true },
orderBy: { createdAt: "desc" },
});
// Update user (triggers beforeUpdate and afterUpdate hooks)
const updatedUser = await userRepo.update("user-id", {
name: "John Updated",
});
// Count users
const count = await userRepo.count({ active: true });Custom Routes
server
.get("/health", (req, res) => {
res.json({ status: "ok", timestamp: new Date() });
})
.post("/users/:id/activate", async (req, res) => {
const userRepo = server.getCrudora().getRepository(User);
const user = await userRepo.update(req.params.id, { active: true });
res.json(user);
});Schema Generation
// Generate Prisma schema from your models
const schema = server.getCrudora().generatePrismaSchema("postgresql");
console.log(schema);Validation
Crudora automatically generates Zod validation schemas:
const crudora = server.getCrudora();
// Get partial validation schema (for updates)
const partialSchema = crudora.getValidationSchema(User);
// Get strict validation schema (for creation)
const strictSchema = crudora.getStrictValidationSchema(User);Project Setup
After installing Crudora, run these commands to complete setup:
# Install additional dependencies
npm install @prisma/client prisma dotenv
# Generate Prisma client
npm run db:generate
# Push database schema
npm run db:push
# Start development server
npm run devAvailable Scripts
Crudora automatically adds these scripts to your package.json:
npm run dev- Start development server with ts-nodenpm run build- Build TypeScript to JavaScriptnpm run start- Start production server from built JavaScriptnpm run start:prod- Build and start production servernpm run db:generate- Generate Prisma clientnpm run db:push- Push schema to databasenpm run db:migrate- Run database migrationsnpm run db:studio- Open Prisma Studio
Documentation
Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
MIT © Crudora
⚠️ Alpha Version - Not recommended for production use
