Skip to content

Support drizzle-zod-generated schemas #607

Open
@jacksonthall22

Description

@jacksonthall22

Is your feature request related to a problem? Please describe.

Edit: Maybe I have the whole idea of this wrong, let me know...

I want to be able to use a table schema that I can get from drizzle-zod (or maybe use it to define a partial schemas as needed for the route's form) instead of having to define my schema in a bunch of different routes:

src/routes/+page.server.ts:

import { getOrCreateUserProfile } from '$lib/auth/index.server'
import { profileTableUpdateSchema } from '$lib/db/schema.js'
import { error } from '@sveltejs/kit'
import { superValidate } from 'sveltekit-superforms'
import { zod } from 'sveltekit-superforms/adapters'
import type { PageServerLoad } from './$types'
// import { z } from 'zod' 

// --- I want to get rid of this! ---
// const schema = z.object({
//   firstName: z.string(),
//   lastName: z.string(),
// })

// I don't want to define the schema again when I can already get it with `drizzle-zod` (see my `schema.ts`):
const schema = profileTableUpdateSchema

export const load: PageServerLoad = async ({ locals }) => {
  // Supabase auth stuff
  let userSession = await locals.safeGetSession()
  let userData
  if (userSession.session) {
    userData = await getOrCreateUserProfile(locals)
  } else {
    userData = undefined
  }

  const form = await superValidate(userData ?? {}, zod(schema))
  //                                                   ^^^^^^
  // I'm getting a red line with this error:
  /*
  Argument of type 'BuildSchema<"update", { id: PgColumn<{ name: "id"; tableName: "profile"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: false; isPrimaryKey: true; isAutoincrement: false; ... 4 more ...; generated: undefined; }, {}, {}>; firstName: PgColumn<...>; lastName: PgC...' is not assignable to parameter of type 'ZodObjectType'.
  Type 'ZodObject<{ id: ZodOptional<ZodUUID>; firstName: ZodOptional<ZodString>; lastName: ZodOptional<ZodString>; }, { ...; }>' is missing the following properties from type 'ZodType<Record<string, unknown>, ZodTypeDef, Record<string, unknown> | undefined>': _type, _parse, _getType, _getOrReturnCtx, and 7 more.ts(2345)
  */
  // Could be some easy fix for this where I just need to transform `profileTableUpdateSchema` in a different way to be accepted by `zod()`?

  if (!form.valid) throw error(500, { message: 'Failed to initialize form' })
  return { form }
}

src/lib/db/schema.ts:

import { pgTable, text, uuid } from 'drizzle-orm/pg-core'
import { createSelectSchema, createUpdateSchema, createInsertSchema } from 'drizzle-zod'

export const profileTable = pgTable('profile', {
  id: uuid('id').primaryKey(),
  firstName: text('first_name').notNull(),
  lastName: text('last_name').notNull(),
})

export const profileTableSelectSchema = createSelectSchema(profileTable)
export const profileTableUpdateSchema = createUpdateSchema(profileTable)
export const profileTableInsertSchema = createInsertSchema(profileTable)

Describe the solution you'd like
I'm not sure if it's helpful, but this pattern also exists - not sure if supporting this could be as simple as exporting the z instance so I could bind to it:

import { pgTable, text, uuid } from 'drizzle-orm/pg-core'
import { createSchemaFactory } from 'drizzle-zod'
import { z } from 'zod'

export const { createSelectSchema, createInsertSchema, createUpdateSchema } = createSchemaFactory({
  zodInstance: z,
})

export const profileTable = pgTable('profile', {
  id: uuid('id').primaryKey(),
  firstName: text('first_name').notNull(),
  lastName: text('last_name').notNull(),
})

export const profileTableSelectSchema = createSelectSchema(profileTable)
export const profileTableUpdateSchema = createUpdateSchema(profileTable)
export const profileTableInsertSchema = createInsertSchema(profileTable)

Describe alternatives you've considered
The alternative is defining schema separately for SuperForms in multiple routes - that means that if one column type in my table changes and I have multiple routes with a form that sets that column, then multiple schema definitions need to be updated.

Additional context
I'm building this starter app: https://github.com/jacksonthall22/sveltekit-supabase

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestquestionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions