Giter Site home page Giter Site logo

vegardit / prisma-generator-nestjs-dto Goto Github PK

View Code? Open in Web Editor NEW
268.0 6.0 72.0 1.17 MB

Generates NestJS DTO classes from Prisma Schema

License: Apache License 2.0

JavaScript 2.27% TypeScript 97.73%
typescript nestjs prisma-schema openapi maintainer-wanted

prisma-generator-nestjs-dto's Introduction

Project Status: Looking for new maintainers!

This project is looking for maintainers.

We are not using this package anymore ourselves, so we can no longer validate/review/test any incoming PRs anymore and ensure correct functionality.

If you are an experienced open source contributor and are interested in taking over maintenance, please open a GitHub issue and let's discuss how to proceed.

Prisma Generator NestJS DTO

Release License

  1. What is it?
  2. Usage
  3. Annotations
  4. Example
  5. Principles
  6. License

What is it?

Generates ConnectDTO, CreateDTO, UpdateDTO, and Entity classes for models in your Prisma Schema. This is useful if you want to leverage OpenAPI in your NestJS application - but also helps with GraphQL resources as well). NestJS Swagger requires input parameters in controllers to be described through classes because it leverages TypeScript's emitted metadata and Reflection to generate models/components for the OpenAPI spec. It does the same for response models/components on your controller methods.

These classes can also be used with the built-in ValidationPipe and Serialization.

Usage?

npm install --save-dev @vegardit/prisma-generator-nestjs-dto
generator nestjsDto {
  provider                        = "prisma-generator-nestjs-dto"
  output                          = "../src/generated/nestjs-dto"
  outputToNestJsResourceStructure = "false"
  exportRelationModifierClasses   = "true"
  reExport                        = "false"
  createDtoPrefix                 = "Create"
  updateDtoPrefix                 = "Update"
  dtoSuffix                       = "Dto"
  entityPrefix                    = ""
  entitySuffix                    = ""
  fileNamingStyle                 = "camel"
}

Parameters

All parameters are optional.

  • [output]: (default: "../src/generated/nestjs-dto") - output path relative to your schema.prisma file
  • [outputToNestJsResourceStructure]: (default: "false") - writes dtos and entities to subfolders aligned with NestJS CRUD generator. Resource module name is derived from lower-cased model name in schema.prisma
  • [exportRelationModifierClasses]: (default: "true") - Should extra classes generated for relationship field operations on DTOs be exported?
  • [reExport]: (default: false) - Should an index.ts be created for every folder?
  • [createDtoPrefix]: (default: "Create") - phrase to prefix every CreateDTO class with
  • [updateDtoPrefix]: (default: "Update") - phrase to prefix every UpdateDTO class with
  • [dtoSuffix]: (default: "Dto") - phrase to suffix every CreateDTO and UpdateDTO class with
  • [entityPrefix]: (default: "") - phrase to prefix every Entity class with
  • [entitySuffix]: (default: "") - phrase to suffix every Entity class with
  • [fileNamingStyle]: (default: "camel") - how to name generated files. Valid choices are "camel", "pascal", "kebab" and "snake".

Annotations

Annotations provide additional information to help this generator understand your intentions. They are applied as tripple slash comments to a field node in your Prisma Schema. You can apply multiple annotations to the same field.

model Post {
  /// @DtoCreateOptional
  /// @DtoUpdateHidden
  createdAt   DateTime @default(now())
}
  • @DtoReadOnly - omits field in CreateDTO and UpdateDTO
  • @DtoEntityHidden - omits field in Entity
  • @DtoCreateOptional - adds field optionally to CreateDTO - useful for fields that would otherwise be omitted (e.g. @id, @updatedAt)
  • @DtoUpdateOptional- adds field optionally to UpdateDTO - useful for fields that would otherwise be omitted (e.g. @id, @updatedAt)
  • @DtoRelationRequired - marks relation required in Entity although it's optional in PrismaSchema - useful when you don't want (SQL) ON DELETE CASCADE behavior - but your logical data schema sees this relation as required (Note: becomes obsolete once referentialActions are released and stable)
  • @DtoRelationCanCreateOnCreate - adds create option on a relation field in the generated CreateDTO - useful when you want to allow to create related model instances
  • @DtoRelationCanConnectOnCreate - adds connect option on a relation field in the generated CreateDTO - useful when you want/need to connect to an existing related instance
  • @DtoRelationCanCreateOnUpdate - adds create option on a relation field in the generated UpdateDTO - useful when you want to allow to create related model instances
  • @DtoRelationCanConnectOnUpdate - adds connect option on a relation field in the generated UpdateDTO - useful when you want/need to connect to an existing related instance

Example

Prisma Schema
generator nestjsDto {
provider = "prisma-generator-nestjs-dto"
output = "../src"
outputToNestJsResourceStructure = "true"
}

