skoshx / pentagon

Prisma-like ORM built on top of Deno KV. Allows you to write your database schemas and relations using Zod schemas, and run queries using familiar syntax from Prisma.
https://dash.deno.com/playground/pentagon-demo
MIT License
148 stars 4 forks source link

Add utilities for creating optional types #10

Open skoshx opened 1 year ago

skoshx commented 1 year ago

In the same way as in Prisma we have createdAt DateTime @default(now()),

we should have in Pentagon something along the lines of:

const User = z.object({
  createdAt: default(z.date(), () => new Date()),
  id: default(z.string(), () => crypto.randomUUID())
  // or
  createdAt: default(z.date(), "now"),
  id: default(z.string(), "uuid")
});
jnssnmrcs commented 1 year ago

This is easily achieved by making users of the lib use the .default function in zod when defining the schemas. That also gives user more flexibility on how they wanna set the default values for these fields:

const User = z.object({
  id: z.string().uuid().default(crypto.randomUUID),
  created: z
    .string()
    .datetime()
    .default(() => new Date().toISOString()),
});

or if they prefer to use timestamps:

const User = z.object({
  id: z.string().uuid().default(crypto.randomUUID),
  created: z
    .number()
    .int()
    .default(() => Date.now()),
});
skoshx commented 1 year ago

@jnssnmrcs Yeah you're completely right, thus it's marked as good first issue :D The reason we would want some wrapper function is that we would be able to get IntelliSense for instance for flags such as "primary key" and "indexed key" and "unique", because having describe("primary") isn't obvious if the end-user isn't familiar with how to use Pentagon

waptik commented 1 year ago

This is easily achieved by making users of the lib use the .default function in zod when defining the schemas. That also gives user more flexibility on how they wanna set the default values for these fields:

const User = z.object({
  id: z.string().uuid().default(crypto.randomUUID),
  created: z
    .string()
    .datetime()
    .default(() => new Date().toISOString()),
});

or if they prefer to use timestamps:

const User = z.object({
  id: z.string().uuid().default(crypto.randomUUID),
  created: z
    .number()
    .int()
    .default(() => Date.now()),
});

i don't if this is an existing solution or just an idea but as I'm using v0.1.1 so i'm leaving this here. Leem know if it doesn't belong here and i'll create a new issue about it.

I have this user table(as seen below), the enableOptions field value is undefined when it's left empty during creation instead of false.

export const User = z.object({
  id: z.number().describe("primary, unique"),
  username: z.string().describe("unique").optional(),
  firstName: z.string(),
  lastName: z.string().optional(),
  enableOptions: z.boolean().default(false).optional(),
  createdAt: z.date(),
  updatedAt: z.date().nullable(),
});
jnssnmrcs commented 1 year ago

This has been fixed in main branch but I don't think it has been released yet, so in the next release zod default values should work.

waptik commented 1 year ago

This has been fixed in main branch but I don't think it has been released yet, so in the next release zod default values should work.

Okay, thanks!

waptik commented 1 year ago

This is easily achieved by making users of the lib use the .default function in zod when defining the schemas. That also gives user more flexibility on how they wanna set the default values for these fields:

const User = z.object({
  id: z.string().uuid().default(crypto.randomUUID),
  created: z
    .string()
    .datetime()
    .default(() => new Date().toISOString()),
});

or if they prefer to use timestamps:

const User = z.object({
  id: z.string().uuid().default(crypto.randomUUID),
  created: z
    .number()
    .int()
    .default(() => Date.now()),
});

I don't know if the latest version implements this feature so i'm not sure if this error i'm getting is related image

UPDATE: I chnaged the code to default(() => crypto.randomUUID()) and it worked perfectly