Go to file
Betterlol b223091d47
MoonZod CI / build-and-test (ubuntu-latest) (push) Failing after 55s Details
MoonZod CI / build-and-test (macos-latest) (push) Has been cancelled Details
MoonZod CI / build-and-test (windows-latest) (push) Has been cancelled Details
[docs]: update INTRO
2026-07-23 17:48:15 +08:00
.githooks init. 2026-06-04 22:51:28 +08:00
.github/workflows [fix] ci: remove redundant Build with Warnings Check steps; use --deny-warn in 'moon check'. 2026-07-17 15:37:17 +08:00
bench_cross_lang [normal][benchmark]: 标准化 benchmark 测试,以及 zod vs moon_zod 性能比较测试。 2026-06-29 11:53:49 +08:00
cmd [fix] format moon.pkg: options("is-main": true) -> pkgtype(kind: "executable") 2026-07-17 15:42:03 +08:00
combinators [feat]: add 'pub fn json_schema_to_prompt' in combinators. 2026-07-12 22:39:16 +08:00
core [fix]: block type-specific methods after transform(); add is_builtin flag 2026-07-23 17:48:10 +08:00
doc [docs]: update INTRO 2026-07-23 17:48:15 +08:00
docs [docs]: update test counts in readme. 2026-07-17 21:18:31 +08:00
examples [examples]: add mock/pipe_agent/ 2026-07-23 17:48:15 +08:00
exporters [fix]: moon fmt. 2026-07-18 14:51:15 +08:00
importers [Phase 42][feat]: add IssueCode + ErrorMap + ParseParams error system 2026-07-18 11:41:40 +08:00
tests [fix]: moon fmt. 2026-07-18 14:51:15 +08:00
.gitignore [normal][fix]: fix doc () problem, add [] to cover rule token in examples, ignore npm node_modules. 2026-06-29 11:53:06 +08:00
AGENTS.md update docs. 2026-06-15 20:19:53 +08:00
CHANGELOG.md [feat]: implement '.required_error()' / '.invalid_type_error()', and update docs. 2026-07-12 22:50:22 +08:00
DESIGN.md [docs]: update DESIGN and readme, add branch 'doc' badge, change ci.yml name. 2026-07-11 15:10:46 +08:00
LICENSE init. 2026-06-04 22:51:28 +08:00
README.mbt.md [docs]: update test counts in readme. 2026-07-17 21:18:31 +08:00
README.md init. 2026-06-04 22:51:28 +08:00
README_zh.mbt.md [docs]: update test counts in readme. 2026-07-17 21:18:31 +08:00
moon.mod [release]: update version. 2026-07-12 23:05:28 +08:00
moon.pkg [Phase 35][refactor]: 新建 combinators 子包 + reexporter 去重 + API 重命名 2026-06-29 13:09:07 +08:00
moon_zod.mbt init. 2026-06-04 22:51:28 +08:00
moonbit_syntax_pitfalls.md [docs]: update moonbit_syntax_pitfalls.md 2026-07-18 14:44:03 +08:00
reexporter.mbt [Phase 43][feat]: add recursive schema and discriminated union 2026-07-18 14:24:46 +08:00

README.md

moon_zod

CI Mooncakes doc

🌏 中文版 README


Documents

Document Description
Design Document Important! Core architecture, design decisions, and future directions
API Reference Detailed API documentation
CLI Reference Command-line usage
Benchmark Performance comparison with other validation libraries
Examples Practical usage examples
Exporters moon_zod exporters documentation
Importers moon_zod importers documentation

About

moon_zod is a runtime Schema intermediate representation (IR) — a validation contract layer decoupled from input sources and output targets. It provides runtime JSON schema validation with a fluent chainable API, designed primarily for LLM Tool Calling, and serves as a cross-format schema interoperability bridge. See DESIGN.md for details.

A Schema IR core providing runtime validation, multi-source import, multi-format export, and LLM hallucination defense — closing the loop from JSON Schema to prompt generation.


Installation

moon add Betterlol/moon_zod

Or add to moon.mod:

import {
  "Betterlol/moon_zod",
}

Quick Start

let schema = @moon_zod.object({
  "name": @moon_zod.string().min(2).max(50),
  "age": @moon_zod.number().int().min(0).max(150),
  "email": @moon_zod.string().email(),
})

match schema.parse(input_json) {
  Ok(valid) => {
    println("Valid")
    println(@debug.to_string(valid))
  }
  Err(errors) => {
    println("Invalid")
    println(errors.length().to_string())
    for e in errors {
      println(e.to_string())
    }
  }
}

Zero-code CLI validation:

# Infer schema from sample, validate data
moon run cmd/validate -- '{"name":"Alice","age":30}' '{"name":"Bob","age":25}'
# PASS

# Batch validation with JSON Lines
moon run cmd/validate -- '{"name":"Alice"}' '{"name":"Bob"}\n{"name":"Eve"}'
# Results: 2 passed, 0 failed

Why MoonZod? (AI-First)

