@nextlevels/crud
v0.0.2
Published
**CRUD Factory Package** - Generiere komplette CRUD-Operationen in wenigen Zeilen! 🚀
Readme
@nextlevels/crud
CRUD Factory Package - Generiere komplette CRUD-Operationen in wenigen Zeilen! 🚀
Features
✅ Auto-generierte tRPC Router mit allen CRUD-Operationen ✅ Auto-generierte DataTable Columns mit Actions ✅ Auto-generierte List Pages mit Pagination & Sorting ✅ Type-Safe - Vollständige TypeScript-Unterstützung ✅ DRY - Kein duplizierter Code mehr! ✅ Flexible - Einfach anzupassen und zu erweitern
Quick Start
1. Entity Config erstellen
import { Role } from "@prisma/client";
import mySchema from "@/schema/my-schema";
const entityConfig = {
name: "myEntity",
schema: mySchema,
permissions: [Role.ADMIN, Role.SUPERADMIN],
labels: {
singular: "Mein Entity",
plural: "Meine Entities",
description: "Verwalte alle Entities",
},
};2. Router erstellen (1 Zeile!)
import { createEntityRouter } from "@nextlevels/crud/router";
import {
createTRPCRouter,
protectedProcedure,
publicProcedure,
} from "@/server/api/trpc";
export const myEntityRouter = createTRPCRouter(
createEntityRouter(entityConfig, { publicProcedure, protectedProcedure })
);Das war's! Du hast jetzt:
fetchAll- Alle Entities abrufen (public)fetchPaginated- Paginierte Liste (protected)fetchById- Einzelnes Entity (protected)create- Neues Entity erstellen (protected)update- Entity bearbeiten (protected)delete- Entity löschen (protected)
3. Columns erstellen
import { createEntityColumns } from "@nextlevels/crud/columns";
export function getColumns({ isLoading, onSuccess } = {}) {
const deleteMutation = api.myEntity.delete;
return createEntityColumns({
entityName: "myEntity",
singularLabel: "Mein Entity",
basePath: "/admin/my-entities",
deleteMutation,
isLoading,
onSuccess,
columns: [
{ key: "name", label: "Name", sortable: true },
{
key: "status",
label: "Status",
render: (value) => (value ? "Aktiv" : "Inaktiv"),
},
],
});
}4. List Page erstellen
import { createListPage } from "@nextlevels/crud/pages";
const MyEntityListPage = createListPage({
pluralLabel: "Meine Entities",
singularLabel: "Mein Entity",
description: "Verwalte alle Entities hier.",
basePath: "/admin/my-entities",
useQuery: api.myEntity.fetchPaginated.useQuery,
columns: getColumns(),
});
export default MyEntityListPage;API Reference
createEntityRouter(config, builder)
Erstellt einen vollständigen tRPC Router mit CRUD-Operationen.
Parameter:
config: EntityConfig- Entity-Konfigurationbuilder: { publicProcedure, protectedProcedure }- tRPC Builder
Returns: Router mit folgenden Endpoints:
fetchAll(input?)- Alle Entities (limit, where)fetchPaginated(input)- Paginierte ListefetchById(input)- Einzelnes Entitycreate(input)- Neues Entityupdate(input)- Entity bearbeitendelete(input)- Entity löschen
createEntityColumns(options)
Erstellt DataTable Columns mit Actions.
Parameter:
entityName: string- Entity-NamesingularLabel: string- Singular-LabelbasePath: string- Basis-Pfad (z.B./admin/videos)columns: ColumnConfig[]- Column-DefinitionendeleteMutation- tRPC Delete MutationisLoading?: boolean- Loading-StateonSuccess?: () => void- Success-CallbackdisplayField?: string- Feld für Delete-Bestätigung (default: "name")
ColumnConfig:
{
key: string; // Feld-Name
label: string; // Column-Header
sortable?: boolean; // Sortierbar? (default: true)
render?: (value) => any; // Custom Renderer
accessor?: (item) => any; // Custom Accessor
}createListPage(options)
Erstellt eine List-Page Component.
Parameter:
pluralLabel: string- Plural-LabelsingularLabel: string- Singular-Labeldescription?: string- BeschreibungbasePath: string- Basis-PfaduseQuery- tRPC Query Hookcolumns: ColumnDef[]- Table ColumnsinitialPageSize?: number- Initiale Page-Size (default: 10)
Vergleich: Vorher vs. Nachher
Router
Vorher: 237 Zeilen Code pro Entity Nachher: ~15 Zeilen Code
// Vorher: video.ts (237 Zeilen)
export const videoRouter = createTRPCRouter({
fetchAll: publicProcedure.input(...).query(async ({ ctx, input }) => {
// 25 Zeilen
}),
fetchPaginated: protectedProcedure.input(...).query(async ({ input, ctx }) => {
// 50 Zeilen
}),
// ... +160 Zeilen mehr
});
// Nachher: video-new.ts (15 Zeilen)
const videoConfig = { ... };
export const videoRouter = createTRPCRouter(
createEntityRouter(videoConfig, { publicProcedure, protectedProcedure })
);Columns
Vorher: 148 Zeilen Code pro Entity Nachher: ~20 Zeilen Code
List Page
Vorher: 73 Zeilen Code pro Entity Nachher: ~15 Zeilen Code
Advanced Usage
Custom Permissions Check
const config = {
name: "myEntity",
schema: mySchema,
permissions: [Role.ADMIN, Role.SUPERADMIN],
// ...
};Custom Default Sort
const config = {
name: "myEntity",
schema: mySchema,
defaultSort: {
field: "createdAt",
order: "desc",
},
// ...
};Custom Prisma Model Name
const config = {
name: "tire",
prismaModel: "Tire", // Falls anders als Entity-Name
// ...
};Custom Column Renderer
columns: [
{
key: "status",
label: "Status",
render: (value) => (
<Badge variant={value ? "success" : "destructive"}>
{value ? "Aktiv" : "Inaktiv"}
</Badge>
),
},
];Migration Guide
So migrierst du bestehende Entities:
Router migrieren:
- Alte Router-Datei kopieren
- Entity Config erstellen
createEntityRouterverwenden- Alte Datei löschen
Columns migrieren:
- Bestehende Columns analysieren
ColumnConfigArray erstellencreateEntityColumnsverwenden
Pages migrieren:
createListPageverwenden- Columns importieren
- Alte Page-Datei löschen
Next Steps
- [ ] Erstelle Generator-CLI für neue Entities
- [ ] Füge Form-Page Factory hinzu
- [ ] Erweitere um Bulk-Actions
- [ ] Füge Export-Funktionen hinzu
License
Private Package - Part of CMS Template Monorepo