model Question {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
/// @DtoReadOnly
createdAt DateTime @default(now())
/// @DtoRelationRequired
createdBy User? @relation("CreatedQuestions", fields: [createdById], references: [id])
createdById String? @db.Uuid
updatedAt DateTime @updatedAt
/// @DtoRelationRequired
updatedBy User? @relation("UpdatedQuestions", fields: [updatedById], references: [id])
updatedById String? @db.Uuid

  /// @DtoRelationRequired
  /// @DtoRelationCanConnectOnCreate
  category   Category? @relation(fields: [categoryId], references: [id])
  categoryId String?   @db.Uuid

  /// @DtoCreateOptional
  /// @DtoRelationCanCreateOnCreate
  /// @DtoRelationCanConnectOnCreate
  /// @DtoRelationCanCreateOnUpdate
  /// @DtoRelationCanConnectOnUpdate
  tags Tag[]

  title     String
  content   String
  responses Response[]

}
Generated results
// src/question/dto/connect-question.dto.ts
export class ConnectQuestionDto {
  id: string;
}
// src/question/dto/create-question.dto.ts
import { ApiExtraModels } from '@nestjs/swagger';
import { ConnectCategoryDto } from '../../category/dto/connect-category.dto';
import { CreateTagDto } from '../../tag/dto/create-tag.dto';
import { ConnectTagDto } from '../../tag/dto/connect-tag.dto';

export class CreateQuestionCategoryRelationInputDto {
  connect: ConnectCategoryDto;
}
export class CreateQuestionTagsRelationInputDto {
  create?: CreateTagDto[];
  connect?: ConnectTagDto[];
}

@ApiExtraModels(
  ConnectCategoryDto,
  CreateQuestionCategoryRelationInputDto,
  CreateTagDto,
  ConnectTagDto,
  CreateQuestionTagsRelationInputDto,
)
export class CreateQuestionDto {
  category: CreateQuestionCategoryRelationInputDto;
  tags?: CreateQuestionTagsRelationInputDto;
  title: string;
  content: string;
}
// src/question/dto/update-question.dto.ts
import { ApiExtraModels } from '@nestjs/swagger';
import { CreateTagDto } from '../../tag/dto/create-tag.dto';
import { ConnectTagDto } from '../../tag/dto/connect-tag.dto';

export class UpdateQuestionTagsRelationInputDto {
  create?: CreateTagDto[];
  connect?: ConnectTagDto[];
}

@ApiExtraModels(CreateTagDto, ConnectTagDto, UpdateQuestionTagsRelationInputDto)
export class UpdateQuestionDto {
  tags?: UpdateQuestionTagsRelationInputDto;
  title?: string;
  content?: string;
}
// src/question/entities/question.entity.ts
import { User } from '../../user/entities/user.entity';
import { Category } from '../../category/entities/category.entity';
import { Tag } from '../../tag/entities/tag.entity';
import { Response } from '../../response/entities/response.entity';

export class Question {
  id: string;
  createdAt: Date;
  createdBy?: User;
  createdById: string;
  updatedAt: Date;
  updatedBy?: User;
  updatedById: string;
  category?: Category;
  categoryId: string;
  tags?: Tag[];
  title: string;
  content: string;
  responses?: Response[];
}

Principles

Generally we read field properties from the DMMF.Field information provided by @prisma/generator-helper. Since a few scenarios don't become quite clear from that, we also check for additional annotations (or decorators) in a field's documentation (that is anything provided as a tripple slash comments for that field in your prisma.schema).

Initially, we wanted DTO classes to implement Prisma.<ModelName><(Create|Update)>Input but that turned out to conflict with required relation fields.

ConnectDTO

This kind of DTO represents the structure of input-data to expect from 'outside' (e.g. REST API consumer) when attempting to connect to a model through a relation field.

A Models ConnectDTO class is composed from a unique'd list of isId and isUnique scalar fields. If the ConnectDTO class has exactly one property, the property is marked as required. If there are more than one properties, all properties are optional (since setting a single one of them is already sufficient for a unique query) - you must however specify at least one property.

ConnectDTOs are used for relation fields in CreateDTOs and UpdateDTOs.

CreateDTO

This kind of DTO represents the structure of input-data to expect from 'outside' (e.g. REST API consumer) when attempting to create a new instance of a Model. Typically the requirements for database schema differ from what we want to allow users to do. As an example (and this is the opinion represented in this generator), we don't think that relation scalar fields should be exposed to users for create, update, or delete activities (btw. TypeScript types generated in PrismaClient exclude these fields as well). If however, your schema defines a required relation, creating an entity of that Model would become quite difficult without the relation data. In some cases you can derive information regarding related instances from context (e.g. HTTP path on the rest endpoint /api/post/:postid/comment to create a Comment with relation to a Post). For all other cases, we have the

  • @DtoRelationCanCreateOnCreate
  • @DtoRelationCanConnectOnCreate
  • @DtoRelationCanCreateOnUpdate
  • @DtoRelationCanConnectOnUpdate

annotations that generate corresponding input properties on CreateDTO and UpdateDTO (optional or required - depending on the nature of the relation).

When generating a Models CreateDTO class, field that meet any of the following conditions are omitted (order matters):

  • isReadOnly OR is annotated with @DtoReadOnly (Note: this apparently includes relation scalar fields)
  • field represents a relation (field.kind === 'object') and is not annotated with @DtoRelationCanCreateOnCreate or @DtoRelationCanConnectOnCreate
  • field is a relation scalar
  • field is not annotated with @DtoCreateOptional AND
    • isId && hasDefaultValue (id fields are not supposed to be provided by the user)
    • isUpdatedAt (Prisma will inject value)
    • isRequired && hasDefaultValue (for schema-required fields that fallback to a default value when empty. Think: createdAt timestamps with @default(now()) (see now()))

UpdateDTO

When generating a Models UpdateDTO class, field that meet any of the following conditions are omitted (order matters):

  • field is annotated with @DtoUpdateOptional
  • isReadOnly OR is annotated with @DtoReadOnly (Note: this apparently includes relation scalar fields)
  • isId (id fields are not supposed to be updated by the user)
  • field represents a relation (field.kind === 'object') and is not annotated with @DtoRelationCanCreateOnUpdate or @DtoRelationCanConnectOnUpdate
  • field is a relation scalar
  • field is not annotated with @DtoUpdateOptional AND
    • isId (id fields are not supposed to be updated by the user)
    • isUpdatedAt (Prisma will inject value)
    • isRequired && hasDefaultValue (for schema-required fields that fallback to a default value when empty. Think: createdAt timestamps with @default(now()) (see now()))

Entity

When generating a Models Entity class, only fields annotated with @DtoEntityHidden are omitted. All other fields are only manipulated regarding their isRequired and isNullable flags.

By default, every scalar field in an entity is required meaning it doesn't get the TypeScript "optional member flag" ? next to it's name. Fields that are marked as optional in PrismaSchema are treated as nullable - meaning their TypeScript type is a union of field.type and null (e.g. string | null).

Relation and relation scalar fields are treated differently. If you don't specifically include a relation in your query, those fields will not exist in the response.

  • every relation field is always optional (isRequired = false)
  • relations are nullable except when
    • the relation field is a one-to-many or many-to-many (i.e. list) type (would return empty array if no related records found)
    • the relation was originally flagged as required (isRequired = true)
    • the relation field is annotated with @DtoRelationRequired (do this when you mark a relation as optional in PrismaSchema because you don't want (SQL) ON DELETE CASCADE behavior - but your logical data schema sees this relation as required)

License

All files are released under the Apache License 2.0.

prisma-generator-nestjs-dto's People

Contributors

benkroeger avatar dependabot[bot] avatar djiit avatar ohmree avatar sebthom avatar tpdewolf avatar webdagger avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

prisma-generator-nestjs-dto's Issues

nothing gets generated

I'm using Prisma 3.7.0
npx prisma migrate dev --name init but no dto or entity gets generateed

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator nestjsDto {
provider = "prisma-generator-nestjs-dto"
output = "../src"
}

model User {
  id           String         @id(map: "user_pk") @db.Uuid
  username     String         @unique(map: "user_username_uindex") @db.VarChar(255)
  email        String         @unique(map: "user_email_uindex") @db.VarChar(255)
  first_name   String         @db.VarChar(255)
  last_name    String         @db.VarChar(255)
  password     String         @db.VarChar(255)
  phone        String         @db.VarChar(255)
  phone_code   String?        @db.VarChar(50)
  last_login   DateTime?      @db.Date
  created_at   DateTime?      @default(now())
  updated_at   DateTime?      @updatedAt
  role         Role           @default(USER)
  article      Article[]
  user_address User_address[]
}

model User_address {
  id            String    @id(map: "user_address_pk") @db.Uuid
  user_id       String    @db.Uuid
  address_line1 String    @db.VarChar(255)
  address_line2 String    @db.VarChar(255)
  city          String    @db.VarChar(255)
  postal_code   String    @db.VarChar(255)
  country       String    @db.VarChar(255)
  created_at    DateTime? @default(now())
  updated_at    DateTime? @updatedAt
  gender        Gender
  user          User      @relation(fields: [user_id], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "user_id_fk")
}

model Article {
  id          String    @id(map: "article_pk") @db.Uuid
  author_id   String    @db.Uuid
  articleName String    @db.VarChar(255)
  isPublished Boolean   @default(false)
  created_at  DateTime? @default(now())
  updated_at  DateTime? @updatedAt
  user        User      @relation(fields: [author_id], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "author_id_fk")
}

enum Gender {
  man
  woman
}

enum Role {
  USER
  ADMIN
  SUPERADMIN
}

Swagger decorators not being added

I'm not sure if this is something i am doing wrong or a problem with the library?

I have created a basic setup as a test but it doesn't seem to be generating the swagger decorators

Schema and output below:

// prisma.schema

generator client {
  provider = "prisma-client-js"
  output   = "../../node_modules/.prisma/client"
}

generator nestjsDto {
  provider                        = "prisma-generator-nestjs-dto"
  output                          = "../src/generated/nestjs-dto"
  outputToNestJsResourceStructure = "true"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id             String     @id @default(uuid())
  username       String     @unique
  email          String     @unique
  firstName      String?
  surname        String?
}
// src/generated/nestjs-dto/user/dto/connect-user.dto.ts

export class ConnectUserDto {
  id?: string;
  username?: string;
  email?: string;
}
// src/generated/nestjs-dto/user/dto/create-user.dto.ts

export class CreateUserDto {
  username: string;
  email: string;
  firstName?: string;
  surname?: string;
}
// src/generated/nestjs-dto/user/dto/update-user.dto.ts

export class UpdateUserDto {
  username?: string;
  email?: string;
  firstName?: string;
  surname?: string;
}

// src/generated/nestjs-dto/user/entities/user.entity.ts

export class User {
  id: string;
  username: string;
  email: string;
  firstName: string | null;
  surname: string | null;
}

Still Maintained?

Dear all,

is this package still maintained? Latest commits are only "update deps" and no new features.
All the best,
Johannes

Incorrect prisma client import from for generated DTOs

❌ Problem:

  1. Current import import {Prisma} from '@prisma/client' is incorrect/outdated, it's causing lots of import errors, a bit of pain to manually correct if you have quite a few tables/entities
  2. Current generated DTO has Eslint issues => annoying to fix myself when I have 30+ files to fix (on top of the import issue above)
import {Prisma} from '@prisma/client'




export class CreateCaloriesDto {
  dateTime?: Date;
value?: Prisma.Decimal;
date?: Date;
}

✅ Expected behaviour:

The package should generate import { PrismaClient } from '@prisma/client'; for each generated dto/entity/class files, and correct the corresponding types that use the old import, rather than keep using the old import {Prisma} from '@prisma/client' for all generated files

For e.g:

💀 Old/incorrect version with import errors

import {Prisma} from '@prisma/client';

export class CreateCaloriesDto {
  dateTime?: Date;
  value?: Prisma.Decimal;
  date?: Date;
}

🙂 Expected/correct new DTO with correct PrismaClient import

import { PrismaClient } from '@prisma/client';

export class CreateCaloriesDto {
  dateTime?: Date;
  value?: PrismaClient.Decimal;
  date?: Date;
}

Generating optional `_count` fields in output entity types

Has anyone managed to add generating a typed _count optional field for entities generated by this tool?

I've been trawling the forks of this repo, and haven't seen anything to support this so far.

It would be really nice to have this feature. I want to attempt this on my fork, but I need some pointers.
The Prisma Client generates typing for the _count field as a part of [model]GetPayload. I'm not sure how to go about incorporating this into the final entity type generation.

Any pointers in the right direction are absolutely welcome. Thanks in advance!

[Requests] - Don't override existing - Generate Only Entity/Dto/Create

Hello, firstly I would like to say thank you for this amazing package. It saved a lot of time for me. Because I am using it currently, I would like to suggest/request two features.

1: Don't override if file exists

  • When it is generated, sometimes we do changes such as adding validator decorators. Especially when I use outputToNestJsResourceStructure = "true", I do add validators. It would be good if this package does not do anything if there is any file on that location. ( as an option )

2: Select what is going to be generated. For example only generate Entity and Create Dto

Proposing syntax to reduce code boilerplate and add flexibility

The current approach was a bit verbose and easily to become complex and unmaintainable specially when there are too many fields and dto properties. As for the future prisma will also add check constraints annotation which will make more hard to read the DTO...

I have a proposed syntax where it can improve some part of the model schema
Here is the example:

enum Gender {
  male
  female
  other
}

enum Role {
  admin
  moderator
  user
}

/// @@CreateDTO(name:"User", fields: [firstname, middlename, lastname, birthday, gender])
/// @@UpdateDTO(name:"UserFullname", fields: [firstname, middlename, lastname])
/// @@UpdateDTO(name:"UserBirthday", fields: [birthday])
/// @@UpdateDTO(name:"UserGender", fields: [gender])
model User {
 id String @id @default(cuid())
 firstname String
 middlename String?
 lastname String
 birthday DateTime?
 gender Gender?

 memberships Membership[]
}

/// @@CreateDTO(name:"Group", fields: [name, description, memberships])
/// @@UpdateDTO(name:"GroupName", fields: [name])
/// @@UpdateDTO(name:"GroupDescription", fields: [description])
model Group {
  id String @id @default(cuid())
  name String
  description String

  memberships Membership[]
}

/// @@CreateDTO(name:"Membership", fields: [groupId, id])
/// @@UpdateDTO(name:"MembershipRole", fields: [role])
model Membership {
  group Group @relation(fields: [groupId], references: [id])
  groupId String

  user User @relation(fields: [id], references: [id])
  id String @id @default(cuid())

  role Role @default(user)
}
  1. This is improves readability by decluttering field level annotating.
  2. More Flexibility to customize the name of DTO and cherry pick a field for specific DTO. Handful if you have many single field update API
  3. All fields for CreateDTO and UpdateDTO are group into single line "Single Responsibility"
  4. All optional fields can be inferred by instrospecting "?" on field type

We want to maintain this project

Hi, This is Jordan from @mvlchain
We're recently using Prisma for our nestjs projects and currently we're using this library for auto-generating dtos.
We've once reached to this project like this PR: #149

Due to the stopping maintenance of this library, we currently using this package deploying to our custom set package manager,
but it would be great if our company succeeds in this project as an open source project and keep touching the community who are using this library and keep going on (Because auto-generate is always good to developers!)

Wishes / Ideas

Good Morning,

I have two ideas for extension:

FIRST:
Maybe I just did not see it, but how can I set the import path of prisma client? I use a different path of prisma client and need to set this as option to nestjsDto generator.

have:
import {Enum_UserSalutation} from '@prisma/client

want:
import {Enum_UserSalutation} from '@db'

SECOND:
Would be nice to have an generated index.ts file with all exports, like:

export { default as A } from "./a";
export { default as B } from "./b";
[...]

Have a great day!

Error: spawn prisma-generator-nestjs-dto ENOENT

Hi,

I just tried out your tool and get following Error on my windows machine after running prisma generate:

Error: spawn prisma-generator-nestjs-dto ENOENT

I tried running it in git bash, IntelliJ Terminal, CMD, Windows Terminal. Is it maybe an missing permission (I have a lokal Admin account..)? Or is my schema code wrong?

generator client {
  provider        = "prisma-client-js"
  output          = "../generated/prisma-client"
}

generator nestjsDto {
  provider                        = "prisma-generator-nestjs-dto"
  output                          = "../libs/shared-dto/src/test"
  outputToNestJsResourceStructure = "false"
  exportRelationModifierClasses   = "true"
  reExport                        = "false"
  createDtoPrefix                 = "Create"
  updateDtoPrefix                 = "Update"
  dtoSuffix                       = "Dto"
  entityPrefix                    = ""
  entitySuffix                    = ""
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

[...]

UPDATE:
I also tried it after doing this:

rimraf node_modules
npm cache clean --force
npm ci

Do you have any idea?

Regards

Generate index.ts

Is it possible to generate a index.ts which exports all generated interfaces/types etc. ?

For example a generated file like this:

export * from './connect-user.dto';
export * from './create-user.dto';
export * from './update-user.dto';
export * from './user.entity';

Missing generated relation DTO's

Hi @benkroeger, thanks for replying back to my issue about relations in #14 .

So I just tried your suggestion of adding in the annotated relations, but I am now running into more issues. The create-${resource}.dto.ts is being appropriately updated with the new relations, however those relation entities are not being generated themselves. Here is an example:

schema.prisma

generator nestjsDto {
  provider                        = "prisma-generator-nestjs-dto"
  output                          = "./schema"
  outputToNestJsResourceStructure = "true"
  entitySuffix                    = "Entity"
}

model Asset {
    ...otherProps
    /// @DtoRelationCanCreateOnCreate
    venue                       Venue           @relation(fields: [venueId], references: [id])
    venueId                     Int
}

create-asset.dto.ts

import { ApiExtraModels } from '@nestjs/swagger';
import { CreateVenueDto } from '../../venue/dto/create-venue.dto';

export class CreateAssetVenueRelationInputDto {
  create: CreateVenueDto;
}

@ApiExtraModels(CreateVenueDtoEntity, CreateAssetVenueRelationInputDtoEntity)
export class CreateAssetDto {
  ...otherProps
  venue: CreateAssetVenueRelationInputDtoEntity;
}

In the above example, the CreateVenueDtoEntity and CreateAssetVenueRelationInputDtoEntity called in the @ApiExtraModels decorator do not exist/have not been generated, and neither has the CreateAssetVenueRelationInputDtoEntity found in the DTO definition.

Because of this, the TS compiler is failing. Any ideas what is going wrong here?

[Feature] Add Validation Annotations

Problem

I cannot add custom validation class annotations to the generated typescript classes from the prisma.schema

Feature Request

If there is a model that looks like this:

model Organization {
  id    String     @id @default(cuid())
  name  String  @unique
  email String
}

It would be nice to have the ability to add annotations as follows:

model Organization {
  id    String     @id @default(cuid())
  /// @IsNotEmpty()
  name  String  @unique
  /// @IsEmail()
  email String
}

that would create a class like this:

export class CreateOrganizationDto {
  @IsNotEmpty()
  name: string;

  @IsEmail()
  email: string;
}

Self relation Problem

I have a simple schema:

generator nestjsDto {
  provider                        = "prisma-generator-nestjs-dto"
  exportRelationModifierClasses   = "true"
  reExport                        = "true"
  createDtoPrefix                 = "Create"
  updateDtoPrefix                 = "Update"
  dtoSuffix                       = "Dto"
  entityPrefix                    = ""
  entitySuffix                    = ""
  fileNamingStyle                 = "kebab"
  output                          = "../src"
  outputToNestJsResourceStructure = "true"
}

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model Puesto {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  nombre String
  /// @DtoCreateOptional
  /// @DtoUpdateOptional
  /// @DtoRelationCanConnectOnCreate
  /// @DtoRelationCanConnectOnUpdate
  jefeInmediato   Puesto?  @relation("JefeEmpleados", fields: [jefeInmediatoId], references: [id])
  jefeInmediatoId Int?
  personalAcargo  Puesto[] @relation("JefeEmpleados")
  @@map("puestos")
}

But when I compile then I keep getting this error on the connect DTO:

 Cannot find module 'C:/sistema-gestion-riesgo/src/puesto/dto/connect-puesto.dto'
Require stack:
- C:\sistema-gestion-riesgo\dist\puesto\dto\create-puesto.dto.js
- C:\sistema-gestion-riesgo\dist\puesto\puesto.controller.js
- C:\sistema-gestion-riesgo\dist\puesto\puesto.module.js
- C:\sistema-gestion-riesgo\dist\app.module.js
- C:\sistema-gestion-riesgo\dist\main.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.type (C:\sistema-gestion-riesgo\dist\puesto\dto\create-puesto.dto.js:15:57)
    at SchemaObjectFactory.mergePropertyWithMetadata (C:\sistema-gestion-riesgo\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:116:38)
    at C:\sistema-gestion-riesgo\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:79:35
    at Array.map (<anonymous>)
    at SchemaObjectFactory.extractPropertiesFromType (C:\sistema-gestion-riesgo\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:78:52)
    at SchemaObjectFactory.exploreModelSchema (C:\sistema-gestion-riesgo\node_modules\@nestjs\swagger\dist\services\schema-object-factory.js:92:41) 

As additional information my tsconfig.JSON file

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2021",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": false,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false
  }
}

