Generate object types, inputs, args, etc. from prisma schema file for usage with @nestjs/graphql module.
- Generates only necessary imports
- Combines zoo of nested/nullable filters
- Does not generate resolvers, since it's application specific
npm install --save-dev prisma-nestjs-graphql
- Add new generator section to
schema.prisma
file
generator nestgraphql {
provider = "node node_modules/prisma-nestjs-graphql"
output = "../src/@generated/prisma-nestjs-graphql"
}
- Run prisma generate
npx prisma generate
- If your models have
Decimal
andJson
types, you need install:
npm install graphql-type-json prisma-graphql-type-decimal
Or write you own graphql scalar types, read more on docs.nestjs.com.
Output folder relative to this schema file
Type: string
File path and name pattern
Type: string
Default: {model}/{name}.{type}.ts
Possible tokens:
{model}
Model name in dashed case or 'prisma' if unknown{name}
Dashed-case name of model/input/arg without suffix{type}
Short type name (model, input, args, output){plural.type}
Plural short type name (models, inputs, enums)
Path to tsconfig.json
Type: string | undefined
Default: undefined
Combine nested/nullable scalar filters to single
Type: boolean
Default: false
Remove input types for atomic operations
Type: boolean
Default: false
Create index.ts
file with re-export
Type: enum
Values:
None
Default, create nothing
Directories
Create index file in all root directories
Single
Create single index file in output directory
All
Create index file in all root directories and in output directory
Example configuration:
generator nestgraphql {
provider = "node node_modules/prisma-nestjs-graphql"
output = "../src/@generated/prisma-nestjs-graphql"
reExport = Directories
}
Generate single file with merged classes and enums.
Type: boolean
Default: false
Emit compiled JavaScript and definitions instead of TypeScript sources,
files will be compiled with emitDecoratorMetadata:false
, because there is a problem
with temporal dead zone when generating merged file.
Type: boolean
Default: false
Delete all files in output
folder
Type: boolean
Default: false
Since GraphQL does not support input union type, this setting map allow to choose which input type is preferable.
generator nestgraphql {
useInputType_{typeName}_{property} = "{pattern}"
}
Where:
typeName
Full name or partial name of the class where need to choose input type.
Example:UserCreateInput
full name,WhereInput
partial name, matchesUserWhereInput
,PostWhereInput
, etc.property
Property of the class for which need to choose type. Special case nameALL
means any / all properties.pattern
Part of name (or full) of type which should be chosen, you can use wild card or negate symbols, in this case pattern should starts withmatcher:
, e.g.matcher:*UncheckedCreateInput
See matcher for details.
Example:
export type PostWhereInput = {
author?: XOR<UserRelationFilter, UserWhereInput>;
};
export type UserRelationFilter = {
is?: UserWhereInput;
isNot?: UserWhereInput;
};
export type UserWhereInput = {
AND?: Enumerable<UserWhereInput>;
OR?: Enumerable<UserWhereInput>;
NOT?: Enumerable<UserWhereInput>;
id?: StringFilter | string;
name?: StringFilter | string;
};
We have generated types above, by default property author
will be decorated as UserRelationFilter
,
to set UserWhereInput
need to configure generator the following way:
generator nestgraphql {
provider = "node node_modules/prisma-nestjs-graphql"
output = "../src/@generated/prisma-nestjs-graphql"
useInputType_WhereInput_ALL = "WhereInput"
}
@InputType()
export class PostWhereInput {
@Field(() => UserWhereInput, { nullable: true })
author?: UserWhereInput;
}
types_{type}_fieldType
TypeScript field type nametypes_{type}_fieldModule
Module to importtypes_{type}_graphqlType
GraphQL type nametypes_{type}_graphqlModule
Module to import
Where {type}
is prisma type in schema
Example (Decimal):
types_Decimal_fieldType = "Decimal"
types_Decimal_fieldModule = "decimal.js"
types_Decimal_graphqlType = "GraphQLDecimal"
types_Decimal_graphqlModule = "graphql-type-decimal"
Generates field:
import { GraphQLDecimal } from 'graphql-type-decimal';
import { Decimal } from 'decimal.js';
...
@Field(() => GraphQLDecimal)
field: Decimal;
Example (DateTime):
types_DateTime_fieldType = "Date"
types_DateTime_graphqlType = "GraphQLISODateTime"
types_DateTime_graphqlModule = "@nestjs/graphql"
Generated fields:
@Field(() => GraphQLISODateTime)
field: Date;
Special directives in triple slash comments for more precise code generation.
Removes field from GraphQL schema.
Alias: @TypeGraphQL.omit(output: true)
By default (without arguments) field will be decorated for hide only in output types (type in schema).
To hide field in input types add input: true
.
To hide field in specific type you can use glob pattern match: string | string[]
see outmatch for details.
Examples:
@HideField()
same as@HideField({ output: true })
@HideField({ input: true, output: true })
@HideField({ match: 'UserCreate*Input' })
model User {
id String @id @default(cuid())
/// @HideField()
password String
/// @HideField({ output: true, input: true })
secret String
/// @HideField({ match: '@(User|Comment)Create*Input' })
createdAt DateTime @default(now())
}
May generate classes:
@ObjectType()
export class User {
@HideField()
password: string;
@HideField()
secret: string;
@Field(() => Date, { nullable: false })
createdAt: Date;
}
@InputType()
export class UserCreateInput {
@Field()
password: string;
@HideField()
secret: string;
@HideField()
createdAt: Date;
}
Applying custom decorators requires configuration of generator.
generator nestgraphql {
fields_{Namespace}_from = "module specifier"
fields_{Namespace}_input = true | false
fields_{Namespace}_output = true | false
fields_{Namespace}_defaultImport = "default import name" | true
fields_{Namespace}_namespaceImport = "namespace import name"
fields_{Namespace}_namedImport = true | false
}
Create configuration map in flatten style for {Namespace}
.
Where {Namespace}
is a namespace used in field triple slash comment.
Required. Name of the module, which will be used in import (class-validator
, graphql-scalars
, etc.)
Type: string
Means that it will be applied on input types (classes decorated by InputType
)
Type: boolean
Default: false
Means that it will be applied on output types (classes decorated by ObjectType
)
Type: boolean
Default: false
Default import name, if module have no namespace.
Type: undefined | string | true
Default: undefined
If defined as true
then import name will be same as {Namespace}
Import all as this namespace from module
Type: undefined | string
Default: Equals to {Namespace}
If imported module has internal namespace, this allow to generate named import,
imported name will be equal to {Namespace}
, see example of usage
Type: boolean
Default: false
Custom decorators example:
generator nestgraphql {
fields_Validator_from = "class-validator"
fields_Validator_input = true
}
model User {
id Int @id
/// @Validator.MinLength(3)
name String
}
May generate following class:
import { InputType, Field } from '@nestjs/graphql';
import * as Validator from 'class-validator';
@InputType()
export class UserCreateInput {
@Field(() => String, { nullable: false })
@Validator.MinLength(3)
name!: string;
}
Allow set custom type for field
model User {
id Int @id
/// @FieldType({ name: 'Scalars.GraphQLEmailAddress', from: 'graphql-scalars', input: true })
email String
}
May generate following class:
import { InputType, Field } from '@nestjs/graphql';
import * as Scalars from 'graphql-scalars';
@InputType()
export class UserCreateInput {
@Field(() => Scalars.GraphQLEmailAddress, { nullable: false })
email!: string;
}
And following GraphQL schema:
scalar EmailAddress
input UserCreateInput {
email: EmailAddress!
}
Same field type may be used in different models and it is not convenient to specify every time all options. There is a shortcut:
generator nestgraphql {
fields_Scalars_from = "graphql-scalars"
fields_Scalars_input = true
fields_Scalars_output = true
}
model User {
id Int @id
/// @FieldType('Scalars.GraphQLEmailAddress')
email String
}
The result will be the same. Scalars
is the namespace here.
Missing field options will merged from generator configuration.
Similar to @FieldType()
but refer to TypeScript property (actually field too).
Named import example:
model Transfer {
id String @id
/// @PropertyType({ name: 'Prisma.Decimal', from: '@prisma/client', namedImport: true })
money Decimal
}
May generate following:
import { Prisma } from '@prisma/client';
@ObjectType()
export class User {
@Field(() => GraphQLDecimal)
money!: Prisma.Decimal;
}
Another example:
generator nestgraphql {
fields_TF_from = "type-fest"
}
model User {
id String @id
/// @PropertyType('TF.JsonObject')
data Json
}
May generate:
import * as TF from 'type-fest';
@ObjectType()
export class User {
@Field(() => GraphQLJSON)
data!: TF.JsonObject;
}
- https://github.com/wSedlacek/prisma-generators/tree/master/libs/nestjs
- https://github.com/EndyKaufman/typegraphql-prisma-nestjs
- https://github.com/MichalLytek/typegraphql-prisma
- Todo - unlight#2
- https://github.com/prisma/prisma/blob/master/src/packages/client/src/generation/TSClient/TSClient.ts
- https://ts-ast-viewer.com/
- https://github.com/unlight/nestjs-graphql-prisma-realworld-example-app
- https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-schema/data-model
- JSON type for the code first approach - nestjs/graphql#111 (comment)
- https://github.com/paljs/prisma-tools/tree/master/packages/plugins
- https://github.com/wasp-lang/wasp