https://github.com/jamiepine/prismix
The Prisma schema mixer 🍹
https://github.com/jamiepine/prismix
prisma
Last synced: over 1 year ago
JSON representation
The Prisma schema mixer 🍹
- Host: GitHub
- URL: https://github.com/jamiepine/prismix
- Owner: jamiepine
- License: gpl-3.0
- Archived: true
- Created: 2021-07-23T00:30:27.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2022-11-05T21:48:19.000Z (over 3 years ago)
- Last Synced: 2025-03-16T13:03:31.587Z (over 1 year ago)
- Topics: prisma
- Language: TypeScript
- Homepage:
- Size: 186 KB
- Stars: 304
- Watchers: 6
- Forks: 41
- Open Issues: 23
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# `Prismix`
### *The Prisma schema mixer 🍹*
_Made for Prisma `^2.0`_
[](https://www.npmjs.com/package/prismix)
[](https://www.npmjs.com/package/prismix)
Prisma restricts your schema to a single file, Prismix allows you to write as many schema files as you'd like, wherever you like—all while supporting cross-file model relations 🤯
> Learn more about Prisma: [prisma.io](https://prisma.io)
Unlike `prisma-merge`, Prismix allows model relations to exist between files by combining models and enums, allowing you to extend and override Models as you please. This is ideal when working in a monorepo where parts of your schema need to exist in separate modules.
## Installation
1. Install Prismix
```
yarn add prismix --dev
```
or NPM
```
npm install prismix --dev
```
2. Create a `prismix.config.json` file in the root of your project. This allows you to define how you would like Prismix to merge your schemas.
```json
{
"mixers": [
{
"input": [
"base.prisma",
"./modules/auth/auth.prisma",
"./modules/posts/posts.prisma",
],
"output": "prisma/schema.prisma"
}
]
}
```
The order of your input files effects how overrides are considered, the later inputs take priority over the earlier inputs.
The default `output` value is `prisma/schema.prisma` (it can be omitted from the config) and Prisma encourages you to keep is as such, especially if you want to use `prisma format`.
3. Add the `npx prismix` command as a prefix to your `package.json` scripts.
```json
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"prismix": "npx prismix && prisma format",
"dev": "yarn prismix && ts-node server.ts",
}
}
```
Or just run `npx prismix` from within the repo that contains the Prismix config file.
Using `prisma format` is optional, but I like clean code.
Note: If you are using a monorepo you won't be able to run this command from the root, if you add a script `"prismix": "npx prismix"` you could run `yarn workspace my-app prismix`.
## Cross-file relations
In order to relate to a model defined in another file you **must create an alias model**. This is simply a model with only the `@id` field.
This is to ensure Prisma can parse the schema file, as Prismix uses the Prisma SDK to parse each file individually before merging models at field level.
```prisma
model Post {
id String @id @default(autoincrement())
}
```
In the above example `Post` would be a model defined in another schema, any fields added in this schema file will be merged with any `Post` model(s) in other schema files. The `@id` field is the only required field in an extended model, however you may add fields specific to a relation. (this is shown in greater detail below)
## Example
Let's go over how Prismix merges schemas. We'll keep it simple with two schemas that need to relate to each other.
## `base.prisma`
```prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = "postgresql://..."
}
model Account {
id Int @id @default(autoincrement())
username String
email String
status String
@@map("accounts")
}
```
We've established our `generator` and `datasource`, as well as our first model, `Account`. It is required that these two definitions be present in at least one of your schemas.
## `posts.prisma`
Now we'll create the Posts schema in a different file. In order for posts to relate to accounts we can define an **empty model** to represent the account.
```prisma
model Post {
id Int @id @default(autoincrement())
title String
content String
account_id Int
account Account @relation(fields: [account_id], references: [id])
@@map("posts")
}
model Account {
id Int @id
posts Post[]
}
```
When Prismix merges these two schemas the relations will be connected.
## `schema.prisma`
This is the generated file, do not edit this file!
```prisma
// *** GENERATED BY PRISMIX :: DO NOT EDIT ***
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = "postgresql://..."
}
model Account {
id Int @id @default(autoincrement())
username String
email String
status String
posts Post[]
}
model Posts {
id Int @id @default(autoincrement())
title String
content String
account_id Int
account Account @relation(fields: [account_id], references: [id])
@@map("posts")
}
```
As you can see the property `posts` was added on to the original Account schema and the `account` relation on the Posts schema links to the original Account schema.
## How it works
Using the Prisma SDK we parse the input schemas into a DMMF objects, then process the schema merge into a single DMMF object as per the config file, finally it is converted back into Prisma schema format using a custom deserializer, adapted from `@IBM/prisma-schema-transformer` and written to the output location.
## To-do
- [x] Make it work
- [x] Add glob support for wildcard schema discovery
- [ ] Make `prismix.config.json` optional
- [ ] Add command flags
Created by [@jamiepine](https://twitter.com/jamiepine)