Required relation field not showing in generated DTO, and marked as optional in generated Entity

I am probably doing something wrong on my end, but seems like my generated files are not correct on a 1 to many relation. I am expecting both the entity and the DTO to include the event property on a CreateListing object.

Prisma Schema:

generator nestjsDto {
  provider                        = "prisma-generator-nestjs-dto"
  output                          = "./schema"
  outputToNestJsResourceStructure = "true"
  entitySuffix                    = "Entity"
}

model Event {
    ...props

    // Relations
    listings            Listing[]
}

model Listing {
   ...props

    // Relations
    event                       Event           @relation(fields: [eventId], references: [id])
    eventId                     Int
}

Generated Listing DTO (No event field):

export class CreateListingDto {
  legacyFeedListingId?: number;
  legacySellerListingId?: number;
  @ApiProperty({ enum: ListingSource })
  listingSource: ListingSource;
  tevoId?: number;
  wholesalePrice: number;
  retailPrice: number;
  @ApiProperty({ enum: AccessType })
  accessType: AccessType;
  notes?: string;
  ticketGroupSizes: number[];
  vipPassNotes?: string;
  parkingNotes?: string;
  seatingNotes?: string;
  cateringNotes?: string;
}

Generated Listing Entity (Marked as optional):

import { ListingSource, AccessType } from '@prisma/client';
import { AssetEntity } from '../../asset/entities/asset.entity';
import { EventEntity } from '../../event/entities/event.entity';

