Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Types broken on void clients (no models) #24182

Open
NBMSacha opened this issue May 14, 2024 · 3 comments
Open

Types broken on void clients (no models) #24182

NBMSacha opened this issue May 14, 2024 · 3 comments
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. team/client Issue for team Client. tech/typescript Issue for tech TypeScript. topic: client types Types in Prisma Client

Comments

@NBMSacha
Copy link

Bug description

Due to the change introduced yesterday by #24160, void clients can now be created (yay!!). However, they aren't complete typescript-wise. The prismaClient.$extends API will throw typescript errors when used.

How to reproduce

Expected behavior

No response

Prisma information

// Add your schema.prisma
// Add your code using Prisma Client

Environment & setup

  • OS:
  • Database:
  • Node.js version:

Prisma Version


@NBMSacha NBMSacha added the kind/bug A reported bug. label May 14, 2024
@janpio janpio added bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. team/client Issue for team Client. topic: client types Types in Prisma Client labels May 14, 2024
@jkomyno
Copy link
Contributor

jkomyno commented May 14, 2024

Hi @NBMSacha, can you please expand on this issue? Can you please paste the prismaClient.$extends API usage in which you see errors, and paste the error message as well?

I would also be beneficial if you please gave us more info for reproducing this, such as your Prisma schema. Thanks!

@jkomyno jkomyno added the tech/typescript Issue for tech TypeScript. label May 14, 2024
@NBMSacha
Copy link
Author

NBMSacha commented May 14, 2024

Sure!

Schema:

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

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

Usecase:

return prismaClient.$extends({
      query: {
        $allModels: {
          // @ts-expect-error too powerful to type
          async update({model, args, query}) {
            return await prismaClient.$transaction(async prisma => {
              // @ts-expect-error too powerful to type
              const previousData = await prisma[model].findUnique({
                where: args.where,
              });

              if (!previousData) {
                throw new Error(
                  'Record to update not found, did you want to upsert?',
                );
              }

              const result = await query(args);

              const queryUnsafe = `INSERT INTO octoflow_${this.streamName}.logs (data, operation, table) VALUES (?, ?, ?, ?, ?)`;
              await prisma.$queryRawUnsafe(
                queryUnsafe,
                previousData,
                1,
                model,
                this.blockNumber,
                this.blockchain,
              );

              return result;
            });
          },

          // @ts-expect-error too powerful to type
          async create({model, args, query}) {
            return await prismaClient.$transaction(async prisma => {
              const result = await this.create(args);

              const queryUnsafe = `INSERT INTO octoflow_${this.streamName}.logs (data, operation, table) VALUES (?, ?, ?, ?, ?)`;
              await prisma.$queryRawUnsafe(
                queryUnsafe,
                result,
                0,
                model,
                this.blockNumber,
                this.blockchain,
              );

              return result;
            });
          },

          // @ts-expect-error too powerful to type
          async delete({model, args, query}) {
            return await prismaClient.$transaction(async prisma => {
              // @ts-expect-error too powerful to type
              const previousData = await prisma[model].findUnique({
                where: args.where,
              });

              const result = await query(args);

              if (previousData !== undefined) {
                const queryUnsafe = `INSERT INTO octoflow_${this.streamName}.logs (data, operation, table) VALUES (?, ?, ?, ?, ?)`;
                await prisma.$queryRawUnsafe(
                  queryUnsafe,
                  previousData,
                  2,
                  model,
                  this.blockNumber,
                  this.blockchain,
                );
              }

              return !!result;
            });
          },

          // @ts-expect-error too powerful to type
          async upsert({model, args, query}) {
            return await prismaClient.$transaction(async prisma => {
              // @ts-expect-error too powerful to type
              const previousData = await prisma[model].findUnique({
                where: args.where,
              });

              if (previousData) {
                const result = await this.update(args);
                const queryUnsafe = `INSERT INTO octoflow_${this.streamName}.logs (data, operation, table) VALUES (?, ?, ?, ?, ?)`;
                await prisma.$queryRawUnsafe(
                  queryUnsafe,
                  previousData,
                  1,
                  model,
                  this.blockNumber,
                  this.blockchain,
                );
                return result;
              } else {
                const result = await this.create(args);
                const queryUnsafe = `INSERT INTO octoflow_${this.streamName}.logs (data, operation, table) VALUES (?, ?, ?, ?, ?)`;
                await prisma.$queryRawUnsafe(
                  queryUnsafe,
                  result,
                  0,
                  model,
                  this.blockNumber,
                  this.blockchain,
                );
                return result;
              }
            });
          },

          // @ts-expect-error too powerful to type
          async updateMany({model, args, query}) {
            return await prismaClient.$transaction(async prisma => {
              // @ts-expect-error too powerful to type
              const previousData = await prisma[model].findMany({
                where: args.where,
              });

              const result = await query(args);

              if (previousData.length > 0) {
                const queryUnsafe = `INSERT INTO octoflow_${this.streamName}.logs (data, operation, table) VALUES (?, ?, ?, ?, ?)`;
                await prisma.$queryRawUnsafe(
                  queryUnsafe,
                  previousData,
                  1,
                  model,
                  this.blockNumber,
                  this.blockchain,
                );
              }

              return result;
            });
          },

          // @ts-expect-error too powerful to type
          async createMany({model, args, query}) {
            return await prismaClient.$transaction(async prisma => {
              const result = await query(args);

              const queryUnsafe = `INSERT INTO octoflow_${this.streamName}.logs (data, operation, table) VALUES (?, ?, ?, ?, ?)`;
              await prisma.$queryRawUnsafe(
                queryUnsafe,
                result,
                0,
                model,
                this.blockNumber,
                this.blockchain,
              );

              return result;
            });
          },

          // @ts-expect-error too powerful to type
          async deleteMany({model, args, query}) {
            return await prismaClient.$transaction(async prisma => {
              // @ts-expect-error too powerful to type
              const previousData = await prisma[model].findMany({
                where: args.where,
              });

              const result = await query(args);

              if (previousData.length > 0) {
                const queryUnsafe = `INSERT INTO octoflow_${this.streamName}.logs (data, operation, table) VALUES (?, ?, ?, ?, ?)`;
                await prisma.$queryRawUnsafe(
                  queryUnsafe,
                  previousData,
                  2,
                  model,
                  this.blockNumber,
                  this.blockchain,
                );
              }

              return result;
            });
          },
        },
      },
    });

Without the "ts-expect-error" flag, we're getting an issue claiming that "update" and all the other methods shouldn't be there!

@Weakky Weakky changed the title Types broken on void clients Types broken on void clients (no models) May 16, 2024
@MangMax
Copy link

MangMax commented May 22, 2024

I have the same problem, typescript doesn't work anymore!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. team/client Issue for team Client. tech/typescript Issue for tech TypeScript. topic: client types Types in Prisma Client
Projects
None yet
Development

No branches or pull requests

4 participants