Shared Zod schemas and Drizzle contract helpers — branded ID-aware select / insert / update schemas with auto-applied column refinements.
npm install @arki/contracts
# or
bun add @arki/contracts
# or
pnpm add @arki/contractsPeer-installs:
drizzle-ormzod(v4)zod-form-data
drizzle-zod's createSelectSchema walks Drizzle's dataType strings to infer Zod shapes. That mechanism loses three things:
- Branded ID types declared via
varchar('id').$type<\usr_${string}`>()collapse to plainstring`. jsonb('col').$type<Shape>()shapes collapse tounknown.- Runtime validation schemas stashed on a column by an ID-factory side-channel are not applied automatically.
@arki/contracts wraps drizzle-zod's factories so the output schema preserves the branded type and auto-applies any column-stashed runtime schema, with user-provided refines still winning.
import { z } from '@arki/contracts';
const Email = z.string().email();The package re-exports everything from zod/v4, so you do not need a direct zod import alongside it.
import { formData } from '@arki/contracts';
const schema = formData.zfd.formData({
name: formData.zfd.text(),
age: formData.zfd.numeric(),
});import { pgTable, varchar, jsonb } from 'drizzle-orm/pg-core';
import { createSelectSchema, createInsertSchema } from '@arki/contracts';
const users = pgTable('users', {
id: varchar('id').$type<`usr_${string}`>().primaryKey(),
email: varchar('email').notNull(),
profile: jsonb('profile').$type<{ displayName: string }>(),
});
const userSelect = createSelectSchema(users);
type User = z.infer<typeof userSelect>;
// { id: `usr_${string}`; email: string; profile: { displayName: string } | null }If an ID-factory stashed a Zod schema on a column via COLUMN_ZOD_SCHEMA, parsing rejects values with the wrong prefix:
userSelect.parse({ id: 'org_42', email: 'a@example.com', profile: null });
// throws: id must start with "usr_"User-provided refines override the auto-applied schema:
const strictSelect = createSelectSchema(users, {
email: schema => schema.email(),
});createSelectSchema(table, refine?)— branded select schema.createInsertSchema(table, refine?)— branded insert schema.createUpdateSchema(table, refine?)— every field optional, otherwise like insert.COLUMN_ZOD_SCHEMA—Symbol.for('@arki/contracts/columnZodSchema')side-channel for ID factories.bufferSchema,jsonSchema,literalSchema,createSchemaFactory— re-exported fromdrizzle-orm/zod.formData— re-exportedzod-form-datanamespace.z,ZodError, every Zod export — re-exported fromzod/v4.
@arki/contracts is framework-agnostic and works on its own. When you
compose it with the @arki/dot
application framework, see packages/dot/docs/ for plugin authoring,
lifecycle, and diagnostics.
MIT. See LICENSE.