export class ListingEntity {
  id: number;
  legacyFeedListingId: number | null;
  legacySellerListingId: number | null;
  listingSource: ListingSource;
  tevoId: number | null;
  wholesalePrice: number;
  retailPrice: number;
  accessType: AccessType;
  notes: string | null;
  ticketGroupSizes: number[];
  numberParkingInc: number;
  concierge: boolean;
  foodInc: boolean;
  alcoholInc: boolean;
  nonAlcoholInc: boolean;
  vipPassInc: boolean;
  vipPassNotes: string | null;
  parkingNotes: string | null;
  seatingNotes: string | null;
  cateringNotes: string | null;
  promote: boolean;
  asset?: AssetEntity | null;
  assetId: number | null;
  event?: EventEntity;
  eventId: number;
}

Issues with imports

Hello, first of all, thanks for the great generator.

Everything seems in order except few things namely imports to Prisma that exports types used in generated classes and the wrong path of entity files in the generated output. Below is the example.


schema.prisma

model Product {
  id          String   @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
  name        String   @db.VarChar(255)
  description String   @db.VarChar(1024)
  images      Json[]   @db.Json
  highlighted Boolean? @default(false)
  reviewCount Int?     @default(0)
  attributes  Json?
  score       Float?
  categoryId  String   @db.Uuid
  companyId   String   @db.Uuid

  /// @DtoRelationRequired
  /// @DtoRelationCanConnectOnCreate
  category    Category @relation(fields: [categoryId], references: [id])

  /// @DtoRelationRequired
  /// @DtoRelationCanConnectOnCreate
  company     Company  @relation(fields: [companyId], references: [id])

  /// @DtoEntityHidden
  /// @DtoCreateOptional
  /// @DtoUpdateOptional
  createdAt DateTime @default(now()) @db.Timestamptz(6)

  /// @DtoEntityHidden
  /// @DtoCreateOptional
  /// @DtoUpdateOptional
  updatedAt DateTime @updatedAt @db.Timestamptz(6)

  @@map("products")
}


