Closed Lotfi-Arif closed 8 months ago
As you know, the 1st principle of typia
and nestia
is not to writing any extra schema like intro page.
It's not a matter to find the best way by yourself, but I don't want to do it, prohibiting the 1st principle \o/.
By the way, if you want to utilize the original type of Prisma, then just use it directly. It is the pure TypeScript type. Also, even when using the zod
schema, you can still utilize it through Infer
feature of the zod
, because it is also the pure TypeScript type. Furthermore, if you turn on the clone
mode of SDK generator, you can clone pure interface DTO types from them.
Yes i understand the principles of nestia which is why i am using it but i did not expect for prisma and zod schema types not to work, Here is some specific details on what i am going through:
I am using Prisma for ORM, and Zod for data validation. I've run into a problem where Nestia fails to recognize and use types when they are either generated by Prisma or inferred from Zod schemas for the Swagger documentation. However, it works correctly when I define the types manually in TypeScript.
When I define a type manually in TypeScript, Nestia successfully generates the Swagger documentation:
export type User = {
id: number;
email: string;
password: string;
name: string | null;
createdAt: Date;
updatedAt: Date;
};
@TypedRoute.Post()
create(@TypedBody() createUserDto: Prisma.UserCreateInput): Promise<User> {
return this.userService.create(createUserDto);
}
When using Zod to define a schema and then inferring the TypeScript type from it, Nestia fails to generate the Swagger documentation:
import * as z from 'zod';
export const userSchema = z.object({
id: z.number(),
email: z.string(),
password: z.string(),
name: z.string().nullable(),
createdAt: z.date(),
updatedAt: z.date(),
});
export type User = z.infer<typeof userSchema>;
@TypedRoute.Post()
create(@TypedBody() createUserDto: Prisma.UserCreateInput): Promise<User> {
return this.userService.create(createUserDto);
}
Similarly, when using types generated by Prisma, Nestia also fails to generate the Swagger documentation:
import { Prisma, User } from '@prisma/client';
// Example Prisma-generated User Model:
export type User = $Result.DefaultSelection<Prisma.$UserPayload>
// ...other properties...
@TypedRoute.Post()
create(@TypedBody() createUserDto: Prisma.UserCreateInput): Promise<User> {
return this.userService.create(createUserDto);
}
Analyzing source codes
-----------------------------------------------------------
Nestia Error Report
-----------------------------------------------------------
src/user/user.controller.ts - UserController.create()
- implicit (unnamed) return type.
src/user/user.controller.ts - UserController.update()
- implicit (unnamed) return type.
src/user/user.controller.ts - UserController.remove()
- implicit (unnamed) return type.
Warning: run-commands command "npx nestia swagger" exited with non-zero status code
Set Up NestJS with Nestia, Prisma, and Zod: Create a NestJS project, integrating Nestia for Swagger documentation, Prisma for ORM, and Zod for validation.
Define Models and Validation: Define data models using Prisma and validation schemas using Zod. Infer TypeScript types from Zod schemas.
Implement Controllers with Different Type Definitions: Implement the controllers using:
Generate Swagger Documentation: Run the Nestia Swagger generation command.
Observe the Difference in Behavior: Note that Nestia successfully generates documentation for manually defined types but fails for types from Zod or Prisma.
Make me a reproducible repo, then I will test.
I can give you a repo now which i am working on to learn nestia: https://github.com/Lotfi-Arif/TradeTrove
It is just a trick, change like below, then it works.
As type X = Y
statement means an alias type definition, your type User = z.infer<typeof userSchema>
statement means that always copying and pasting the z.infer<typeof userSchema>
type statement everywhere the type User
being utilized. If you change it to a new interface
statement, the problem being solved.
The
z.infer
is also an alias type of implicit type of TMP. So it is blocked.The reason why blocking the implicit type is for the SDK purpose (client developer needs explicit type definition)
export interface User extends z.infer<typeof userSchema> {}
Oh i am guessing it is the same case for prisma generated types. I think i understand the solution, Thanks for the help!
Question
Hello, I'm currently working on a NestJS project that utilizes Prisma Client for ORM and Zod for data validation. I've been trying to integrate Nestia for Swagger documentation generation, but I'm facing challenges with Nestia's ability to detect and use types generated by Prisma Client and schemas inferred by Zod. I was wondering if there's a recommended approach or existing solution to integrate these effectively with Nestia's Swagger documentation generation.
Detailed Explanation
In my project, models are defined using Prisma Client and validated with Zod. However, the Swagger documentation generated by Nestia doesn't accurately reflect these types. When I switch to native TypeScript types defined manually, Nestia generates the documentation correctly.
I'm particularly interested in:
Context
This issue is significant for our project, as we rely on Prisma Client for ORM and Zod for validation. While native TypeScript types are a workaround, they don't offer the same level of convenience and functionality as the generated types from Prisma and Zod. We're seeking a more streamlined approach that allows for seamless integration.
Additional Information
Any insights, advice, or resources on this matter would be greatly appreciated. If more information or specific examples from our codebase are needed to better understand the issue, I'd be happy to provide them.
Thank you for your time and support in addressing this query.