Skip to content

Insta-clean llm-generated schemas and make them safe to execute.

License

Notifications You must be signed in to change notification settings

SouthBridgeAI/zodsheriff

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

13 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ›‘οΈ ZodSheriff

npm version TypeScript

Safe validation and execution of LLM-generated Zod schemas

Safely run Zod schemas from LLMs while preserving structure, comments, and documentation. Invalid parts are surgically removed while keeping the rest intact.

Features β€’ Quick Start β€’ Usage β€’ Advanced Features β€’ Architecture

🎯 Key Features

  • πŸ”’ Safe Schema Execution: Run Zod schemas from LLMs without worrying about malicious code or infinite loops
  • πŸ›‘οΈ Proactive Security: Prevents regex DoS attacks and detects unsafe patterns
  • ⚑ Resource Protection: Aggressive timeout management and depth tracking
  • πŸ” Deep Validation: Comprehensive validation of methods, arguments, and properties
  • 🎯 Smart Schema Analysis: Powerful schema unification and transformation capabilities
  • 🎚️ Configurable Safety: Multiple security profiles with deep customization
  • πŸ“Š Type-Safe Architecture: Built with TypeScript, featuring extensive type safety
  • πŸ› οΈ CLI & API: Flexible usage through CLI or programmatic API

πŸš€ Quick Start

CLI Usage

# Basic validation
bunx zodsheriff schema.ts

# Read from clipboard
bunx zodsheriff --clipboard

# Read from stdin (great for pipelines)
cat schema.ts | bunx zodsheriff --stdin

# Choose security level
bunx zodsheriff --config medium schema.ts

# Get cleaned schema
bunx zodsheriff --clean-only schema.ts > safe-schema.ts

# Get unified schema (combines dependent schemas)
bunx zodsheriff --getUnifiedLargest schema.ts > unified.ts

# Unwrap top-level arrays in unified schema
bunx zodsheriff --getUnifiedLargest --unwrapArrays schema.ts > unified.ts

πŸ“¦ Installation

npm install zodsheriff   # Using npm
yarn add zodsheriff      # Using yarn
pnpm add zodsheriff     # Using pnpm

πŸ’» Usage

API Usage

import { validateZodSchema } from "zodsheriff";

// Basic validation
const result = await validateZodSchema(schemaCode);
if (result.isValid) {
  console.log("Schema is safe!");
  console.log(result.cleanedCode);
}

// With schema unification
const result = await validateZodSchema(schemaCode, {
  schemaUnification: {
    enabled: true,
    unwrapArrayRoot: true, // Unwrap top-level arrays
  },
});

// Access unified schemas
if (result.schemaGroups?.length) {
  console.log("Largest unified schema:", result.schemaGroups[0].code);
}

Security Levels

import {
  validateZodSchema,
  extremelySafeConfig,
  mediumConfig,
  relaxedConfig,
} from "zodsheriff";

// Extremely Safe - Best for untrusted LLM output
const safeResult = await validateZodSchema(code, extremelySafeConfig);

// Medium - Balanced for semi-trusted sources
const mediumResult = await validateZodSchema(code, mediumConfig);

// Relaxed - For trusted sources
const relaxedResult = await validateZodSchema(code, relaxedConfig);

Custom Configuration

import { validateZodSchema, createConfig, relaxedConfig } from "zodsheriff";

const config = createConfig(relaxedConfig, {
  timeoutMs: 2000,
  maxNodeCount: 5000,
  maxChainDepth: 4,
  schemaUnification: {
    enabled: true,
    unwrapArrayRoot: true,
  },
  propertySafety: {
    deniedPrefixes: ["_", "$"],
    deniedProperties: new Set(["constructor", "__proto__"]),
  },
});

const result = await validateZodSchema(schemaCode, config);

πŸ” Advanced Features

Schema Unification

ZodSheriff can analyze dependencies between schemas and generate unified, self-contained versions:

// Input schemas with dependencies
const addressSchema = z.object({
  street: z.string(),
  city: z.string(),
});

const userSchema = z.object({
  name: z.string(),
  address: addressSchema,
});

// After unification (--getUnifiedLargest):
const unifiedSchema = z.object({
  name: z.string(),
  address: z.object({
    street: z.string(),
    city: z.string(),
  }),
});

Array Unwrapping

When using schema unification, you can automatically unwrap top-level array schemas:

// Input schema
const arraySchema = z.array(
  z.object({
    id: z.string(),
    value: z.number(),
  })
);

// After unification with --unwrapArrays:
const unwrappedSchema = z.object({
  id: z.string(),
  value: z.number(),
});

Validation Results

const result = await validateZodSchema(schemaCode);

// Validation status
console.log("Valid:", result.isValid);

// Review issues
result.issues.forEach((issue) => {
  console.log(`${issue.severity}: ${issue.message} at line ${issue.line}`);
  if (issue.suggestion) {
    console.log(`Suggestion: ${issue.suggestion}`);
  }
});

// Access root schemas
console.log("Root schemas:", result.rootSchemaNames);

// Access unified schemas
if (result.schemaGroups?.length) {
  const largest = result.schemaGroups[0];
  console.log(`Unified schema with ${largest.metrics.schemaCount} schemas`);
}

πŸ—οΈ Architecture Decisions

Safety First

  • Strict method and property whitelisting
  • Comprehensive function validation
  • Protection against prototype pollution
  • Resource limits and timeout protection

Smart Processing

  • AST-based schema analysis
  • Schema dependency tracking
  • Intelligent unification
  • Comment and structure preservation

Performance

  • Smart caching strategy
  • Optimized validation paths
  • Resource-aware processing
  • Configurable parallelization

πŸ“š Documentation

For detailed documentation, visit:

🀝 Contributing

Contributions are welcome! Please read our Contributing Guide and Code of Conduct.

πŸ“„ License

MIT License - see LICENSE for details

About

Insta-clean llm-generated schemas and make them safe to execute.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published