@manic.code/schema
Version:
A flexible schema definition and validation system for TypeScript with multi-database support
317 lines (245 loc) • 7.95 kB
Markdown
# 🧠 .code/schema
[](https://www.npmjs.com/package/@manic.codes/schema)
[](https://github.com/maniccodes/schema)
[](https://codecov.io/gh/maniccodes/schema)
[](https://github.com/maniccodes/schema/blob/main/LICENSE)
A powerful, flexible schema definition and validation system for TypeScript with seamless multi-database support.
<p align="center">
<img src="banner.svg" alt="SAGE Schema" width="100%">
</p>
## 🔥 Overview
MANIC Schema is a revolutionary TypeScript-first ORM/ODM that lets you define your data model once and seamlessly use it across multiple databases — MongoDB, Neo4j, PostgreSQL, and more. Built from the ground up with modern best practices:
## ✨ Key Features
- **Define Once, Use Anywhere**: Define schema in TypeScript, deploy to any supported database
- **Multi-Database Architecture**: Mix and match databases for optimal performance
- **Cross-Database Relationships**: Maintain relationships between entities in different databases
- **GraphQL Ready**: Auto-generate GraphQL schema from your entities
- **Database-Specific Optimizations**: Leverage native database features when needed
- **Type-Safe**: Full TypeScript support with proper types throughout
## 🏗️ Core Architecture
- **Clean Design**: Explicit dependencies, no global state, no magic
- **Adapter Pattern**: Extensible adapter system for database integrations
- **Decorator-Based**: Intuitive TypeScript decorators for schema definition
- **100% Test Coverage**: Comprehensive test suite with property-based testing
## 🗄️ Supported Databases
| Database | Status | Features |
| ---------- | -------------- | ----------------------------------------------- |
| MongoDB | ✅ Stable | Collections, indexes, embedding |
| Neo4j | ✅ Stable | Node labels, relationship types, Cypher queries |
| PostgreSQL | ✅ Stable | Tables, columns, indexes, joins |
| SQLite | 🚧 In Progress | Basic functionality |
| Redis | 🚧 In Progress | Basic functionality |
| DynamoDB | 🗓️ Planned | - |
| Firestore | 🗓️ Planned | - |
## 🧩 Key Components
### Decorators
Define your entities with TypeScript decorators:
```typescript
class Post {
id: string;
title: string;
content: string;
createdAt: Date;
author: User;
tags: Tag[] = [];
}
```
### Database-Specific Decorators
Optimize for specific databases when needed:
```typescript
// MongoDB specific
class Post {
/* ... */
}
// Neo4j specific
class Post {
/* ... */
}
// PostgreSQL specific
class Post {
/* ... */
}
```
### SchemaBuilder & Registry
Explicit dependencies, no global state:
```typescript
// Create registry and builder
const registry = new MetadataRegistry();
const builder = new SchemaBuilder(registry);
// Register your entities
builder.registerEntities([User, Post, Comment, Tag]);
```
### Multi-Database Adapters
Use different databases for different entity types:
```typescript
// Create adapters for different databases
const mongoAdapter = new MongoDBAdapter(
registry,
"mongodb://localhost:27017/blog"
);
const neo4jAdapter = new Neo4jAdapter(registry, "bolt://localhost:7687");
const pgAdapter = new PostgreSQLAdapter(
registry,
"postgres://localhost:5432/blog"
);
// Create repositories with appropriate adapters
const userRepo = new Repository<User>(User, mongoAdapter);
const postRepo = new Repository<Post>(Post, neo4jAdapter);
const tagRepo = new Repository<Tag>(Tag, pgAdapter);
```
### Repositories
Consistent interface across all databases:
```typescript
// Find by ID
const user = await userRepo.findById("user123");
// Query by criteria
const posts = await postRepo.find({ completed: true });
// Create and save
const tag = new Tag();
tag.name = "TypeScript";
await tagRepo.save(tag);
// Delete
await userRepo.delete("user123");
```
## 📊 GraphQL Integration
Automatic GraphQL schema generation:
```typescript
// Generate GraphQL schema from entities
import { generateGraphQLSchema } from "@manic.codes/schema/graphql";
const typeDefs = generateGraphQLSchema(registry);
const resolvers = generateResolvers(registry, {
User: userRepo,
Post: postRepo,
Tag: tagRepo,
});
// Create Apollo Server
const server = new ApolloServer({
typeDefs,
resolvers,
});
```
## 🚀 Complete Multi-Database Example
```typescript
import {
Entity,
Id,
Property,
ManyToOne,
ManyToMany,
MetadataRegistry,
SchemaBuilder,
MongoDBAdapter,
Neo4jAdapter,
PostgreSQLAdapter,
Repository,
} from "@manic.code/schema";
// Define entities
class User {
id: string;
name: string;
email: string;
posts: Post[] = [];
}
class Post {
id: string;
title: string;
content: string;
createdAt: Date = new Date();
author: User;
tags: Tag[] = [];
}
class Tag {
id: string;
name: string;
posts: Post[] = [];
}
// Set up the registry and builder
const registry = new MetadataRegistry();
const builder = new SchemaBuilder(registry);
builder.registerEntities([User, Post, Tag]);
// Create database adapters
const mongoAdapter = new MongoDBAdapter(
registry,
"mongodb://localhost:27017/blog"
);
const neo4jAdapter = new Neo4jAdapter(registry, "bolt://localhost:7687");
const pgAdapter = new PostgreSQLAdapter(
registry,
"postgres://localhost:5432/blog"
);
// Create repositories with different adapters
const userRepo = new Repository<User>(User, mongoAdapter);
const postRepo = new Repository<Post>(Post, neo4jAdapter);
const tagRepo = new Repository<Tag>(Tag, pgAdapter);
// Create entities with relationships across databases
async function createBlogPost() {
// Create user in MongoDB
const user = new User();
user.id = "user1";
user.name = "John Doe";
user.email = "john@example.com";
await userRepo.save(user);
// Create tags in PostgreSQL
const tag1 = new Tag();
tag1.id = "tag1";
tag1.name = "TypeScript";
await tagRepo.save(tag1);
const tag2 = new Tag();
tag2.id = "tag2";
tag2.name = "ORM";
await tagRepo.save(tag2);
// Create post in Neo4j with relationships to MongoDB and PostgreSQL
const post = new Post();
post.id = "post1";
post.title = "Multi-Database ORM with TypeScript";
post.content = "This is amazing...";
post.author = user;
post.tags.push(tag1, tag2);
await postRepo.save(post);
return post;
}
```
## 🔧 Installation
```bash
npm install .code/schema
```
## 📄 License
MIT © [Zach Winter](https://github.com/zachwinter)