Napolean Paced Mischeviously

    jsbrain-prisma-nestjs-graphql

    0.0.0-dev.13 • Public • Published

    prisma-nestjs-graphql

    Generate object types, inputs, args, etc. from prisma schema file for usage with @nestjs/graphql module.

    Features

    • Generates only necessary imports
    • Combines zoo of nested/nullable filters
    • Does not generate resolvers, since it's application specific

    Install

    npm install --save-dev prisma-nestjs-graphql

    Usage

    1. Add new generator section to schema.prisma file
    generator nestgraphql {
        provider = "node node_modules/prisma-nestjs-graphql"
        output = "../src/@generated/prisma-nestjs-graphql"
    }
    1. Run prisma generate
    npx prisma generate
    1. If your models have Decimal and Json 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.

    Generator options

    output

    Output folder relative to this schema file
    Type: string

    outputFilePattern

    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)

    tsConfigFilePath

    Path to tsconfig.json
    Type: string | undefined
    Default: undefined

    combineScalarFilters

    Combine nested/nullable scalar filters to single
    Type: boolean
    Default: false

    noAtomicOperations

    Remove input types for atomic operations
    Type: boolean
    Default: false

    reExport

    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
    }

    emitSingle

    Generate single file with merged classes and enums.
    Type: boolean
    Default: false

    emitCompiled

    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

    purgeOutput

    Delete all files in output folder
    Type: boolean
    Default: false

    useInputType

    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, matches UserWhereInput, PostWhereInput, etc.
    • property Property of the class for which need to choose type. Special case name ALL 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 with matcher:, 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_* (deprecated)

    Map prisma scalar types in [flatten](https://github.com/hughsk/flat) style
    • types_{type}_fieldType TypeScript field type name
    • types_{type}_fieldModule Module to import
    • types_{type}_graphqlType GraphQL type name
    • types_{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;

    Field Settings

    Special directives in triple slash comments for more precise code generation.

    @HideField()

    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;
    }

    Custom Decorators

    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.

    fields_{Namespace}_from

    Required. Name of the module, which will be used in import (class-validator, graphql-scalars, etc.)
    Type: string

    fields_{Namespace}_input

    Means that it will be applied on input types (classes decorated by InputType)
    Type: boolean
    Default: false

    fields_{Namespace}_output

    Means that it will be applied on output types (classes decorated by ObjectType)
    Type: boolean
    Default: false

    fields_{Namespace}_defaultImport

    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}

    fields_{Namespace}_namespaceImport

    Import all as this namespace from module
    Type: undefined | string
    Default: Equals to {Namespace}

    fields_{Namespace}_namedImport

    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;
    }

    @FieldType()

    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.

    @PropertyType()

    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;
    }

    Similar Projects

    Resources

    Install

    npm i jsbrain-prisma-nestjs-graphql

    DownloadsWeekly Downloads

    1

    Version

    0.0.0-dev.13

    License

    MIT

    Unpacked Size

    70.3 kB

    Total Files

    5

    Last publish

    Collaborators

    • jsbrain