Output

Folder structure:

├── product.service.ts
├── dto
│   ├── create-product.dto.ts
│   ├── connect-product.dto.ts
│   └── update-product.dto.ts
├── entities
│   └── product.entity.ts
├── product.controller.ts
└── product.module.ts

Dto folder and entities folder are generated service module and controller are nestjs standard files.

product.entity.ts

import { Category } from '../../category/dto/category.entity';
import { Company } from '../../company/dto/company.entity';

export class Product {
  id: string;
  name: string;
  description: string;
  images: Prisma.JsonValue[];
  highlighted: boolean | null;
  reviewCount: number | null;
  attributes: Prisma.JsonValue | null;
  score: number | null;
  categoryId: string;
  companyId: string;
  category?: Category;
  company?: Company;
}

As expected importing from the wrong path fails and since there is no Prisma in scope it also fails.

The solution is to manually import Category and Company from the right generated paths and to import Prisma from @prisma/client.

I may be missing something but apart from those two issues, everything else seems to work just fine. Thanks again for the generator.

Support for enum types.

Since NestJS requires you to manually set the enum property on the @ApiProperty:
https://docs.nestjs.com/openapi/types-and-parameters#enums

Would it be possible to extract the enum properties from the prisma.schema and generate the corresponding @Api decorator like so:

  • prisma.schema
model User {
  id          String   @id @default(cuid())
  userType    UserType
}
enum UserType {
  student
  teacher
}
  • user.entity.ts
import { UserType } from '@prisma/client';

export class User {
  id: string;
  
  @ApiProperty({ enum: ['student', 'teacher']})
  userType: UserType;
}

Project maintainer

Hi team, I am not an experienced open source contributor but would like to try and maintain this project. Please let me know if that's alright and what are the next steps. Thank you!

Duplicate imports for duplicate fields type

Thank you for this beautiful library, it's really helpful.

The generator tries to import a dto twice when there is multiple fields with the same type in the prisma.schema, like this for example:

model Teacher {
  id             String    @id @default(cuid())
  /// @DtoRelationCanConnectOnUpdate
  proposedOffers Offer[]   @relation("proposedOffers")
  /// @DtoRelationCanConnectOnUpdate
  acceptedOffers Offer[]   @relation("acceptedOffers")
  /// @DtoReadOnly
  createdAt      DateTime  @default(now())
  /// @DtoReadOnly
  updatedAt      DateTime  @updatedAt
}

So in the update-teacher.dto, I get two imports like this:

...
import { ConnectOfferDto } from './connect-offer.dto';
import { ConnectOfferDto } from './connect-offer.dto';
...

Prisma Generate: MongoDB throws related model not found when using Types

In this scenario, I have a nested Document type that isn't a database indexed item.

