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

[Feature Request] Ignore useless input types improve performances #260

Open
Spoutnik97 opened this issue Jun 25, 2024 · 2 comments
Open

Comments

@Spoutnik97
Copy link

For a simple schema.prisma :


model User {
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt @map("updated_at")
  id        String   @id @default(uuid()) @db.Uuid
  email     String   @unique
  name      String?
  posts     Post[]
}

model Post {
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt @map("updated_at")
  id        String   @id @default(uuid()) @db.Uuid
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  String
}

If I activate the createInputTypes option, my type file grows from ~50 lines to 1200 lines...
So with my real schema, it is more than 40 000 lines of codes. It takes more than 1 minutes to execute the tsc command for my package

I would like to add an option to choose only the CreateInputTypes (and maybe the UpdateInutTypes) ,but not all the CreateManyAndReturn, ConnectOrCreate, etc...

@drakedeatonuk
Copy link

My company's schema has nearly 100 database tables. The problem you're describing makes the library almost unusable in its current state at that scale.

It helps if the path you generate the validators into is gitignored, but we still notice significant performance issues with intellisense when the validators are being used.

In practice use less than 1% of the validators that are generated, so more specific controls around what & which validators are generated would be much more performant without compromising on its utility.

The potential of this library is off the charts though. It's solving something truly worthwhile imo.

@Spoutnik97
Copy link
Author

Spoutnik97 commented Nov 6, 2024

I bypassed the issue by creating a those functions :

import { z } from 'zod';

export const makeCreateInputSchema = <T extends z.ZodObject<any, any>>(
  schema: T,
): z.ZodObject<{
  [K in Exclude<
    keyof T['shape'],
    'id' | 'createdAt' | 'updatedAt'
  >]: T['shape'][K] extends z.ZodNullable<any>
    ? z.ZodOptional<Nullable<T['shape'][K]>>
    : T['shape'][K];
}> => {
  const cleanedSchema = excludeBasicFields(schema);

  return makeNullableFieldsOptional(cleanedSchema);
};


function excludeBasicFields<T extends z.ZodObject<any, any>>(
  schema: T,
): z.ZodObject<Omit<T['shape'], 'id' | 'createdAt' | 'updatedAt'>> {
  const { id: _, createdAt: __, updatedAt: ___, ...rest } = schema.shape;
  return z.object(rest) as z.ZodObject<
    Omit<T['shape'], 'id' | 'createdAt' | 'updatedAt'>
  >;
}


 type Nullable<T> = T extends z.ZodNullable<infer U> ? U : T;

function makeNullableFieldsOptional<T extends z.ZodObject<any, any>>(
  schema: T,
): z.ZodObject<{
  [K in keyof T['shape']]: T['shape'][K] extends z.ZodNullable<any>
    ? z.ZodOptional<Nullable<T['shape'][K]>>
    : T['shape'][K];
}> {
  const newShape = Object.entries(schema.shape).reduce((acc, [key, value]) => {
    if ((value as z.ZodTypeAny).isNullable()) {
      acc[key] = (value as z.ZodTypeAny).optional() as z.ZodTypeAny;
    } else {
      acc[key] = value as z.ZodTypeAny;
    }
    return acc;
  }, {} as { [key: string]: z.ZodTypeAny });

  return z.object(newShape) as z.ZodObject<{
    [K in keyof T['shape']]: T['shape'][K] extends z.ZodNullable<any>
      ? z.ZodOptional<Nullable<T['shape'][K]>>
      : T['shape'][K];
  }>;
}

the makeCreateInputSchema function create a new object without "id", "createdAt" and "updatedAt" fields (need to be customized for your project), then make all nullable fields optional, to avoid to give to the create function all the fields

Then it is used like that:

export const CreateMyOwnInputSchema = makeCreateInputSchema(
  MySchema.omit({
    clientId: true,
{{ YOUR_FIELDS_TO_EXCLUDE }}
  }))

I hope it could help you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants