0.5.2 • Published 4 months ago

drizzle-zero v0.5.2

Weekly downloads
-
License
Unlicense
Repository
github
Last release
4 months ago

drizzle-zero

Generate Zero schemas from Drizzle ORM schemas.

Installation

npm install drizzle-zero
# or
yarn add drizzle-zero
# or
pnpm add drizzle-zero

Usage

Here's an example of how to convert a Drizzle schema to a Zero schema with bidirectional relationships:

import { relations } from "drizzle-orm";
import { pgTable, text, jsonb } from "drizzle-orm/pg-core";

export const users = pgTable("user", {
  id: text("id").primaryKey(),
  name: text("name"),
});

export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
}));

export const posts = pgTable("post", {
  id: text("id").primaryKey(),
  // this JSON type will be passed to Zero
  content: jsonb("content").$type<{ textValue: string }>().notNull(),
  authorId: text("author_id").references(() => users.id),
});

export const postsRelations = relations(posts, ({ one }) => ({
  author: one(users, {
    fields: [posts.authorId],
    references: [users.id],
  }),
}));

Convert this Drizzle schema to a Zero schema:

import { createZeroSchema } from "drizzle-zero";
import * as drizzleSchema from "./drizzle-schema";

// Convert to Zero schema
export const schema = createZeroSchema(drizzleSchema, {
  // The version of the schema passed to Zero.
  version: 1,

  // Specify the casing style to use for the schema.
  // This is useful for when you want to use a different casing style than the default.
  // This works in the same way as the `casing` option in the Drizzle ORM.
  //
  // @example
  // casing: "snake_case",

  // Specify which tables and columns to include in the Zero schema.
  // This allows for the "expand/migrate/contract" pattern recommended in the Zero docs.
  // When a column is first added, it should be set to false, and then changed to true
  // once the migration has been run.

  // All tables/columns must be defined, but can be set to false to exclude them from the Zero schema.
  // Column names match your Drizzle schema definitions
  tables: {
    // this can be set to false
    // e.g. user: false,
    users: {
      id: true,
      name: true,
    },
    posts: {
      // or this can be set to false
      // e.g. id: false,
      id: true,
      content: true,
      // Use the JavaScript field name (authorId), not the DB column name (author_id)
      authorId: true,
    },
  },
});

// Define permissions with the inferred types from Drizzle
type Schema = typeof schema;
type User = Row<typeof schema.tables.users>;

export const permissions = definePermissions<{}, Schema>(schema, () => {
  // ...further permissions definitions
});

Use the generated Zero schema:

import { useQuery, useZero } from "@rocicorp/zero/react";

function PostList() {
  const z = useZero();

  // Build a query for posts with their authors
  const postsQuery = z.query.post.related("author").limit(10);

  const [posts] = useQuery(postsQuery);

  return (
    <div>
      {posts.map((post) => (
        <div key={post.id} className="post">
          {/* Access the JSON content from Drizzle */}
          <p>{post.content.textValue}</p>
          <p>By: {post.author?.name}</p>
        </div>
      ))}
    </div>
  );
}

Many-to-Many Relationships

drizzle-zero supports many-to-many relationships with a junction table. You can configure them in two ways:

Simple Configuration

export const schema = createZeroSchema(drizzleSchema, {
  version: 1,
  tables: {
    user: {
      id: true,
      name: true,
    },
    usersToGroup: {
      userId: true,
      groupId: true,
    },
    group: {
      id: true,
      name: true,
    },
  },
  manyToMany: {
    user: {
      // Simple format: [junction table, target table]
      // Do not use the same name as any existing relationships
      groups: ["usersToGroup", "group"],
    },
  },
});

Then query as usual, skipping the junction table:

const userQuery = z.query.user.where("id", "=", "1").related("groups").one();

const [user] = useQuery(userQuery);

console.log(user);
// {
//   id: "user_1",
//   name: "User 1",
//   groups: [
//     { id: "group_1", name: "Group 1" },
//     { id: "group_2", name: "Group 2" },
//   ],
// }

Extended Configuration

For more complex scenarios like self-referential relationships:

export const schema = createZeroSchema(drizzleSchema, {
  version: 1,
  tables: {
    user: {
      id: true,
      name: true,
    },
    friendship: {
      requestingId: true,
      acceptingId: true,
    },
  },
  manyToMany: {
    user: {
      // Extended format with explicit field mappings
      friends: [
        {
          sourceField: ["id"],
          destTable: "friendship",
          destField: ["requestingId"],
        },
        {
          sourceField: ["acceptingId"],
          destTable: "user",
          destField: ["id"],
        },
      ],
    },
  },
});

Features

  • Convert Drizzle ORM schemas to Zero schemas
    • Sync a subset of tables and columns
  • Handles all Drizzle column types that are supported by Zero
  • Type-safe schema generation with inferred types from Drizzle
  • Supports relationships:
    • One-to-one relationships
    • One-to-many relationships
    • Many-to-many relationships with simple or extended configuration
    • Self-referential relationships
  • Handles custom schemas and column mappings

License

Unlicense

0.5.2

4 months ago

0.5.1

5 months ago

0.4.1-rc.0

5 months ago

0.4.1-rc.5

5 months ago

0.4.1-rc.6

5 months ago

0.4.1-rc.3

5 months ago

0.4.1-rc.4

5 months ago

0.4.1-rc.1

5 months ago

0.4.1-rc.2

5 months ago

0.5.0

5 months ago

0.4.0

5 months ago

0.3.1

5 months ago

0.3.0

6 months ago

0.2.3

6 months ago

0.2.4

6 months ago

0.2.1

6 months ago

0.2.2

6 months ago

0.2.0

6 months ago

0.1.10

6 months ago

0.1.9

6 months ago

0.1.8

6 months ago

0.1.7

6 months ago

0.1.6

6 months ago

0.1.5

6 months ago

0.1.0

6 months ago

0.1.2

6 months ago

0.1.1

6 months ago

0.1.4

6 months ago

0.1.3

6 months ago

0.0.2-beta.3

7 months ago

0.0.2-beta.2

7 months ago

0.0.2-beta.1

7 months ago

0.0.1

7 months ago

0.0.1-alpha.4

7 months ago

0.0.1-alpha.3

7 months ago

0.0.1-alpha.2

7 months ago

0.0.1-alpha.1

7 months ago