Feature moon_zod Typical Validation
Error collection Collects all errors in one pass Most libs fail-fast on first error
Hallucination defense Default Strip mode silently removes unknown fields Would pass through hallucinated data
Named schema export schema_to_prompt_named() generates modular TypeScript interfaces with type name references Inline expansion + duplication
JSON Schema export to_json_schema() generates standard schema for LLM API Manual schema maintenance
Path precision Every error includes exact field path (users[0].profile.age) Often just a flat message
Wasm-ready Mutable path stack — zero heap allocation on success path String-heavy allocation per parse

In LLM Tool Calling, the model often produces multiple errors at once and hallucinates extra fields. moon_zod collects every error in a single pass (so you can send them all back for self-correction), and strips unknown fields by default (no silent data corruption from hallucinated keys).


Project Layout

moon_zod/
├── core/                     # Core schema validation library
│   ├── types.mbt             # ValidationError, SchemaResult, core types
│   ├── schema.mbt            # Schema struct, parse dispatch, path stack
│   ├── string.mbt            # string() factory + validators (trim, to_lower, to_upper)
│   ├── number.mbt            # number() factory + validators
│   ├── boolean.mbt           # boolean() factory
│   ├── null.mbt              # null() factory
│   ├── bigint.mbt            # bigint() factory
│   ├── any_unknown.mbt       # any() / unknown() pass-through schemas
│   ├── array.mbt             # array() factory + parse_array
│   ├── tuple.mbt             # tuple() factory + parse_tuple
│   ├── object.mbt            # object() + modes (strip/passthrough/strict), pick/omit/partial/extend/merge
│   ├── optional.mbt          # optional() factory
│   ├── default.mbt           # default() factory
│   ├── enum.mbt              # enum_values() factory
│   ├── literal.mbt           # literal() factory (constant values)
│   ├── union.mbt             # union() factory
│   ├── intersection.mbt      # intersection() / intersect()
│   ├── refine.mbt            # refine() for custom validation
│   ├── transform.mbt         # transform() for data transformation
│   ├── preprocess.mbt        # preprocess() for input preprocessing
│   ├── shared_utils.mbt      # Common utilities (unwrap_schema, peel_optional, etc.)
│   ├── constraint_extractor.mbt  # Extract constraint info from rules
│   └── moon_zod_wbtest.mbt   # White-box tests (path stack invariants)
│
├── combinators/              # Schema combinator utilities
│   └── schema_combinators.mbt # Schema composition helpers
│
├── exporters/                # Code/schema export tools
│   ├── prompt.mbt            # schema_to_prompt() / schema_to_prompt_named()
│   ├── prompt_renderer.mbt   # Trait-based prompt rendering
│   ├── json_schema.mbt       # to_json_schema() / to_json_schema_named()
│   ├── json_schema_renderer.mbt # Trait-based JSON Schema rendering
│   ├── moonbit_struct.mbt    # schema_to_moonbit_struct() + static to_schema() generation
│   └── schema_exporter.mbt   # Shared exporter utilities
│
├── importers/                # Schema import tools
│   └── from_json_schema.mbt  # json_schema_to_moon_zod() — reverse JSON Schema → moon_zod code generation
│
├── tests/                    # Test suite (479 tests)
│   ├── test_string.mbt       # string() validator tests (trim, to_lower, to_upper, nonempty)
│   ├── test_number.mbt       # number() validator tests
│   ├── test_boolean_null.mbt # boolean/null tests
│   ├── test_object.mbt       # object() mode + pick/omit/partial/extend/merge tests
│   ├── test_array.mbt        # array() + nonempty tests
│   ├── test_tuple.mbt        # tuple() tests
│   ├── test_combinators.mbt  # union/literal/optional/default/brand/bigint tests
│   ├── test_any_unknown_preprocess.mbt # any/unknown/preprocess tests
│   ├── test_transform_refine.mbt # transform/refine tests
│   ├── test_json_schema.mbt  # JSON Schema export + $defs/$ref tests
│   ├── test_json_schema_fixes.mbt # exclusiveMin/Max semantics + enum edge cases
│   ├── test_moonbit_struct.mbt # MoonBit struct generation tests
│   ├── test_prompt.mbt       # Prompt generation tests
│   ├── test_prompt_named.mbt # Named schema export tests
│   ├── test_custom_message.mbt # Custom error message tests
│   ├── test_errors.mbt       # Error collection tests
│   ├── test_schema_to_code.mbt # Code generation tests
│   └── reexporter.mbt        # Test re-exports
│
├── cmd/                      # CLI tools
│   ├── main/                 # Benchmark runner (performance baselines)
│   ├── wasm/                 # WebAssembly cross-language benchmark
│   ├── json2schema/          # JSON → moon_zod schema code generator + JSON Schema reverse importer
│   ├── gen-struct/           # JSON Schema → MoonBit struct generator
│   └── validate/             # JSON schema validator (infer-then-validate)
│
└── examples/                 # LLM agent demonstrations
    ├── gen-struct/           # JSON Schema → MoonBit struct generator demo
    ├── json2schema/          # JSON → moon_zod schema code generation
    ├── mock/                 # Mock agent demonstrations
    │   ├── llm_agent/        # Basic LLM tool calling example
    │   └── educational_agent/ # Multi-round self-correction demo
    ├── multiple_schemas/     # Handling multiple schemas
    ├── real_llm_agent/       # Real LLM integration (with API fallback to mock)
    ├── resources/            # Sample data files (JSON, JSON Schema)
    ├── schema2json/          # Schema → JSON Schema export demo
    ├── schema2prompt/        # Schema → prompt generation showcase
    ├── shared_schemas/       # Shared schema definitions (library package)
    └── validate_cli/         # CLI validation demo

