はじめに
prisma-lint
に設定できる Rule は RULES.md に記載。
RULES.md の内容を日本語で説明したく訳を作成しました。
2024/11時点の情報です。最新の情報は下記URLを確認してください。
https://github.com/loop-payments/prisma-lint/blob/main/RULES.md
ルール
ban-unbounded-string-type
文字列フィールドが長さを制限するために、データベースネイティブの型で定義されていることを確認する(例: @db.VarChar(x))。
意図せず無制限の長さをサポートするAPIを構築しないようにすることを目的としている。
このルールは https://brandur.org/text に影響を受け作成された。
設定
z.object({
allowNativeTextType: z.boolean().optional(),
}).strict();
例
// OK
model User {
id String @db.VarChar(36)
}
// NG
model User {
id String
}
// NG
model User {
id String @db.Text
}
// OK
model User {
id String @db.Text
}
enum-name-pascal-case
Enum 型の名前が PascalCase であることを確認する。
設定
z.object({
allowList: z.array(z.union([z.string(), z.instanceof(RegExp)])).optional(),
trimPrefix: z
.union([
z.string(),
z.instanceof(RegExp),
z.array(z.union([z.string(), z.instanceof(RegExp)])),
])
.optional(),
}).strict();
例
// OK
enum ExampleOptions {
value1
}
// NG
enum exampleOptions {
value1
}
// NG
enum example_options {
value1
}
enum-value-snake-case
列挙型の値が snake_case であることを確認する。
このルールは、特定の列挙型の値を無視するためにprisma-lint-ignore-enumコメントが使用可能。
/// prisma-lint-ignore-enum enum-value-snake-case SCREAMING_SNAKE
上記記述によって SCREAMING_SNAKE
が許可される。それ以外の値はsnake_caseである必要がある。
設定
z.object({
allowList: z.array(z.union([z.string(), z.instanceof(RegExp)])).optional(),
trimPrefix: z
.union([
z.string(),
z.instanceof(RegExp),
z.array(z.union([z.string(), z.instanceof(RegExp)])),
])
.optional(),
}).strict();
例
// OK
enum Example {
value
}
// OK
enum Example {
value_1
}
// NG
enum Example {
Value
}
// NG
enum Example {
VALUE
}
// NG
enum Example {
camelCase
}
field-name-camel-case
フィールド名がキャメルケースで記述されていることを確認する。
設定
z.object({
allowList: z.array(z.union([z.string(), z.instanceof(RegExp)])).optional(),
trimPrefix: z
.union([
z.string(),
z.instanceof(RegExp),
z.array(z.union([z.string(), z.instanceof(RegExp)])),
])
.optional(),
}).strict();
例
// OK
model User {
rowId String @id
}
// NG
model User {
RowId String @id
}
// NG
model User {
row_id String @id
}
field-name-mapping-snake-case
フィールドのマッピング名がスネークケースであることを確認する。
設定
z.object({
compoundWords: z.array(z.string()).optional(),
requireUnderscorePrefixForIds: z.boolean().optional(),
})
.strict()
.optional();
例
// OK
model UserRole {
userId String @map(name: "user_id")
}
model UserRole {
// 単語のみで構成されるフィールド名はマッピング不要
id String
// 関連フィールドはマッピング不要
grantedByUser User
}
// NG
model UserRole {
userId String
}
model UserRole {
userId String @map(name: "user_i_d")
}
// OK
model PersistedQuery {
graphQLId String @map(name: "graphql_id")
}
// NG
model PersistedQuery {
graphQLId String @map(name: "graph_q_l_id")
}
// OK
model PersistedQuery {
id String @id @map(name: "_id")
otherField String @map(name: "other_field")
}
// NG
model PersistedQuery {
id String @id @map(name: "id")
otherField String @map(name: "other_field")
}
// OK
enum RoleType {
ADMIN
MEMBER
}
model UserRole {
roleType RoleType @map(name: "role_type")
}
// NG
model UserRole {
roleType RoleType
}
// OK
type UserInfo {
institution String
}
model User {
userInfo UserInfo @map(name: "user_info")
}
// NG
model User {
userInfo UserInfo
}
// OK
type Post {
/// prisma-lint-ignore-model field-name-mapping-snake-case tenantId
tenantId String
userId String @map(name: "user_id")
}
// NG
type Post {
/// prisma-lint-ignore-model field-name-mapping-snake-case tenantId
tenantId String
userId String
}
field-order
モデル内のフィールドが指定された順序で並んでいることを確認する。
order リストに含まれないフィールドは無視。
フィールドを必須にする場合は、require-field ルールを使用する。
order リストの最初のフィールドはモデルの先頭に、最後のフィールドはモデルの末尾に配置されることが要求される。特別なフィールド名 ... は、その位置に任意の数のフィールドが配置可能であることを示す。
設定
z.object({
order: z.array(z.string()),
}).strict();
例
// OK
model User {
tenantId String
id String @id
email String
}
model User {
tenantId String
id String @id
createdAt DateTime
email String
}
// NG
model User {
id String @id
email String
tenantId String
}
// OK
model User {
tenantId String
id String
email String
createdAt DateTime
updatedAt DateTime
}
model User {
tenantId String
id String
email String
createdAt DateTime
}
// NG
model User {
id String @id
createdAt DateTime
email String
}
forbid-field
特定の名前のフィールドを禁止する。
設定
z.object({
forbid: z.array(z.union([z.string(), z.instanceof(RegExp)])),
}).strict();
例
// OK
type Product {
uuid String
}
// NG
type Product {
id String
}
// OK
type Product {
id String
priceAmountD6 Int
}
// NG
type Product {
id Int
priceD6 Int
}
forbid-required-ignored-field
デフォルト値のない必須の無視されたフィールドを禁止する。
このルールは、フィールドがクライアントに生成されない一方で、データベースが対応する非NULL列を要求することを防ぐ。
さらなる保護を検討する場合は、Prisma Safety の使用を推奨。
例
// OK
type Product {
uuid String
toBeRemoved String? @ignore
}
// OK
type Product {
uuid String
toBeRemoved Boolean @default(false) @ignore
}
// NG
type Product {
uuid String
toBeRemoved String @ignore
}
model-name-grammatical-number
モデル名が単数形または複数形のスタイルに準拠しているかをチェックする。
文法的数 (Grammatical number) に基づき、モデル名を制約する。
設定
z.object({
style: z.enum(['singular', 'plural']),
allowlist: z.array(z.union([z.string(), z.instanceof(RegExp)])).optional(),
}).strict();
例
// OK
model User {
id String @id
}
// NG
model Users {
id String @id
}
// OK
model Users {
id String @id
}
// NG
model User {
id String @id
}
// OK
model UserData {
id String @id
}
model User {
id String @id
}
// NG ("Data" はデフォルトで複数形と見なされる)
model TenantData {
id String @id
}
model Users {
id String @id
}
// OK
model UserData {
id String @id
}
model TenantData {
id String @id
}
// NG
model DataRecords {
id String @id
}
model Users {
id String @id
}
model-name-mapping-snake-case
モデルのマッピング名がスネークケース (snake_case) に準拠しているかをチェックする。
設定
z.object({
compoundWords: z.array(z.string()).optional(),
irregularPlurals: z.record(z.string()).optional(),
pluralize: z.boolean().optional(),
trimPrefix: z.string().optional(),
})
.strict()
.optional();
例
// OK
model UserRole {
id String @id
@@map(name: "user_role")
}
// NG
model UserRole {
id String @id
}
model UserRole {
id String @id
@@map(name: "user_roles")
}
// OK
model DbUserRole {
id String @id
@@map(name: "user_role")
}
// NG
model DbUserRole {
id String @id
@@map(name: "db_user_role")
}
// OK
model GraphQLPersistedQuery {
id String @id
@@map(name: "graphql_persisted_query")
}
// NG
model GraphQLPersistedQuery {
id String @id
@@map(name: "graph_q_l_persisted_query")
}
// OK
model UserRole {
id String @id
@@map(name: "user_roles")
}
// NG
model UserRole {
id String @id
}
model UserRole {
id String @id
@@map(name: "user_role")
}
model-name-pascal-case
モデル名がパスカルケース (PascalCase) に準拠しているかをチェックする。
設定
z.object({
allowList: z.array(z.union([z.string(), z.instanceof(RegExp)])).optional(),
trimPrefix: z
.union([
z.string(),
z.instanceof(RegExp),
z.array(z.union([z.string(), z.instanceof(RegExp)])),
])
.optional(),
}).strict();
例
// OK
model DbUser {
id String @id
}
// NG
model dbUser {
id String @id
}
// NG
model db_user {
id String @id
}
model-name-prefix
モデル名が指定されたプレフィックスを含んでいるかをチェックする。
設定
z.object({
prefix: z.string(),
}).strict();
例
// OK
model DbUser {
id String @id
}
// NG
model User {
id String @id
}
require-default-empty-arrays
配列フィールドにデフォルト値として空配列を設定することを要求する。
動機
空配列をデフォルト値として明示的に設定することで、予期しないエラーを防ぐ。詳細な動機は Prisma lint issue #275 を参照。
例
// OK
model Post {
tags String[] @default([])
}
// NG
model Post {
tags String[]
}
require-field-index
特定のフィールドにインデックスが設定されていることを確認する。
設定
z.object({
forAllRelations: z.boolean().optional(),
forNames: z
.union([z.string(), z.array(z.union([z.string(), z.instanceof(RegExp)]))])
.optional(),
}).strict();
例
// OK
model User {
createdAt DateTime @unique
}
model User {
createdAt DateTime
@@index([createdAt])
}
model User {
createdAt DateTime
id String
@@index([createdAt, id])
}
// NG
model User {
createdAt string
}
model User {
createdAt DateTime
id String
@@index([id, createdAt])
}
// OK
model User {
tenantId String
@@index([tenantId])
}
// NG
model User {
tenantId String
}
// OK
type Bar {
fooId String
foo Foo @relation(fields: [fooId], references: [id])
@@index([fooId])
}
// NG
type Bar {
fooId String
foo Foo @relation(fields: [fooId], references: [id])
}
require-field-type
特定のフィールドが特定の型を持っていることを確認する。
設定
z.object({
require: z.array(
z.object({
ifName: z.union([z.string(), z.instanceof(RegExp)]),
type: z.string(),
}),
),
}).strict();
例
// OK
model User {
id String
}
// NG
model User {
id Int
}
// OK
model User {
createdAt DateTime
updatedAt DateTime
}
// NG
model User {
createdAt String
updatedAt String
}
require-field
モデルが特定のフィールドを持つことを確認する。
このルールは prisma-lint-ignore-model コメントを使用して特定のフィールドを無視することができる。例えば:
/// prisma-lint-ignore-model require-field tenantId
これは、モデル内の tenantId フィールド違反のみを無視する。他の必須フィールドは引き続き適用される。複数のフィールドを無視する場合は、カンマで区切って指定する。
設定
z.object({
require: z.array(
z.union([
z.string(),
z.object({
name: z.string(),
ifSibling: z.union([z.string(), z.instanceof(RegExp)]),
}),
]),
),
}).strict();
例
// OK
model User {
id Int @id
}
// NG
model User {
name String
}
// OK
model Product {
currencyCode String
priceAmountD6 Int
}
// NG
model Product {
priceAmountD6 Int
}
Ref