The aim of this proposal is to provide a sneak-peek for the new feature that will be added to Prisma Util v2.0. In this issue, I'll be outlining the process of how you can use the new Enhanced Introspection features to manipulate your schema.
Introduction
This feature will be released under the enhancedIntrospection flag and will require manual activation. Because this feature uses Project Toolchain's Generation API, it will create the typings necessary for configuring the fields of this object. All Enhanced Introspection steps will be ran before the schema is generated, to allow you to modify the models before they are written to the final file.
Configuration
To configure the Enhanced Introspection feature, you're going to have to add an introspection property to your configuration object like this:
export default {
// Other configuration options
introspection: {
modelPatterns: {
// We'll come back to this option later on.
}
}
}
We've created a separate introspection object to facilitate a fieldPatterns option coming in the future.
Model Patterns
Model Patterns are used for defining rules that models should follow. To offer more granular control for your schema, we've implemented the following class that will be passed to your functions:
abstract class Model {
/**
* The name of this model. If this parameter hasn't been modified before, it will be the table name from the database.
*/
public abstract get name();
/**
* Set the name for this model.
*/
public abstract set name(name: string);
/**
* Add an attribute to this model.
* @param attribute The attribute to add. You can use the `schema-creator` module for a list of attributes.
*/
public abstract addAttribute(attribute: string);
}
The rules for Model Patterns are split into 3 categories:
Static Changes
Static changes edit models based on their name and are placed under the $static key. These can be configured in 2 ways:
Using a String
Using a String is the easiest way to remap a table. To do it, add the following object to your introspection block:
In this example, `ModelName` will map to `table_name` and will add the `@@unique([name, email])` attribute to the model.
- ### Regex Changes
Regex changes use regexes to match model names. These regexes are ran with the `gims` flags and are placed under the `$regex` key. To configure a regex replacer, add a function like this:
```ts
export default {
// Other configuration options
introspection: {
modelPatterns: {
$regex: {
"model_name(\\d)": async (model: Model, match: string, ...groups: string[]) => {
model.name = `ModelName${groups[1]}`;
return model;
}
}
}
}
}
One regex replacer can be called for multiple tables and will pass the correct model as a parameter. In this example, all tables that match the regex will have the underscore removed and will be changed to PascalCase.
Catch-all Changes
Catch-all replacers will be ran for all models. To configure a catch-all replacer, add a function like this:
In this example, all tables will have the underscore removed.
Handling Conflicts
Because the Enhanced Introspection step is ran before the Conflict Manager has a chance to run, all models that will trigger a naming conflict will be flagged and the normal rename/skip dialog will be shown.
Prioritizing Changes
Replacers will be ran from the first key to the last key. A table can trigger multiple replacers, if the latter ones match the new name set by the previous replacers. You can use this to your advantage: by reordering the $static, $regex and $all keys you can create a powerful workflow that fits your use-case. One example of such workflow would be leaving the $all key as the last property of the object to enforce default naming conventions on all models.
Scope
The aim of this proposal is to provide a sneak-peek for the new feature that will be added to Prisma Util v2.0. In this issue, I'll be outlining the process of how you can use the new Enhanced Introspection features to manipulate your schema.
Introduction
This feature will be released under the
enhancedIntrospection
flag and will require manual activation. Because this feature uses Project Toolchain's Generation API, it will create the typings necessary for configuring the fields of this object. All Enhanced Introspection steps will be ran before the schema is generated, to allow you to modify the models before they are written to the final file.Configuration
To configure the Enhanced Introspection feature, you're going to have to add an
introspection
property to your configuration object like this:We've created a separate
introspection
object to facilitate afieldPatterns
option coming in the future.Model Patterns
Model Patterns are used for defining rules that models should follow. To offer more granular control for your schema, we've implemented the following class that will be passed to your functions:
The rules for Model Patterns are split into 3 categories:
Static Changes
Static changes edit models based on their name and are placed under the
$static
key. These can be configured in 2 ways:Using a String
Using a String is the easiest way to remap a table. To do it, add the following object to your
introspection
block:In this example,
ModelName
will map totable_name
.Using a Function
Using a function allows more granular control for this table. To do it, add the following object to your
introspection
block:export default { // Other configuration options introspection: { modelPatterns: { $static: { "table_name": async (model: Model) => { model.name = "ModelName"; model.addAttribute(Constraints.Model.UNIQUE(["name", "email"])); return model; } } } } }
One regex replacer can be called for multiple tables and will pass the correct model as a parameter. In this example, all tables that match the regex will have the underscore removed and will be changed to PascalCase.
Catch-all Changes
Catch-all replacers will be ran for all models. To configure a catch-all replacer, add a function like this:
In this example, all tables will have the underscore removed.
Handling Conflicts
Because the Enhanced Introspection step is ran before the Conflict Manager has a chance to run, all models that will trigger a naming conflict will be flagged and the normal rename/skip dialog will be shown.
Prioritizing Changes
Replacers will be ran from the first key to the last key. A table can trigger multiple replacers, if the latter ones match the new name set by the previous replacers. You can use this to your advantage: by reordering the
$static
,$regex
and$all
keys you can create a powerful workflow that fits your use-case. One example of such workflow would be leaving the$all
key as the last property of the object to enforce default naming conventions on all models.