Let's use Foo and Oof both needing access to the type of Bar.

file: schema.prisma

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mongodb"
  url      = "{urlOmitted}"
}

generator nestjsDto {
  provider                        = "prisma-generator-nestjs-dto"
  output                          = "../src"
  outputToNestJsResourceStructure = "true"
}

type Bar {
  thing1 String
  thing2 Int
  thing3 Boolean
}

model Foo {
  id            String          @id @default(auto()) @map("_id") @db.ObjectId
  bar          Bar
  thing       Int
}

model Oof {
  id            String          @id @default(auto()) @map("_id") @db.ObjectId
  bar          Bar
  thing      String
}

Upon generation, an error is thrown Error: related model 'Bar' for 'Foo.bar' not found

npx prisma generate
Prisma schema loaded from prisma/schema.prisma
prisma:info Processing Model Foo
Error:
✔ Generated Prisma Client (3.14.0 | library) to ./node_modules/@prisma/client in 74ms

Error: related model 'Bar' for 'Foo.bar' not found

Configurable file naming scheme

Hi, this project looks really nice, thanks for creating it!

I've noticed that ATM the generated file names are always in camelCase, while I prefer kebab-case.

I could really benefit from an option to set the naming scheme for generated files, similarly to the one that seems to be implemented in this generator.

Is this something that could be added?

npm run test not running

I cloned your repo, and ran npm i. What is required to get the tests to run?

Thanks.

Running coverage on untested files...Failed to collect coverage from /Users/raarts/work/prisma-generator-nestjs-dto/src/@generated/prisma-generator-nestjs-dto/create-product.dto.ts
ERROR: src/@generated/prisma-generator-nestjs-dto/create-product.dto.ts:1:24 - error TS2307: Cannot find module '@prisma/client' or its corresponding type declarations.

1 import { Prisma } from '@prisma/client';
                         ~~~~~~~~~~~~~~~~
src/@generated/prisma-generator-nestjs-dto/create-product.dto.ts:2:32 - error TS2307: Cannot find module '@nestjs/swagger' or its corresponding type declarations.

2 import { ApiExtraModels } from '@nestjs/swagger';
                                 ~~~~~~~~~~~~~~~~~
src/@generated/prisma-generator-nestjs-dto/create-product.dto.ts:7:3 - error TS2564: Property 'connect' has no initializer and is not definitely assigned in the constructor.

7   connect: ConnectCategoryDto;

Support node v14

Installing the package gives me the error that it's incompatible with node < 16.3.

Is there a problem why this package doesn't work with v14 or is it just a matter of configuration?

Thanks :)

Generated code imports using \ instead of /

Example of generated code:

import {Authentication} from '..\..\authentication\entities\authentication.entity'


export class Account {
  email: string ;
name: string ;
authentication?: Authentication  | null;
authenticationId: string  | null;
createdAt: Date ;
updatedAt: Date ;
}

On windows 11, node lts

Enum gets imported even if the field is excluded

Using the annotation for excluding a field on an enum:

model User {
  id   String @id @default(uuid())
  name String
  /// @DtoReadOnly
  role Role
}

The generated output still imports the Enum, which results in eslint errors:


import {Role} from '@prisma/client'

export class CreateUserDto {
  name: string;
}

Upcoming rename of `@prisma/sdk` to `@prisma/internals` with Prisma 4

Hey,

Jan from Prisma Engineering here.

Quick heads up that we will soon rename our @prisma/sdk package to @prisma/internals with Prisma 4, which we plan to release on June 28th (soon!).

The @prisma/sdk package was meant as an Prisma internal package only, but somehow it leaked out over time and is now used across all kinds of tools - including yours of course 😄

With the rename of the Npm package we want to make it clearer that we can not give any API guarantees for @prisma/internals, might need to introduce breaking changes to the API from time to time and will not follow semantic versioning (breaking changes only in major upgrade) with it. We think that it is better communicated with internals than with sdk.
With Prisma 4, besides the package name nothing should change though.

Additionally it would be super helpful if you could help us gain an understanding where, how and why you are using @prisma/sdk (soon @prisma/internals, remember 😀) to achieve, what exactly. We want to cleanup that package and your feedback will be valuable to us to define a better API.

Looking forward to your feedback.

Best
Jan & your friends at Prisma

PS: Are you using Prisma.dmmf from import { Prisma } from '@prisma/client' in your code somewhere by chance? That will also change soon and not include the Prisma.dmmf.schema sub property. Instead you can use getDmmf from @prisma/internals moving forward.

Future maintainer

Hello, I'd love to maintain this project seeing as how I use it quite a bit.

I have a fork located here that I created to add some options

Funnily enough, I noticed that this would effectively close #92

Generated files are poorly formatted

When I generate the classes from my Prisma schema, the outputted files are very weirdly/poorly formatted.
Some files have empty lines before the class starts, others are unnecessarily or inconsistently indented.

The problem is easily fixed by running npm run format but it would be nice if this step would not be necessary.

Singular vs Plural resource name

While generating the dto and entities using the outputToNestJsResourceStructure option, resources names are singular; but the CRUD resource generator of NestJS uses plural names. Should we use plural names?

Formating generated output

When we use this generator the output is formatted according to its own prettier rules.
When the generated code ends up in our project, that has different rules, we see the diff on every generation as local changes.

Is there a way to avoid this behavior such as:

  • load project prettier rules
  • add a hook after generation so we can run prettier --write . or similar command
  • add an option to enable/disable the generator
  • another solution
