prisma-case-format
prisma introspect
names its model 1:1 with your database's conventions. That's great, but if your db is purely snake_case
, or worse if your tables lack any common convention, it can make the autogenerated client code less pleasant to consume. prisma-case-format
will format your prisma schema's model and field names to enforce a more conventional experience.
Use Cases
As a one-time migration assistant
Use --dry-run
to figure out which case conventions are correct for your project. Once things look correct, drop the flag to save changes to the --file
(or your local schema.prisma
by default).
As a small CI/CD component
prisma-case-format
aims to be idempotent, so you can use it to confirm that case conventions in your schema.prisma
have not accidentally drifted. prisma-case-format
can be applied on-commit or on-push, either in a git commit-hook package or as a CI/CD step. Use --dry-run
to diff changes with the original file, or backup the original and compare to the edit.
With NextAuth.js
If your team is using NextAuth.js
, you may have encountered an issue where prisma-case-format
steam rolls the strict data contract expected by the NextAuth.js
integration. Specify the --uses-next-auth
flag in order to protect your NextAuth.js
tables from your specified conventions.
Usage
❯ prisma-case-format --help
Usage: prisma-case-format [options]
Give your schema.prisma sane naming conventions
Options:
-f, --file <file> cwd-relative path to `schema.prisma` file (default: "schema.prisma")
-c, --config-file <cfgFile> cwd-relative path to `.prisma-case-format` config file (default: ".prisma-case-format")
-D, --dry-run print changes to console, rather than back to file (default: false)
--table-case <tableCase> case convention for table names (SEE BOTTOM) (default: "pascal")
--field-case <fieldCase> case convention for field names (default: "camel")
--enum-case <enumCase> case convention for enum names. In case of not declared, uses value of “--table-case”. (default: "pascal")
--map-table-case <mapTableCase> case convention for @@map() annotations (SEE BOTTOM)
--map-field-case <mapFieldCase> case convention for @map() annotations
--map-enum-case <mapEnumCase> case convention for @map() annotations of enums. In case of not declared, uses value of “--map-table-case”.
-p, --pluralize optionally pluralize array type fields (default: false)
--uses-next-auth guarantee next-auth models (Account, User, Session, etc) uphold their data-contracts
-V, --version hint: you have v2.1.0
-h, --help display help for command
-------------------------
Supported case conventions: ["pascal", "camel", "snake"].
Additionally, append ',plural' after any case-convention selection to mark case convention as pluralized.
For instance:
--map-table-case=snake,plural
will append `@@map("users")` to `model User`.
Append ',singular' after any case-convention selection to mark case convention as singularized.
For instance,
--map-table-case=snake,singular
will append `@@map("user")` to `model Users`
Example
// schema.prisma before
...
model house_rating {
id Int @id @default(autoincrement())
house_id String
house house @relation(fields: [house_id], references: [id])
...
}
...
model house {
id String @id @default(uuid())
house_rating house_rating[]
...
}
...
❯ prisma-case-format
✨ Done.
// schema.prisma after
...
model HouseRating {
id Int @id @default(autoincrement())
houseId String @map("house_id")
house House @relation(fields: [houseId], references: [id])
...
@@map("house_rating")
}
...
model House {
id String @id @default(uuid())
houseRating HouseRating[]
...
@@map("house")
}
...
Drift Protection
prisma-case-format
lets you manage three case conventions: table
, field
, and enum
.
table
model Example { // <- controlled by `--table-case`
id String @id
value1 String @map("value_1")
@@map("example") // <- controlled by `--map-table-case`
}
Table conventions are controlled by the --table-case
& --map-table-case
flags. --table-case
specifies the case convention for the models in the generated prisma client library. --map-table-case
will manage the database name case convention. It manages models & views.
field
model Example {
id String @id
// r-- controlled by `--field-case`
// | r-- controlled by `--map-field-case`
// v v
value1 String @map("value_1")
}
Field conventions are controlled by the --field-case
& --map-field-case
flags. --field-case
specifies the case convention for the fields in models within the generated prisma client library. --map-field-case
will manage the case convention for the field in the database. It does not apply to enum constants.
enum
enum Example { // <- controlled by --enum-case
Value1
Value2
@@map("example") // <- controlled by --map-enum-case
}
Enum conventions are controlled by the --enum-case
& --map-enum-case
flags. --enum-case
specifies the case convention for the enums in the generated prisma client library. --map-enum-case
will manage the case convention for the enum within the database. It does not apply to enum constants, only enum names.
Config file
prisma-case-format
supports a config file, which primarily exists as a means to override case conventions per model or per field. This can be especially useful if you are coming from an existing database that doesn't have perfect naming convention consistency. For example, some of your model fields are snake_case
, others are camelCase
.
By default, this file is located at .prisma-case-format
. The file is expected to be yaml
internally. The following section details the config file format.
Config file format
Property: default?: string
:
An alternative to specifying the commandline arguments. The format is a simple ;
-delimited list, white space allowed.
Example:
default: 'table=pascal; mapTable=snake; field=pascal; mapField=snake; enum=pascal; mapEnum=pascal'
uses_next_auth: false
Property: override?: Dictionary<string, { default?: string, field?: Field }>
Type: Field=Dictionary<string, string>
Controls overrides on a per-table & per-field basis. Each key in override
& subkey in field
is allowed to be a regex, in which case it will attempt to match based on the specified pattern. This can be useful if you have several fields with pre or suffixes.
Example
default: 'table=pascal; mapTable=snake; field=pascal; mapField=snake; enum=pascal; mapEnum=pascal'
override:
MyTable:
default: 'table=snake;mapTable=camel;field=snake;mapField=snake;enum=snake;mapEnum=snake'
field:
fooFieldOnMyTable: 'field=pascal;mapField=pascal'
'my_prefix.*': 'mapField=pascal;'
Results in:
model my_table {
id String @id
FooFieldOnMyTable Integer
my_prefix_prop_a Json
@@map("myTable")
}
'Disable'
The .prisma-case-format
file supports specifying that a particular model or field has its case convention management "disabled". This is achieved by setting the key under override
or sukey under field
to 'disable'
.
Example:
default: ...
override:
MyTable: 'disable'
...
Results in:
model mYTaBlE {
nowican String @id
cAnFAlL_iNtO_UtTeR__DiSrePaiR String @map("lol")
iN_T0T4L_p34C3 Integer @map("great")
@map("myspace")
}
The other tables surrounding mYTaBlE
will remain managed.
Property: uses_next_auth?: boolean
If =true
, then the models added by NextAuth.js
will not have their case conventions rewritten by user's selected case conventions, preserving the expected contract. If you are not using NextAuth.js
, it is suggested to keep this unspecified or false
.
This property is equivalent to the following configuration:
uses_next_auth: false
default: ...
overrides:
Account:
default: 'table=pascal; mapTable=pascal;'
field:
id: 'field=camel; mapField=camel'
userId: 'field=camel; mapField=camel'
type: 'field=camel; mapField=camel'
provider: 'field=camel; mapField=camel'
providerAccountId: 'field=camel; mapField=camel'
refresh_token: 'field=snake; mapField=snake'
access_token: 'field=snake; mapField=snake'
expires_at: 'field=snake; mapField=snake'
token_type: 'field=snake; mapField=snake'
scope: 'field=snake; mapField=snake'
id_token: 'field=snake; mapField=snake'
session_state: 'field=snake; mapField=snake'
user: 'field=snake; mapField=snake'
Session:
default: 'table=pascal; mapTable=pascal; field=camel; mapField=camel'
User:
default: 'table=pascal; mapTable=pascal; field=camel; mapField=camel'
VerificationToken:
default: 'table=pascal; mapTable=pascal; field=camel; mapField=camel'
Note that if uses_next_auth: true
and your overrides
section contains conflicting specifications for any of the above model names (Account
, Session
, User
, or VerificationToken
), uses_next_auth
will blow away your configuration rules for those models and use the above rules.
Pluralization
Supply the -p
or --pluralize
argument to get array pluralizations.
❯ prisma-case-format -p
✨ Done.
// schema.prisma after pluralization
...
model House {
...
houseRatings HouseRating[]
ownerContacts String[] @map("owner_contact")
...
}
...