Skip to content

Demon-Die/schema-cast

Repository files navigation

schema-cast

One schema. Four outputs. Zero drift.

npm version License: MIT TypeScript Build PRs Welcome

Define your data model once in JSON or YAML — schema-cast generates TypeScript types, Zod validators, Mongoose models, and PostgreSQL SQL, all kept in sync automatically.

Getting Started · CLI Reference · Field Types · Contributing


The Problem

In a typical fullstack project, the same data shape is written four separate times:

User interface → TypeScript
Request validation → Zod
Database model → Mongoose
Table definition → SQL

They drift. They conflict. You update one and forget the rest. schema-cast solves this with a single source of truth.


What It Generates

Given one .schema.json file, schema-cast produces:

Output File Description
TypeScript user.types.ts Interfaces and type definitions
Zod user.zod.ts Runtime validation schema
Mongoose user.model.ts MongoDB model with schema
PostgreSQL user.sql CREATE TABLE statement

Installation

# Global install (recommended for CLI use)
npm install -g schema-cast

# Or use without installing
npx schema-cast generate --input ./schemas/user.schema.json --out ./generated

Quick Start

1. Define Your Schema

Create a user.schema.json file:

{
  "name": "User",
  "fields": [
    { "name": "id",        "type": "uuid",   "required": true, "primary": true },
    { "name": "email",     "type": "email",  "required": true, "unique": true },
    { "name": "age",       "type": "number", "required": false },
    { "name": "role",      "type": "enum",   "values": ["admin", "user", "guest"], "default": "user" },
    { "name": "createdAt", "type": "date",   "required": true },
    { "name": "profile",   "type": "object", "fields": [
      { "name": "bio",    "type": "string" },
      { "name": "avatar", "type": "url" }
    ]}
  ]
}

2. Generate

schema-cast generate --input ./schemas/user.schema.json --out ./generated

3. Use the Output

Four files land in ./generated/:

user.types.ts — TypeScript interface
export interface User {
  id: string;
  email: string;
  age?: number;
  role: 'admin' | 'user' | 'guest';
  createdAt: Date;
  profile?: {
    bio?: string;
    avatar?: string;
  };
}
user.zod.ts — Zod validation schema
import { z } from 'zod';

export const UserSchema = z.object({
  id:        z.string().uuid(),
  email:     z.string().email(),
  age:       z.number().optional(),
  role:      z.enum(['admin', 'user', 'guest']).default('user'),
  createdAt: z.date(),
  profile: z.object({
    bio:    z.string().optional(),
    avatar: z.string().url().optional(),
  }).optional(),
});

export type User = z.infer<typeof UserSchema>;
user.model.ts — Mongoose model
import { Schema, model } from 'mongoose';

const UserSchema = new Schema({
  email:     { type: String, required: true, unique: true },
  age:       { type: Number },
  role:      { type: String, enum: ['admin', 'user', 'guest'], default: 'user' },
  createdAt: { type: Date, required: true },
  profile: {
    bio:    { type: String },
    avatar: { type: String },
  },
});

export const UserModel = model('User', UserSchema);
user.sql — PostgreSQL CREATE TABLE
CREATE TABLE users (
  id         UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email      VARCHAR NOT NULL UNIQUE,
  age        INTEGER,
  role       VARCHAR CHECK (role IN ('admin', 'user', 'guest')) DEFAULT 'user',
  created_at TIMESTAMP NOT NULL,
  profile    JSONB
);

CLI

generate — Generate from one or all schemas

# Single file
schema-cast generate --input ./schemas/user.schema.json --out ./generated

# Entire directory
schema-cast generate --all --input ./schemas/ --out ./generated
Flag Description
--input Path to a .schema.json / .schema.yaml file or directory
--out Output directory for generated files
--all Process all schema files in the input directory

watch — Auto-regenerate on change

schema-cast watch --input ./schemas/

Only regenerates files whose schema changed — fast and non-destructive.


Supported Field Types

Type TypeScript Zod Mongoose PostgreSQL
string string z.string() String VARCHAR
number number z.number() Number NUMERIC
boolean boolean z.boolean() Boolean BOOLEAN
date Date z.date() Date TIMESTAMP
uuid string z.string().uuid() String UUID
email string z.string().email() String VARCHAR
url string z.string().url() String VARCHAR
enum 'a' | 'b' z.enum([...]) { enum: [...] } CHECK (col IN (...))
object { ... } z.object({...}) Nested schema JSONB
array T[] z.array(...) [{ type: T }] JSONB

Field Options

Option Type Description
required boolean Whether the field must be present (default: false)
unique boolean Enforce unique constraint (Mongoose + PostgreSQL)
primary boolean Mark as primary key — _id in Mongoose, PRIMARY KEY in SQL
default any Default value applied across all outputs
values string[] Enum values — required when type is "enum"
fields FieldDefinition[] Nested fields — required when type is "object"
items FieldDefinition Item type — required when type is "array"

YAML Support

YAML schemas are supported alongside JSON:

name: Post
fields:
  - name: title
    type: string
    required: true
  - name: tags
    type: array
    items:
      type: string
  - name: status
    type: enum
    values: [draft, published, archived]
    default: draft

Project Structure

schema-bridge/
├── src/
│   ├── index.ts              # Public API entry point
│   ├── parser.ts             # JSON / YAML schema parser
│   ├── generators/
│   │   ├── typescript.ts     # TypeScript interface generator
│   │   ├── zod.ts            # Zod schema generator
│   │   ├── mongoose.ts       # Mongoose model generator
│   │   └── postgres.ts       # SQL CREATE TABLE generator
│   ├── cli.ts                # CLI entry point (commander.js)
│   └── watcher.ts            # Watch mode (chokidar)
└── tests/
    └── generators.test.ts

Contributing

Contributions are welcome. DemonDie is an open source community — if you're building with React, Next.js, Node.js, or any modern web stack, this tool is for you.

git clone https://github.com/Demon-Die/schema-bridge.git
cd schema-bridge
npm install
npm run dev

To run tests:

npm test

Please open an issue before submitting large PRs. See CONTRIBUTING.md for guidelines.


Built by DemonDie

schema-cast is part of the DemonDie open source ecosystem — a community building developer tools, web applications, AI/ML solutions, and community platforms.


License

MIT © DemonDie

About

Define your data once. schema-forge generates TypeScript, Zod, Mongoose, and PostgreSQL from a single schema file.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors