0.0.3 • Published 5 months ago

sizuku v0.0.3

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

Sizuku

Sizuku is a tool that generates Valibot validation schemas and ER diagrams from commented Drizzle schemas.

Features

  • 💎 Automatically generates Zod schemas from your Drizzle schema
  • 🤖 Automatically generates Valibot schemas from your Drizzle schema
  • 📊 Creates Mermaid ER diagrams

Getting Started

Installation

npm install -D sizuku

Usage

Example

input:

import { sql } from 'drizzle-orm'
import { mysqlTable, varchar, timestamp, unique } from 'drizzle-orm/mysql-core'

export const user = mysqlTable('user', {
  /// Unique identifier for the user.
  /// @z.string().uuid()
  /// @v.pipe(v.string(), v.uuid())
  id: varchar('id', { length: 36 }).primaryKey(),
  /// Username of the user.
  /// @z.string()
  /// @v.string()
  username: varchar('username', { length: 255 }).notNull(),
  /// Email address of the user.
  /// @z.string().email()
  /// @v.pipe(v.string(), v.email())
  email: varchar('email', { length: 255 }).notNull().unique(),
  /// Password for the user.
  /// @z.string().min(8).max(100)
  /// @v.pipe(v.string(), v.minLength(8), v.maxLength(100))
  password: varchar('password', { length: 100 }).notNull(),
  /// Timestamp when the user was created.
  /// @z.date()
  /// @v.date()
  createdAt: timestamp('created_at', { mode: 'string' }).notNull().default(sql`CURRENT_TIMESTAMP`),
  /// Timestamp when the user was last updated.
  /// @z.date()
  /// @v.date()
  updatedAt: timestamp('updated_at', { mode: 'string' })
    .notNull()
    .default(sql`CURRENT_TIMESTAMP`)
    .$onUpdate(() => sql`CURRENT_TIMESTAMP`),
})

/// @relation user.id post.userId one-to-many
export const post = mysqlTable('post', {
  /// Unique identifier for the post.
  /// @z.string().uuid()
  /// @v.pipe(v.string(), v.uuid())
  id: varchar('id', { length: 36 }).primaryKey(),
  /// ID of the user who created the post.
  /// @z.string().uuid()
  /// @v.pipe(v.string(), v.uuid())
  userId: varchar('user_id', { length: 36 })
    .notNull()
    .references(() => user.id, { onDelete: 'cascade' }),
  /// Content of the post.
  /// @z.string()
  /// @v.string()
  content: varchar('content', { length: 500 }).notNull(),
  /// Timestamp when the post was created.
  /// @z.date()
  /// @v.date()
  createdAt: timestamp('created_at', { mode: 'string' }).notNull().default(sql`CURRENT_TIMESTAMP`),
  /// Timestamp when the post was last updated.
  /// @z.date()
  /// @v.date()
  updatedAt: timestamp('updated_at', { mode: 'string' })
    .notNull()
    .default(sql`CURRENT_TIMESTAMP`)
    .$onUpdate(() => sql`CURRENT_TIMESTAMP`),
})

/// @relation post.id likes.postId one-to-many
/// @relation user.id likes.userId one-to-many
export const likes = mysqlTable(
  'likes',
  {
    /// Unique identifier for the like.
    /// @z.string().uuid()
    /// @v.pipe(v.string(), v.uuid())
    id: varchar('id', { length: 36 }).primaryKey(),
    /// ID of the post that is liked.
    /// @z.string().uuid()
    /// @v.pipe(v.string(), v.uuid())
    postId: varchar('post_id', { length: 36 })
      .notNull()
      .references(() => post.id, { onDelete: 'cascade' }),
    /// ID of the user who liked the post.
    /// @z.string().uuid()
    /// @v.pipe(v.string(), v.uuid())
    userId: varchar('user_id', { length: 36 })
      .notNull()
      .references(() => user.id, { onDelete: 'cascade' }),
    /// Timestamp when the like was created.
    /// @z.date()
    /// @v.date()
    createdAt: timestamp('created_at', { mode: 'string' })
      .notNull()
      .default(sql`CURRENT_TIMESTAMP`),
  },
  (t) => [unique().on(t.userId, t.postId)],
)

Zod

npx sizuku-zod path/to/db/schema.ts -o path/to/output.ts

output:

import { z } from 'zod'

export const UserSchema = z.object({
  /**
   * Unique identifier for the user.
   */
  id: z.string().uuid(),
  /**
   * Username of the user.
   */
  username: z.string(),
  /**
   * Email address of the user.
   */
  email: z.string().email(),
  /**
   * Password for the user.
   */
  password: z.string().min(8).max(100),
  /**
   * Timestamp when the user was created.
   */
  createdAt: z.date(),
  /**
   * Timestamp when the user was last updated.
   */
  updatedAt: z.date(),
})

export const PostSchema = z.object({
  /**
   * Unique identifier for the post.
   */
  id: z.string().uuid(),
  /**
   * ID of the user who created the post.
   */
  userId: z.string().uuid(),
  /**
   * Content of the post.
   */
  content: z.string(),
  /**
   * Timestamp when the post was created.
   */
  createdAt: z.date(),
  /**
   * Timestamp when the post was last updated.
   */
  updatedAt: z.date(),
})

export const LikesSchema = z.object({
  /**
   * Unique identifier for the like.
   */
  id: z.string().uuid(),
  /**
   * ID of the post that is liked.
   */
  postId: z.string().uuid(),
  /**
   * ID of the user who liked the post.
   */
  userId: z.string().uuid(),
  /**
   * Timestamp when the like was created.
   */
  createdAt: z.date(),
})

Valibot

