What is @mrleebo/prisma-ast?
@mrleebo/prisma-ast is an npm package designed to parse and manipulate Prisma schema files. It provides an Abstract Syntax Tree (AST) representation of Prisma schema files, allowing developers to programmatically read, modify, and generate Prisma schema definitions.
What are @mrleebo/prisma-ast's main functionalities?
Parsing Prisma Schema
This feature allows you to parse a Prisma schema string into an AST. The code sample demonstrates how to parse a simple Prisma schema and output the resulting AST.
const { parseSchema } = require('@mrleebo/prisma-ast');
const schema = `
model User {
id Int @id @default(autoincrement())
name String
}
`;
const ast = parseSchema(schema);
console.log(JSON.stringify(ast, null, 2));
Modifying Prisma Schema
This feature allows you to modify an existing Prisma schema by manipulating its AST. The code sample shows how to add a new field to the User model and then print the updated schema.
const { parseSchema, printSchema } = require('@mrleebo/prisma-ast');
let schema = `
model User {
id Int @id @default(autoincrement())
name String
}
`;
let ast = parseSchema(schema);
ast.declarations[0].fields.push({
name: 'email',
type: 'String',
attributes: []
});
schema = printSchema(ast);
console.log(schema);
Generating Prisma Schema
This feature allows you to generate a Prisma schema from an AST. The code sample demonstrates how to create an AST for a simple User model and then generate the corresponding Prisma schema string.
const { printSchema } = require('@mrleebo/prisma-ast');
const ast = {
type: 'schema',
declarations: [
{
type: 'model',
name: 'User',
fields: [
{ name: 'id', type: 'Int', attributes: [{ type: 'attribute', name: 'id' }, { type: 'attribute', name: 'default', args: [{ type: 'function', name: 'autoincrement' }] }] },
{ name: 'name', type: 'String', attributes: [] }
]
}
]
};
const schema = printSchema(ast);
console.log(schema);
Other packages similar to @mrleebo/prisma-ast
prisma
The official Prisma ORM package. While it does not provide direct AST manipulation capabilities, it offers a comprehensive set of tools for working with databases using Prisma schema files. It focuses more on database interactions and migrations rather than schema parsing and manipulation.
prisma-schema-dsl
A package that provides a Domain Specific Language (DSL) for generating Prisma schema files. It allows for programmatic creation of Prisma schema definitions but does not offer the same level of AST manipulation as @mrleebo/prisma-ast.
prisma-dbml-generator
A package that converts Prisma schema files to DBML (Database Markup Language) format. It focuses on schema conversion rather than direct AST manipulation, making it useful for different use cases compared to @mrleebo/prisma-ast.
@mrleebo/prisma-ast
This library uses an abstract syntax tree to parse schema.prisma files into an object in JavaScript.
It is similar to @prisma/sdk except that it preserves comments and model attributes. It also doesn't attempt to validate the correctness of the schema at all; the focus is instead on the ability to parse the schema into an object, manipulate it using JavaScript, and re-print the schema back to a file without losing information that isn't captured by other parsers.
It is probable that a future version of @prisma/sdk will render this library obsolete.
Install
npm install @mrleebo/prisma-ast
Examples
Parse a schema.prisma file into a JS object
import { getSchema } from '@mrleebo/prisma-ast'
const source = `
model User {
id Int @id @default(autoincrement())
name String @unique
}
`
const schema = getSchema(source)
Print a schema back out as a string
import { printSchema } from '@mrleebo/prisma-ast'
const source = printSchema(schema)
Add a datasource
schema.list.push({
type: "datasource",
name: "db",
assignments: [
{type: "assignment", key: "provider", value: '"postgresql"'},
{
type: "assignment",
key: "url",
value: {type: "function", name: "env", params: ['"DATABASE_URL"']},
},
],
})
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
Add a generator
schema.list.push({
type: "generator",
name: "nexusPrisma",
assignments: [{type: "assignment", key: "provider", value: '"nexus-prisma"'}],
})
generator nexusPrisma {
provider = "nexus-prisma"
}
Add a model
const model = schema.list.push({
type: "model",
name: "Project",
properties: [
{ type: "field", name: "name", fieldType: "String" }
]
})
model Project {
name String
}
Add a field to a model
const field = model.properties.push({
type: "field",
name: "projectCode",
fieldType: "String",
optional: false,
attributes: [{type: "attribute", kind: "field", name: "unique"}],
})
model Project {
name String
projectCode String @unique
}
Add an index to a model
model.properties.push({
type: "attribute",
kind: "model",
name: "index",
args: [{ type: "attributeArgument", value: { type: "array", args: ["name"] } }]
})
model Project {
name String
projectCode String @unique
@@index([name])
}
Add an enum
schema.list.push({
type: "enum",
name: "Role",
enumerators: [
{type: "enumerator", name: "USER"},
{type: "enumerator", name: "ADMIN"},
],
})
enum Role {
USER
ADMIN
}
Comments and Line breaks are also parsed and can be added to the schema
model.properties.push({
type: "break"
}, {
type: "comment",
text: "// I wish I could add a color to your rainbow"
})
model Project {
name String
projectCode String @unique
@@index([name])
// I wish I could add a color to your rainbow
}