-export class ConnectCampaignDto {
-  id?: string
-  slug?: string
-}
+  export class ConnectCampaignDto {
+    id?: string;
+slug?: string;
+  }
  

prisma-generator-nestjs-dto: not found

Hi,
I feel excited to find your repository after reading Prisma Generator concepts from Prisma main documents.
I've installed the generator using the readme command line: npm install --save-dev @vegardit/prisma-generator-nestjs-dto and added the corresponding generator in my schema.prisma file, but changed the output folder using the output parameter, no other parameters are provided.

generator client {
  provider = "prisma-client-js"
  output   = "../libs/tipus-avismon/src/lib"
}

generator nestjsDto {
  provider = "prisma-generator-nestjs-dto"
  output   = "../libs/tipus-avismon/src/lib"
}

I've started prisma generate but the following error is show:

$ prisma generate
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Error: Generator at prisma-generator-nestjs-dto could not start:

/bin/sh: 1: prisma-generator-nestjs-dto: not found

prisma client generator is also in my schema.prisma file and it worked fine.

I've searched in issues and found some information at #16 about the symlink. It is there, but I cannot find node_modules/prisma-generator-nestjs-dto/dist/cli.js in my node_modules folder.

I'm using prisma on a nx (@nrwl/nx) nest/angular monorepo. Maybe this could be involved in the issue.
Additional information about environement and versions:

**Prisma:**
   Environment variables loaded from .env
   prisma                  : 3.12.0
   @prisma/client          : 3.12.0
   Current platform        : debian-openssl-1.1.x
   Query Engine (Node-API) : libquery-engine 22b822189f46ef0dc5c5b503368d1bee01213980 (at .../.nvm/versions/node/v16.14.2/lib/node_modules/prisma/node_modules/@prisma/engines/libquery_engine-debian-openssl- 1.1.x.so.node)
   Migration Engine        : migration-engine-cli 22b822189f46ef0dc5c5b503368d1bee01213980 (at ../.nvm/versions/node/v16.14.2/lib/node_modules/prisma/node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x)
   Introspection Engine    : introspection-core 22b822189f46ef0dc5c5b503368d1bee01213980 (at ../.nvm/versions/node/v16.14.2/lib/node_modules/prisma/node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x)
   Format Binary           : prisma-fmt 22b822189f46ef0dc5c5b503368d1bee01213980 (at ../.nvm/versions/node/v16.14.2/lib/node_modules/prisma/node_modules/@prisma/engines/prisma-fmt-debian-openssl-1.1.x)
   Default Engines Hash    : 22b822189f46ef0dc5c5b503368d1bee01213980
   Studio                  : 0.459.0

** Node / OS **

   Node : 16.14.2
   OS   : linux x64
   npm  : 8.6.0
   
** NX **
   nx : 13.9.7
   @nrwl/angular : 13.9.7
   @nrwl/cypress : 13.9.7
   @nrwl/detox : Not Found
   @nrwl/devkit : 13.9.7
   @nrwl/eslint-plugin-nx : 13.9.7
   @nrwl/express : Not Found
   @nrwl/jest : 13.9.7
   @nrwl/js : 13.9.7
   @nrwl/linter : 13.9.7
   @nrwl/nest : 13.9.7
   @nrwl/next : Not Found
   @nrwl/node : 13.9.7
   @nrwl/nx-cloud : Not Found
   @nrwl/nx-plugin : Not Found
   @nrwl/react : Not Found
   @nrwl/react-native : Not Found
   @nrwl/schematics : Not Found
   @nrwl/storybook : 13.9.7
   @nrwl/web : Not Found
   @nrwl/workspace : 13.9.7
   typescript : 4.5.5
   rxjs : 7.5.5

Hope this helps!

[Bug] Cannot find `fs.promises`

Dear team,

thanks a lot for this package. It seems very promising, and I would like to evaluate it for further usage. Unfortunately, I was not able to get it to run properly.

My Schema file looks like this (only important parts)

generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "linux-musl"]
}

generator nestjsDto {
  provider                        = "prisma-generator-nestjs-dto"
  output                          = "../src/generated/nestjs-dto"
  outputToNestJsResourceStructure = "false"
  exportRelationModifierClasses   = "true"
  reExport                        = "false"
  createDtoPrefix                 = "Create"
  updateDtoPrefix                 = "Update"
  dtoSuffix                       = "Dto"
  entityPrefix                    = ""
  entitySuffix                    = ""
  fileNamingStyle                 = "camel"
}

datasource db {
  provider = "postgresql"
  url      = env("DB_CONNECTION_STRING")
}

the error i get is like this:

> npx prisma generate

Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Error: Generator at prisma-generator-nestjs-dto could not start:

internal/modules/cjs/loader.js:883
  throw err;
  ^
Error: Cannot find module 'node:fs/promises'
Require stack:
- /home/x/projects/y/node_modules/@vegardit/prisma-generator-nestjs-dto/dist/index.js
- /home/x/projects/y/node_modules/@vegardit/prisma-generator-nestjs-dto/dist/cli.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
    at Function.Module._load (internal/modules/cjs/loader.js:725:27)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (/home/x/projects/y/node_modules/@vegardit/prisma-generator-nestjs-dto/dist/index.js:7:36)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/x/projects/y/node_modules/@vegardit/prisma-generator-nestjs-dto/dist/index.js',
    '/home/x/projects/y/node_modules/@vegardit/prisma-generator-nestjs-dto/dist/cli.js'
  ]
}

Am i missing something?
All the best,
Johannes

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.