Development

# Testing & Building
moon test                # Run all tests (479 total, 0 warnings)
moon build               # Build the library
moon check               # Type check (0 errors, 0 warnings)
moon info && moon fmt    # Update interface + format

# CLI Tools
moon run cmd/main                                      # Run performance benchmarks
moon run cmd/json2schema -- '{"hello":"world"}'      # JSON → moon_zod schema code
moon run cmd/json2schema -- --from-json-schema '<{...}>'  # JSON Schema → moon_zod code
moon run cmd/json2schema -- --from-json-schema '<{...}>' --verbose  # with debug output
moon run cmd/gen-struct -- --schema '<{...}>'          # JSON Schema → MoonBit structs
moon run cmd/validate -- '{"name":"Alice"}' '{"name":"Bob"}'  # Validate JSON

# Examples
moon run examples/mock/llm_agent                     # Basic LLM tool calling demo
moon run examples/mock/educational_agent             # Multi-round self-correction demo
moon run examples/real_llm_agent -- product prompt   # Real LLM with mock fallback
moon run examples/real_llm_agent -- product validate # Validate with real API
moon run examples/multiple_schemas                   # Multiple schema handling
moon run examples/schema2json -- product schema      # Schema → JSON Schema export
moon run examples/schema2prompt -- product schema    # Schema → prompt generation showcase
moon run examples/json2schema                        # JSON → moon_zod schema code gen

Features

  • Primitive schemas: string(), number(), boolean(), null(), bigint()
  • Compound schemas: object(Map), array(Schema), tuple([Schema...]), union(Array[Schema]), intersection(Array[Schema]), enum_values(Array[String]), literal(Json)
  • Pass-through schemas: any() and unknown() accept any JSON value (semantic distinction)
  • String validators (23+): .min(n), .max(n), .nonempty(), .trim(), .to_lower(), .to_upper(), .email() (full RFC validation), .url() (full structure), .regex(pattern) (regular expression match), .startsWith(), .endsWith(), .includes(), .uuid(), .cuid(), .ulid(), .datetime(), .ip()/.ipv4()/.ipv6(), .length(n)
  • Number validators (8+): .int(), .positive(), .negative(), .multipleOf(), .finite(), .safe(), .min(), .max()
  • Object modes: .strip() (default, removes unknown fields), .passthrough() (keeps unknown fields), .strict() (rejects unknown fields)
  • Object composition: .pick(keys), .omit(keys), .partial(), .extend_with(Map), .merge(Schema)
  • Optional/Default handling: .optional() and .default(value) with correct rule chaining through wrappers
  • Data transformation: .transform(fn) validates then transforms; preprocess(fn, schema) transforms then validates
  • Custom rules: .refine(check, message), .intersect(other) for explicit intersection
  • Schema naming & metadata: .name(text) for named exports, .describe(text) for LLM prompts, .brand(text) for nominal typing
  • Custom error messages: msg? parameter on all validators, .message(text) override method, type-level required_error / invalid_type_error
  • Error collection: Collects all validation errors in one pass, perfect for LLM self-correction loops
  • Full-path error reporting: Every error includes exact field path (users[0].profile.age)
  • LLM prompt generation:
    • schema_to_prompt(schema) — inline TypeScript-interface with constraint comments
    • schema_to_prompt_named(schema, include_names?) — modular interfaces with topological sorting and type name references
  • JSON Schema export:
    • to_json_schema(schema) — standard JSON Schema with full constraint annotations
    • to_json_schema_skeleton(schema) — lightweight skeleton (structure only)
    • to_json_schema_named(schema, include_names?) — separate $defs and $ref references
  • JSON Schema reverse import:
    • json_schema_to_moon_zod(json_schema) — generate moon_zod source code from standard JSON Schema
    • Full support for $defs, $ref, constraints, format validation, enum
  • MoonBit struct generation:
    • schema_to_moonbit_struct(schema) — recursively generate MoonBit struct/enum definitions for every object/enum schema
    • schema_to_moonbit_struct_full(schema) — generate definitions plus static Type::to_schema() functions
  • Lightweight dependencies: Core MoonBit library plus official moonbitlang/regexp for regex validation
  • WebAssembly-ready: Mutable path stack for zero heap allocation on success path
  • Performance: ~18.5k-56k validations/second depending on schema complexity

website: extension.


Learn More