tsedio / tsed

:triangular_ruler: Ts.ED is a Node.js and TypeScript framework on top of Express to write your application with TypeScript (or ES6). It provides a lot of decorators and guideline to make your code more readable and less error-prone. ⭐️ Star to support our work!
https://tsed.io/
MIT License
2.86k stars 284 forks source link

[BUG] Serialization over a data generated by prisma #2415

Open victorsmits opened 1 year ago

victorsmits commented 1 year ago

The response serialization is not working when you get data through the generated prisma repository but work as expected when you pass by the prisma service

Information

A few sentences describing the overall goals of the issue.

Example with prisma repository

export class ProfilePlayerModel {
  @Property()
  playerFirstName: string;

  @Property()
  playerID: number;

  @Property()
  playerLastName: string;
}

export class ProfileModel {
  @Property()
  DiscordId: string;

  @Property()
  SteamId: string;

  @Property()
  DiscordName: string;

  @CollectionOf(() => ProfilePlayerModel)
  @ForwardGroups()
  player: ProfilePlayerModel;
}

@Controller('/profile')
@UseBefore(JwtMiddleware)
export class ProfileController {
  @Inject()
  protected account: AccountsRepository;

  @Inject()
  protected players: PlayersRepository;

  @Get('/')
  @Returns(200, ProfileModel)
  async getProfile(@Req() req: Req) {
    const player = await this.players.findFirst({
      where: {
        active: 1,
        archived: false,
      },
      include: {},
    });

    return {
      ...req.user,
      player: player,
    };
  }
}

response

{
    "DiscordId": "543046299826520074",
    "SteamId": "1100001062b26b4",
    "DiscordName": "VictorSmits",
    "player": {
        "playerID": 1,
        "steamID": "11000013d4ab95d",
        "active": 1,
        "playerLastName": "Light",
        "playerFirstName": "Ryan",
        "playerBirthYear": 1985,
        "playerBirthMonth": 12,
        "playerBirthDay": 26,
        "playerGender": "Homme",
        "playerFatherFace": 0,
        "playerMotherFace": 0,
        "playerHeredityHead": 0,
        "playerHeredityBody": 0,
        "playerHairStyle": 3,
        "playerHairColor": 8,
        "playerHairHighlightColor": 29,
        "playerEyebrowsStyle": 0,
        "playerEyebrowsColor": 0,
        "playerEyesColor": 0,
        "playerBeardStyle": 15,
        "playerBeardColor": 3,
        "playerAgeingStyle": 16,
        "playerChestHairStyle": 255,
        "playerChestHairColor": 0,
        "makeUpStyle": 255,
        "makeUpType": 0,
        "makeUpColor1": 0,
        "makeUpColor2": 0,
        "paintStyle": 255,
        "paintType": 0,
        "paintColor1": 0,
        "paintColor2": 0,
        "lipStyle": 255,
        "lipType": 0,
        "lipColor1": 0,
        "lipColor2": 0,
        "stain6Style": 255,
        "stain7Style": 255,
        "stain9Style": 255,
        "stain0Style": 255,
        "stain11Style": 255,
        "archived": false,
        "createDate": "2021-04-28T13:19:54.000Z",
        "updated_at": "2021-04-28T13:19:54.000Z"
    }
}

Example with prisma service

export class ProfilePlayerModel {
  @Property()
  playerFirstName: string;

  @Property()
  playerID: number;

  @Property()
  playerLastName: string;
}

export class ProfileModel {
  @Property()
  DiscordId: string;

  @Property()
  SteamId: string;

  @Property()
  DiscordName: string;

  @Property()
  @ForwardGroups()
  player: ProfilePlayerModel;
}

@Controller('/profile')
@UseBefore(JwtMiddleware)
export class ProfileController {
  @Inject()
  protected prisma: PrismaService;

  @Get('/')
  @Returns(200, ProfileModel)
  async getProfile(@Req() req: Req) {
    const player = await this.prisma.players.findFirst({
      where: {
        active: 1,
        archived: false,
      },
      include: {},
    });

    return {
      ...req.user,
      player,
    };
  }
}

response

{
    "DiscordId": "543046299826520074",
    "SteamId": "1100001062b26b4",
    "DiscordName": "VictorSmits",
    "player": {
        "playerFirstName": "Ryan",
        "playerID": 1,
        "playerLastName": "Light"
    }
}
Romakita commented 1 year ago
victorsmits commented 1 year ago

Hello I have update my project to the latest version and now I have an other issue it seams that the repositories are not instantiate and thus its impossible to call them.

"TypeError: Cannot read properties of undefined (reading 'findMany')\n" + ' at MessengerGroupsRepository.findMany (C:\Users\victo\Documents\21JumpClick\tablet-api\node_modules\@tsed\prisma\lib\cjs\.schema\repositories\MessengerGroupsRepository.js:37:43)\n' + ' at MessengerController.getGroup (C:\Users\victo\Documents\21JumpClick\tablet-api\src\controllers\rest\messenger.controller.ts:74:32)\n' + ' at C:\Users\victo\Documents\21JumpClick\tablet-api\node_modules\@tsed\platform-params\src\builder\PlatformParams.ts:57:36'

Romakita commented 1 year ago

@victorsmits are you sure you have updated all dependencies correctly? Because I haven’t deployed fix on prisma. There is no change.

victorsmits commented 1 year ago

Yes all my dependencies are up to date.

image

Romakita commented 1 year ago

I suggest you to create repository to reproduce the issue. Also can bump your packages progressively to find the version responsible to your issue. see you

Romakita commented 1 year ago

All works for me: https://github.com/tsedio/tsed-example-prisma

DB start and serialization works. But I haven't tested your specific use case. I'll try to create the same case.

Romakita commented 1 year ago

Note: Problem around the prisma schema when the table name is on snake case format

yaratavares commented 2 months ago

I encountered the same problem when dealing with models in snake_case. In my case, I was able to resolve the issue by using the @@map attribute in Prisma, which allowed me to utilize the repositories generated. I mapped my model example_table to exampleTable as follows:

model exampleTable {
    id            Int        @id @default(autoincrement())
    uid           String     @unique @default(uuid())
    created_at    DateTime   @default(now())
    updated_at    DateTime   @updatedAt
    method        Method

    @@map("example_table")
}

This approach allowed me to keep the snake_case table name while using a camelCase model name.