Skip to content

Instantly share code, notes, and snippets.

@nandorojo
Last active November 12, 2024 17:43
Show Gist options
  • Save nandorojo/c61a27c8821e11ed137cc2cbda553231 to your computer and use it in GitHub Desktop.
Save nandorojo/c61a27c8821e11ed137cc2cbda553231 to your computer and use it in GitHub Desktop.
Drizzle Zod Inserts & Selects from Schema Generator

Drizzle + Zod Helpers

If you want a really nice API for your drizzle PG tables from Zod, such as:

import { inserts, select, enums } from './drizzle-zod-helpers'

const userType = enums.UserType.parse('admin')

// construct a type-safe insert
const userInsert = inserts.user.parse({
  ...user
})

const userSelect = selects.user.parse({
  ...user
})

// construct type-safe insert functions
async function createUser(user: Zod.infer<typeof inserts.user>) {
  return await db.insert(schema.users).values(user).execute()
}

Installation

Be sure to install drizzle-zod (and zod)

yarn add drizzle-zod zod

Next, copy the TypeScript file from this Gist into your repo. Be sure to change the first line to point to your schema file.

import * as schema from './schema' // make this point to your schema file
import { PgEnum, PgTableWithColumns } from 'drizzle-orm/pg-core'
import { createInsertSchema, createSelectSchema } from 'drizzle-zod'
import { z } from 'zod'
type ExtractPgTableKeys<T> = {
[K in keyof T]: T[K] extends PgTableWithColumns<any> ? K : never
}[keyof T]
export const selects = Object.fromEntries(
Object.entries(schema)
.map(([key, table]) =>
'$inferSelect' in table
? [
key,
createSelectSchema(table as any)
.strict()
.describe(`Fields for ${key}.`),
]
: null
)
.filter(Boolean) as any
) as {
[key in ExtractPgTableKeys<typeof schema>]: ReturnType<
typeof createSelectSchema<(typeof schema)[key]>
>
}
export const inserts = Object.fromEntries(
Object.entries(schema)
.map(([key, table]) =>
'$inferInsert' in table
? [
key,
createInsertSchema(table as any)
.describe(`Insert for ${key}.`)
.strict(),
]
: null
)
.filter(Boolean) as any
) as {
[key in ExtractPgTableKeys<typeof schema>]: ReturnType<
typeof createInsertSchema<(typeof schema)[key]>
>
}
export const enums = Object.fromEntries(
Object.entries(schema)
.map(([key, enums]) => ('enumValues' in enums ? [key, z.enum(enums.enumValues)] : null))
.filter(Boolean) as any
) as {
[key in ExtractPgEnumKeys<typeof schema>]: Zod.ZodEnum<(typeof schema)[key]['enumValues']>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment