Initial commit

This commit is contained in:
jessy-david-dev
2026-01-18 23:33:05 +01:00
commit d926a2acd1
65 changed files with 6331 additions and 0 deletions
@@ -0,0 +1,192 @@
import { describe, it, expect } from 'vitest';
import { parsePrismaSchema, detectPrismaVersion, validatePrismaSchema } from '../index';
describe('Prisma Schema Parser', () => {
it('should parse a basic Prisma 5 schema', async () => {
const schema = `
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
`;
const result = await parsePrismaSchema(schema);
expect(result.version).toBe(5);
expect(result.models).toHaveLength(1);
expect(result.models[0].name).toBe('User');
expect(result.models[0].fields).toHaveLength(3);
});
it('should detect Prisma 6 features', () => {
const schema = `
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id
password String @omit
}
`;
expect(detectPrismaVersion(schema)).toBe(6);
});
it('should detect Prisma 7 features', () => {
const schema = `
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client"
}
model User {
id Int @id
}
`;
expect(detectPrismaVersion(schema)).toBe(7);
});
it('should handle relations correctly', async () => {
const schema = `
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id
posts Post[]
}
model Post {
id Int @id
author User @relation(fields: [authorId], references: [id])
authorId Int
}
`;
const result = await parsePrismaSchema(schema);
const userModel = result.models.find((m) => m.name === 'User');
const postModel = result.models.find((m) => m.name === 'Post');
expect(userModel?.fields.find((f) => f.name === 'posts')?.kind).toBe('object');
expect(postModel?.fields.find((f) => f.name === 'author')?.relationFromFields).toEqual([
'authorId',
]);
});
it('should parse enums correctly', async () => {
const schema = `
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
enum Role {
ADMIN
USER
GUEST
}
model User {
id Int @id
role Role @default(USER)
}
`;
const result = await parsePrismaSchema(schema);
expect(result.enums).toHaveLength(1);
expect(result.enums[0].name).toBe('Role');
expect(result.enums[0].values).toHaveLength(3);
expect(result.enums[0].values.map((v) => v.name)).toEqual(['ADMIN', 'USER', 'GUEST']);
});
it('should validate schema correctly', () => {
const validSchema = `
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id
}
`;
const invalidSchema = `
model User {
id Int @id
`;
expect(validatePrismaSchema(validSchema).valid).toBe(true);
expect(validatePrismaSchema(invalidSchema).valid).toBe(false);
});
it('should parse composite primary keys', async () => {
const schema = `
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model PostTag {
postId Int
tagId Int
@@id([postId, tagId])
}
`;
const result = await parsePrismaSchema(schema);
const model = result.models[0];
expect(model.primaryKey).toBeDefined();
expect(model.primaryKey?.fields).toEqual(['postId', 'tagId']);
});
it('should parse indexes and unique constraints', async () => {
const schema = `
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id
email String
firstName String
lastName String
@@unique([email])
@@index([firstName, lastName])
}
`;
const result = await parsePrismaSchema(schema);
const model = result.models[0];
expect(model.uniqueConstraints).toHaveLength(1);
expect(model.uniqueConstraints[0].fields).toEqual(['email']);
expect(model.indexes).toHaveLength(1);
expect(model.indexes[0].fields).toEqual(['firstName', 'lastName']);
});
});
@@ -0,0 +1,107 @@
import { describe, it, expect } from 'vitest';
import { parsePrismaSchema, toMermaid, toPlantUML, toDBML } from '../index';
const testSchema = `
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
enum Role {
ADMIN
USER
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
role Role @default(USER)
posts Post[]
createdAt DateTime @default(now())
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
`;
describe('Renderers', () => {
describe('Mermaid Renderer', () => {
it('should generate valid Mermaid ER diagram', async () => {
const schema = await parsePrismaSchema(testSchema);
const mermaid = toMermaid(schema);
expect(mermaid).toContain('erDiagram');
expect(mermaid).toContain('User {');
expect(mermaid).toContain('Post {');
expect(mermaid).toContain('int id "PK"');
expect(mermaid).toContain('string email "UK"');
});
it('should include relations', async () => {
const schema = await parsePrismaSchema(testSchema);
const mermaid = toMermaid(schema);
expect(mermaid).toMatch(/User.*Post/);
});
});
describe('PlantUML Renderer', () => {
it('should generate valid PlantUML diagram', async () => {
const schema = await parsePrismaSchema(testSchema);
const plantuml = toPlantUML(schema);
expect(plantuml).toContain('@startuml');
expect(plantuml).toContain('@enduml');
expect(plantuml).toContain('entity');
expect(plantuml).toContain('User');
expect(plantuml).toContain('Post');
});
it('should include enums', async () => {
const schema = await parsePrismaSchema(testSchema);
const plantuml = toPlantUML(schema);
expect(plantuml).toContain('enum Role');
expect(plantuml).toContain('ADMIN');
expect(plantuml).toContain('USER');
});
});
describe('DBML Renderer', () => {
it('should generate valid DBML', async () => {
const schema = await parsePrismaSchema(testSchema);
const dbml = toDBML(schema);
expect(dbml).toContain('Project prisma_schema');
expect(dbml).toContain('Table User');
expect(dbml).toContain('Table Post');
expect(dbml).toContain('Ref:');
});
it('should include field constraints', async () => {
const schema = await parsePrismaSchema(testSchema);
const dbml = toDBML(schema);
expect(dbml).toContain('pk');
expect(dbml).toContain('unique');
});
it('should include enums', async () => {
const schema = await parsePrismaSchema(testSchema);
const dbml = toDBML(schema);
expect(dbml).toContain('Enum Role');
});
});
});