npx sizuku-valibot path/to/db/schema.ts -o path/to/output.ts

output:

import * as v from 'valibot'

export const UserSchema = v.object({
  /**
   * Unique identifier for the user.
   */
  id: v.pipe(v.string(), v.uuid()),
  /**
   * Username of the user.
   */
  username: v.string(),
  /**
   * Email address of the user.
   */
  email: v.pipe(v.string(), v.email()),
  /**
   * Password for the user.
   */
  password: v.pipe(v.string(), v.minLength(8), v.maxLength(100)),
  /**
   * Timestamp when the user was created.
   */
  createdAt: v.date(),
  /**
   * Timestamp when the user was last updated.
   */
  updatedAt: v.date(),
})

export const PostSchema = v.object({
  /**
   * Unique identifier for the post.
   */
  id: v.pipe(v.string(), v.uuid()),
  /**
   * ID of the user who created the post.
   */
  userId: v.pipe(v.string(), v.uuid()),
  /**
   * Content of the post.
   */
  content: v.string(),
  /**
   * Timestamp when the post was created.
   */
  createdAt: v.date(),
  /**
   * Timestamp when the post was last updated.
   */
  updatedAt: v.date(),
})

export const LikesSchema = v.object({
  /**
   * Unique identifier for the like.
   */
  id: v.pipe(v.string(), v.uuid()),
  /**
   * ID of the post that is liked.
   */
  postId: v.pipe(v.string(), v.uuid()),
  /**
   * ID of the user who liked the post.
   */
  userId: v.pipe(v.string(), v.uuid()),
  /**
   * Timestamp when the like was created.
   */
  createdAt: v.date(),
})

Mermaid ER

npx sizuku-mermaid-er path/to/db/schema.ts -o path/to/output.md

output:

erDiagram
    user ||--o{ post : "(id) - (userId)"
    post ||--o{ likes : "(id) - (postId)"
    user ||--o{ likes : "(id) - (userId)"
    user {
        varchar id "(PK) Unique identifier for the user."
        varchar username "Username of the user."
        varchar email "Email address of the user."
        varchar password "Password for the user."
        timestamp createdAt "Timestamp when the user was created."
        timestamp updatedAt "Timestamp when the user was last updated."
    }
    post {
        varchar id "(PK) Unique identifier for the post."
        varchar userId "(FK) ID of the user who created the post."
        varchar content "Content of the post."
        timestamp createdAt "Timestamp when the post was created."
        timestamp updatedAt "Timestamp when the post was last updated."
    }
    likes {
        varchar id "(PK) Unique identifier for the like."
        varchar postId "(FK) ID of the post that is liked."
        varchar userId "(FK) ID of the user who liked the post."
        timestamp createdAt "Timestamp when the like was created."
    }

Configuration

sizuku-zod.json

Schema Options

OptionTypeDefaultDescription
name"PascalCase" | "camelCase""PascalCase"Naming convention for generated schema variables
exportbooleanfalseWhen true, exports all schema definitions

Type Options

OptionTypeDefaultDescription
name"PascalCase" | "camelCase""PascalCase"Naming convention for generated type definitions
exportbooleanfalseWhen true, exports all type definitions

Comment Options

OptionTypeDefaultDescription
namebooleanfalseIf enabled, includes the element's original name in TSDoc comments.

Input and Output

OptionTypeDefaultDescription
inputstring""Input file path
outputstring""Output file path

Example

{
  "schema": {
    "name": "PascalCase"
  },
  "type": {
    "name": "PascalCase",
    "export": false
  },
  "comment": true,
  "input": "db/schema.ts",
  "output": "zod/index.ts"
}

⚠️ When using a configuration file, command line arguments are not required. The configuration file settings take precedence over command line arguments.

When you have configured sizuku-zod.json, you can simply run:

npx sizuku-zod

sizuku-valibot.json

Schema Options

OptionTypeDefaultDescription
name"PascalCase" | "camelCase""PascalCase"Naming convention for generated schema variables
exportbooleanfalseWhen true, exports all schema definitions

Type Options

OptionTypeDefaultDescription
name"PascalCase" | "camelCase""PascalCase"Naming convention for generated type definitions
exportbooleanfalseWhen true, exports all type definitions

Comment Options

OptionTypeDefaultDescription
namebooleanfalseIf enabled, includes the element's original name in TSDoc comments.

Input and Output

OptionTypeDefaultDescription
inputstring""Input file path
outputstring""Output file path

Examples

{
  "schema": {
    "name": "PascalCase"
  },
  "type": {
    "name": "PascalCase",
    "export": false
  },
  "comment": true,
  "input": "db/schema.ts",
  "output": "valibot/index.ts"
}

⚠️ When using a configuration file, command line arguments are not required. The configuration file settings take precedence over command line arguments.

When you have configured sizuku-valibot.json, you can simply run:

npx sizuku-valibot

sizuku-mermaid-er.json

OptionTypeDefaultDescription
inputstring""Input file path
outputstring""Output file path

Example

{
  "input": "db/schema.ts",
  "output": "mermaid-er/ER.md"
}

⚠️ When using a configuration file, command line arguments are not required. The configuration file settings take precedence over command line arguments.

When you have configured sizuku-mermaid-er.json, you can simply run:

npx sizuku-mermaid-er

This project is in early development and being maintained by a developer with about 2 years of experience. While I'm doing my best to create a useful tool:

⚠️ WARNING: Potential Breaking Changes Without Notice

**This package is in active development and may introduce breaking changes without prior notice.

License

Distributed under the MIT License. See LICENSE for more information.

0.0.3

5 months ago

0.0.2

5 months ago

0.0.1

5 months ago