@animaapp/entities-generator
v1.3.0
Published
DB Entity JSON generator from frontend project codebases
Readme
@animaapp/entities-generator
LangGraph agent for generating Entity JSON definitions from frontend codebases. Analyzes React/TypeScript code to produce database entity schemas with security patterns.
Installation
npm install @animaapp/entities-generatorQuick Start
import { EntitiesAgent } from '@animaapp/entities-generator';
const agent = new EntitiesAgent();
const result = await agent.run({
files: {
'src/components/UserProfile.tsx': '...',
'src/components/ProductCard.tsx': '...',
'src/pages/Dashboard.tsx': '...'
},
keys: {
openrouterApiKey: process.env.OPENROUTER_API_KEY
},
settings: {
maxEntities: 10
}
});
if (result.success) {
console.log('Generated entities:', result.entities);
} else {
console.error('Errors:', result.errors);
}LangGraph Studio
This package is designed to work with LangGraph Studio. The langgraph.json configuration enables visual debugging and monitoring of the agent workflow.
Running with LangGraph CLI
# Start the development server
cd packages/entities-generator
npm run start
# Or use the LangGraph CLI directly
npx @langchain/langgraph-cli devThis will start LangGraph Studio where you can:
- Visualize the agent's execution graph
- Inspect intermediate states
- Debug entity generation step-by-step
- Monitor token usage in real-time
LLM Models via OpenRouter
All models are accessed through OpenRouter, which provides unified access to multiple AI providers. Currently hardcoded to use x-ai/grok-4-fast, but supports the following models:
Supported Models
import type { OpenRouterModel } from '@animaapp/entities-generator';
// Available models through OpenRouter
type Models =
| 'openai/gpt-5'
| 'openai/gpt-5-mini'
| 'openai/gpt-5-nano'
| 'openai/gpt-4.1'
| 'anthropic/claude-sonnet-4-5'
| 'anthropic/claude-sonnet-4-0'
| 'anthropic/claude-3-7-sonnet-latest'
| 'google/gemini-2.5-flash'
| 'x-ai/grok-4-fast'; // Currently used by defaultGetting an OpenRouter API Key
- Sign up at openrouter.ai
- Generate an API key from your dashboard
- Set it in your environment:
OPENROUTER_API_KEY=your-key-here
API Reference
EntitiesAgent
LangGraph agent that orchestrates the entity generation workflow.
Constructor
const agent = new EntitiesAgent();agent.run(input)
Executes the entity generation workflow.
Parameters:
interface EntitiesAgentInput {
files: Record<string, string>; // file path -> content
keys: {
openrouterApiKey?: string; // Required if not in env
};
settings?: {
maxEntities?: number; // Default: 10, Max: 50
};
}Returns:
interface EntitiesAgentOutput {
entities: EntityJSON[];
success: boolean;
errors?: string[];
warnings?: string[];
}
interface EntityJSON {
name: string; // CamelCase entity name
description: string;
properties: Record<string, PropertyDefinition>;
security?: SecurityConstraints;
}
interface PropertyDefinition {
type: 'string' | 'number' | 'boolean' | 'date';
description: string;
optional?: boolean;
}
interface SecurityConstraints {
create?: 'admin' | 'creator' | 'authenticated' | 'public';
read?: 'admin' | 'creator' | 'authenticated' | 'public';
update?: 'admin' | 'creator' | 'authenticated' | 'public';
delete?: 'admin' | 'creator' | 'authenticated' | 'public';
}agent.getGraph()
Returns the compiled LangGraph workflow for inspection or visualization.
const graph = agent.getGraph();
// Use with LangGraph Studio or for custom executionSecurity Patterns
The agent automatically detects and applies one of five security patterns to each entity:
1. Admin Control
Use case: System configs, settings, admin-only data
Permissions: All operations require admin access
{
create: 'admin',
read: 'admin',
update: 'admin',
delete: 'admin'
}2. Public Info
Use case: Blog posts, product catalogs, public content
Permissions: Public can read, only admins can modify
{
create: 'admin',
read: 'public',
update: 'admin',
delete: 'admin'
}3. Personal Data
Use case: User profiles, preferences, private settings
Permissions: Only the creator can access their own data
{
create: 'creator',
read: 'creator',
update: 'creator',
delete: 'creator'
}4. Collect Input
Use case: Contact forms, feedback submissions, surveys
Permissions: Anyone can submit, only admins can view
{
create: 'public',
read: 'admin',
update: 'admin',
delete: 'admin'
}5. Share Publicly
Use case: User posts, reviews, public contributions
Permissions: Authenticated users create, everyone reads, creators edit own
{
create: 'authenticated',
read: 'public',
update: 'creator',
delete: 'creator'
}How It Works
The agent follows a multi-step workflow:
- Preprocessing - Analyzes codebase structure, extracts data patterns from TypeScript interfaces, React props, API calls, and form submissions
- Context Building - Identifies security patterns (auth, roles, permissions) and categorizes files (components, pages, utilities)
- LLM Generation - Sends preprocessed context to LLM via OpenRouter
- Postprocessing - Validates output, applies security patterns, fixes naming conventions
- Output - Returns validated EntityJSON array with metadata
Configuration
Environment Variables
# Required
OPENROUTER_API_KEY=your-openrouter-api-key
# Optional - Debug logging
ENTITIES_GENERATOR_DEBUG=debug # Show all logs
ENTITIES_GENERATOR_DEBUG=info # Show info, warnings, errors
ENTITIES_GENERATOR_DEBUG=warn # Show warnings, errors only (default)
ENTITIES_GENERATOR_DEBUG=error # Show errors onlyExamples
E-commerce Project
import { EntitiesAgent } from '@animaapp/entities-generator';
const agent = new EntitiesAgent();
const result = await agent.run({
files: {
'src/components/ProductCard.tsx': `
interface Product {
id: string;
name: string;
price: number;
category: string;
inStock: boolean;
}
export function ProductCard({ product }: { product: Product }) {
return <div>{product.name} - ${product.price}</div>;
}
`,
'src/components/UserProfile.tsx': `
interface User {
id: string;
email: string;
name: string;
orders: Order[];
createdAt: Date;
}
`
},
keys: {
openrouterApiKey: process.env.OPENROUTER_API_KEY
},
settings: {
maxEntities: 5
}
});
if (result.success) {
console.log('Generated entities:', result.entities);
// Expected output:
// [
// {
// name: 'Product',
// description: 'E-commerce product entity',
// properties: {
// id: { type: 'string', description: 'Unique identifier' },
// name: { type: 'string', description: 'Product name' },
// price: { type: 'number', description: 'Product price' },
// category: { type: 'string', description: 'Product category' },
// inStock: { type: 'boolean', description: 'Availability status' }
// },
// security: {
// create: 'admin',
// read: 'public',
// update: 'admin',
// delete: 'admin'
// }
// },
// {
// name: 'User',
// description: 'User account entity',
// properties: { ... },
// security: {
// create: 'creator',
// read: 'creator',
// update: 'creator',
// delete: 'creator'
// }
// }
// ]
}Blog Platform
import { EntitiesAgent } from '@animaapp/entities-generator';
const agent = new EntitiesAgent();
const result = await agent.run({
files: {
'src/pages/BlogPost.tsx': `
interface BlogPost {
id: string;
title: string;
content: string;
author: Author;
publishedAt: Date;
tags: string[];
isPublished: boolean;
}
export function BlogPostPage({ post }: { post: BlogPost }) {
return (
<article>
<h1>{post.title}</h1>
<p>By {post.author.name}</p>
<div>{post.content}</div>
</article>
);
}
`,
'src/components/ContactForm.tsx': `
interface ContactSubmission {
name: string;
email: string;
message: string;
submittedAt: Date;
}
export function ContactForm() {
const [form, setForm] = useState<ContactSubmission>();
// Form submission logic
}
`
},
keys: {
openrouterApiKey: process.env.OPENROUTER_API_KEY
}
});Custom Max Entities
const agent = new EntitiesAgent();
// Generate up to 20 entities from a large codebase
const result = await agent.run({
files: yourLargeCodebase,
keys: {
openrouterApiKey: process.env.OPENROUTER_API_KEY
},
settings: {
maxEntities: 20 // Default is 10, max is 50
}
});Error Handling
const agent = new EntitiesAgent();
try {
const result = await agent.run({
files: yourFiles,
keys: {
openrouterApiKey: process.env.OPENROUTER_API_KEY
}
});
if (!result.success) {
console.error('Generation failed:', result.errors);
// Handle errors gracefully
}
if (result.warnings) {
console.warn('Warnings encountered:', result.warnings);
// Log warnings but continue
}
// Process successful results
result.entities.forEach(entity => {
console.log(`Entity: ${entity.name}`);
console.log(`Properties: ${Object.keys(entity.properties).length}`);
console.log(`Security pattern applied: ${JSON.stringify(entity.security)}`);
});
} catch (error) {
console.error('Agent execution failed:', error);
}Development
Building
npm run buildTesting
npm test
npm run test:watch
npm run test:coverageType Checking
npm run lintDevelopment Mode
# Watch mode for development
npm run dev
# Run with LangGraph Studio
npm run startArchitecture
This package is built with:
- LangGraph - Agent orchestration and workflow management
- LangChain - LLM integration and message handling
- Zod - Runtime type validation and schemas
- OpenRouter - Unified access to multiple LLM providers
- TypeScript - Full type safety throughout
Project Structure
src/
├── agent/ # LangGraph agent implementation
│ ├── index.ts # EntitiesAgent class & workflow
│ ├── state.ts # State management
│ └── nodes/ # Workflow nodes
├── modules/ # Core business logic
│ ├── entities-generator/
│ │ ├── generator.ts # Main generation logic
│ │ ├── preprocessor.ts # File analysis
│ │ ├── postprocessor.ts # Validation & cleanup
│ │ └── prompts.ts # LLM prompts
│ └── shared-types/ # Type definitions
├── providers/ # LLM provider clients
│ └── openrouter.ts
└── utils/ # Utilities (logger, parsing, validation)Publishing
To publish a new version:
# Build and publish to npm
yarn deploy
# Or manually
yarn build
npm publish --access public --no-workspacesLicense
MIT
Contributing
This package is part of the Anima Design to Code monorepo. See the main repository for contribution guidelines.
