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
- π 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
# 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.tsnpm install zodsheriff # Using npm
yarn add zodsheriff # Using yarn
pnpm add zodsheriff # Using pnpmimport { 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);
}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);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);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(),
}),
});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(),
});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`);
}- Strict method and property whitelisting
- Comprehensive function validation
- Protection against prototype pollution
- Resource limits and timeout protection
- AST-based schema analysis
- Schema dependency tracking
- Intelligent unification
- Comment and structure preservation
- Smart caching strategy
- Optimized validation paths
- Resource-aware processing
- Configurable parallelization
For detailed documentation, visit:
Contributions are welcome! Please read our Contributing Guide and Code of Conduct.
MIT License - see LICENSE for details