@braingrid/json-guard
v0.1.1
Published
Schema-aware JSON repair engine for LLM output recovery and user input validation
Readme
@braingrid/json-guard
Schema-aware JSON repair engine for LLM output recovery and user input validation
A minimal, pluggable JSON repair engine designed to recover malformed AI outputs into schema-valid JSON.
Philosophy: "Repair what's broken, validate it, no modes, no profiles — just JSON that works."
Features
- 🔧 Automatic Repair - Fixes common JSON syntax errors from AI outputs
- 📐 Schema-Driven - Uses JSON Schema (Ajv) or Zod for validation
- 🔌 Pluggable - Extensible with custom repair strategies
- 🎯 Type-Safe - Full TypeScript support with generics
- 🚀 Dual Package - ESM and CJS support
Installation
pnpm add @braingrid/json-guard
# or
npm install @braingrid/json-guard
# or
yarn add @braingrid/json-guardQuick Start
import { createGuard, ajvAdapter } from "@braingrid/json-guard";
// Define your schema
const schema = ajvAdapter().fromJsonSchema({
type: "object",
required: ["action"],
properties: {
action: { enum: ["search", "create", "delete"] },
limit: { type: "integer", default: 10 }
},
additionalProperties: false
});
// Create a guard
const guard = createGuard();
// Repair malformed AI output
const result = await guard.repair(
"```json\n{ action:'Search', limit:'10', extra:true }\n```",
{ schema }
);
console.log(result.value);
// => { action: "search", limit: 10 }API
createGuard()
Creates a new Guard instance with all default strategies registered.
const guard = createGuard();guard.repair<T>(rawInput: string, options: RepairOptions): Promise<GuardResult<T>>
Repairs malformed JSON against a schema.
Parameters:
rawInput(string, required) - The potentially malformed JSON stringoptions.schema(SchemaAdapter, required) - Schema adapter for validationoptions.defaultStrategies(string[], optional) - List of built-in strategies to applyoptions.customStrategies(Strategy[], optional) - User-defined strategies to run after defaults
Returns: Promise<GuardResult<T>>
interface GuardResult<T = unknown> {
ok: boolean; // Whether repair succeeded
value?: T; // Parsed and validated value
json?: string; // Repaired JSON string
diagnostics: Diagnostic[]; // Repair diagnostics
confidence: number; // Confidence score (0-1)
}Built-In Strategies
The following strategies run in order by default:
- extractJsonBlock - Extracts JSON from markdown code blocks or surrounding text
- tolerantParse - Fixes single quotes, unquoted keys, trailing commas, comments
- separatorNormalizer - Fixes separator issues (semicolons, missing commas)
- bracketAndQuoteFixer - Adds missing closing brackets and quotes
- schemaAlign - Type coercion, enum normalization, default values
- sanitizers - Removes disallowed properties per schema
- finalize - Final validation and serialization
Schema Adapters
Ajv (JSON Schema)
import { ajvAdapter } from "@braingrid/json-guard";
const schema = ajvAdapter().fromJsonSchema({
type: "object",
properties: {
name: { type: "string" },
age: { type: "number" }
}
});Zod
import { zodAdapter } from "@braingrid/json-guard";
import { z } from "zod";
const schema = zodAdapter().fromZodSchema(
z.object({
name: z.string(),
age: z.number()
})
);Custom Strategies
Create custom strategies to handle domain-specific repairs:
import type { Strategy } from "@braingrid/json-guard";
const aliasKeys: Strategy = {
name: "aliasKeys",
async apply({ value }) {
if (value && typeof value === "object" && "firstname" in value) {
return {
value: { ...value, name: value.firstname },
diagnostics: [{
severity: "info",
message: "Mapped 'firstname' to 'name'",
strategy: "aliasKeys"
}]
};
}
return { diagnostics: [] };
}
};
const result = await guard.repair(rawInput, {
schema,
customStrategies: [aliasKeys]
});Selective Strategy Usage
Disable specific default strategies:
import { DEFAULT_STRATEGIES } from "@braingrid/json-guard";
const result = await guard.repair(rawInput, {
schema,
defaultStrategies: DEFAULT_STRATEGIES.filter(
s => s !== "separatorNormalizer"
)
});Examples
Markdown-Wrapped JSON
const input = '```json\n{"name": "test"}\n```';
const result = await guard.repair(input, { schema });
// Extracts and validates the JSONSingle Quotes & Unquoted Keys
const input = "{name: 'test', active: true}";
const result = await guard.repair(input, { schema });
// Fixes to: {"name": "test", "active": true}Enum Case Normalization
const input = '{"action": "CREATE"}'; // Wrong case
const result = await guard.repair(input, { schema });
// Normalizes to: {"action": "create"}Type Coercion
const input = '{"age": "30"}'; // String instead of number
const result = await guard.repair(input, { schema });
// Coerces to: {"age": 30}TypeScript Types
import type {
Guard,
GuardResult,
Strategy,
SchemaAdapter,
Diagnostic
} from "@braingrid/json-guard";License
Apache-2.0
Contributing
Contributions welcome! Please see the main repository for contribution guidelines.
