@10up/block-renderer-validator
v0.2.0
Published
Validation for WordPress block trees - schema, nesting, and token validation
Readme
@10up/block-renderer-validator
Validate JSON block trees against schemas, nesting rules, and theme tokens. This package ensures block trees are valid before rendering.
Installation
npm install @10up/block-renderer-validator
# or
pnpm add @10up/block-renderer-validatorOverview
This package provides comprehensive validation for block trees:
- Schema Validation - Validates block props against Zod schemas from block definitions
- Nesting Validation - Checks parent/ancestor/allowedBlocks constraints
- Token Validation - Verifies theme token references (colors, spacing, etc.)
- Pattern Validation - Confirms pattern slugs exist in the registry
Usage
Full Tree Validation
The main entry point - validates a tree with all available validators:
import { validateTree } from '@10up/block-renderer-validator';
const tree = {
root: 'para-1',
elements: {
'para-1': {
key: 'para-1',
type: 'core/paragraph',
props: {
content: 'Hello',
style: { color: { background: 'var:preset|color|primary' } }
}
}
}
};
const result = validateTree(tree, {
catalog: blockCatalog, // Block definitions for schema/nesting
tokens: themeTokens, // Theme tokens for color/spacing validation
patterns: patternRegistry // Pattern definitions
});
if (result.valid) {
console.log('Tree is valid');
} else {
console.log('Errors:', result.errors);
// ['Unknown color token: primary', 'Invalid block type: core/unknown']
}Validation Options
interface ValidateTreeOptions {
/** Block catalog for schema and nesting validation */
catalog?: BlockCatalog;
/** Theme tokens for token validation */
tokens?: ThemeTokens;
/** Pattern registry for pattern validation */
patterns?: PatternRegistry;
/** Whether to validate schemas (default: true if catalog provided) */
validateSchemas?: boolean;
/** Whether to validate nesting rules (default: true if catalog provided) */
validateNesting?: boolean;
/** Whether to validate theme tokens (default: true if tokens provided) */
validateTokens?: boolean;
/** Whether to validate pattern references (default: true if patterns provided) */
validatePatterns?: boolean;
}Create Reusable Validator
import { createTreeValidator } from '@10up/block-renderer-validator';
const validator = createTreeValidator({
catalog: blockCatalog,
tokens: themeTokens,
patterns: patternRegistry,
});
// Use the pre-configured validator
const result1 = validator(tree1);
const result2 = validator(tree2);Schema Validation
Validate block props against their Zod schemas:
import { validateBlockProps, validateTreeSchemas } from '@10up/block-renderer-validator';
// Validate a single element's props
const result = validateBlockProps(element.props, blockDefinition.schema);
if (!result.valid) {
console.log(result.errors);
// ['content: Expected string, received number']
}
// Validate all elements in a tree
const treeResult = validateTreeSchemas(tree, catalog);Create Block Validator
Create a validator for a specific block:
import { createBlockValidator } from '@10up/block-renderer-validator';
const validateParagraph = createBlockValidator(paragraphDefinition);
const result = validateParagraph({ content: 'Hello', dropCap: true });Get Valid Attributes
Filter props to only include valid attributes:
import { getValidAttributes } from '@10up/block-renderer-validator';
const cleanProps = getValidAttributes(props, blockDefinition.schema);
// Returns only props that match the schemaNesting Validation
Validate block nesting rules:
import { validateTreeNesting } from '@10up/block-renderer-validator';
const result = validateTreeNesting(tree, catalog);
if (!result.valid) {
console.log(result.errors);
// ['core/column must be inside core/columns']
}Individual Nesting Validators
import {
validateParent,
validateAncestor,
validateChildren,
validateMultiple,
} from '@10up/block-renderer-validator';
// Check if element has valid parent
validateParent(element, parentElement, blockDefinition);
// Check if element has valid ancestor chain
validateAncestor(element, ancestorChain, blockDefinition);
// Check if children are valid for this block
validateChildren(element, childElements, blockDefinition);
// Check if multiple instances are allowed
validateMultiple(elements, blockDefinition);Token Validation
Validate theme token references in block props:
import { validateTreeTokens, validateElementTokens } from '@10up/block-renderer-validator';
// Validate all tokens in a tree
const result = validateTreeTokens(tree, themeTokens);
if (!result.valid) {
console.log(result.errors);
// ['Unknown color token: invalid-color']
}
// Validate a single element's tokens
const elementResult = validateElementTokens(element, themeTokens);Specific Token Validators
import {
validateColorTokens,
validateTypographyTokens,
validateSpacingTokens,
} from '@10up/block-renderer-validator';
// Validate specific token types
validateColorTokens(props, themeTokens);
validateTypographyTokens(props, themeTokens);
validateSpacingTokens(props, themeTokens);Pattern Validation
Validate pattern block references:
import {
validatePatternReference,
validateTreePatterns,
isPatternReference,
getPatternReferences,
} from '@10up/block-renderer-validator';
// Check if an element is a pattern reference
if (isPatternReference(element)) {
const result = validatePatternReference(element, patternRegistry);
if (!result.valid) {
console.log(result.errors);
// ['Unknown pattern: theme/nonexistent-pattern']
}
}
// Validate all patterns in a tree
const treeResult = validateTreePatterns(tree, patternRegistry);
// Get all pattern references from a tree
const patternRefs = getPatternReferences(tree);
// ['theme/hero-section', 'theme/footer']Template Validation
Validate BlockTemplate format (PHP-style nested arrays):
import {
validateTemplate,
validateTemplateStructure,
validateTemplateBlockTypes,
validateTemplateNesting,
} from '@10up/block-renderer-validator';
const template = [
['core/group', { layout: { type: 'constrained' } }, [
['core/heading', { content: 'Title', level: 2 }],
['core/paragraph', { content: 'Content' }],
]],
];
// Full template validation
const result = validateTemplate(template, {
catalog: blockCatalog,
});
if (!result.valid) {
console.log('Errors:', result.errors);
}
// Validate just structure (correct array format)
const structureResult = validateTemplateStructure(template);
// Validate block types exist
const typesResult = validateTemplateBlockTypes(template, catalog);
// Validate nesting rules
const nestingResult = validateTemplateNesting(template, catalog);Template Validation Options
interface ValidateTemplateOptions {
/** Block catalog for type and nesting validation */
catalog?: BlockCatalog;
/** Whether to validate that block types exist (default: true if catalog provided) */
validateBlockTypes?: boolean;
/** Whether to validate nesting rules (default: true if catalog provided) */
validateNesting?: boolean;
}Complete Exports
Main Functions
| Function | Description |
|----------|-------------|
| validateTree(tree, options) | Full tree validation with all validators |
| createTreeValidator(options) | Create reusable validator function |
Schema Validation
| Function | Description |
|----------|-------------|
| validateBlockProps(props, schema) | Validate props against Zod schema |
| validateTreeSchemas(tree, catalog) | Validate all elements in tree |
| createBlockValidator(definition) | Create validator for specific block |
| getValidAttributes(props, schema) | Filter to valid attributes only |
Nesting Validation
| Function | Description |
|----------|-------------|
| validateTreeNesting(tree, catalog) | Validate all nesting rules in tree |
| validateParent(element, parent, def) | Check valid parent constraint |
| validateAncestor(element, ancestors, def) | Check valid ancestor constraint |
| validateChildren(element, children, def) | Check valid children constraint |
| validateMultiple(elements, def) | Check multiple instance constraint |
Token Validation
| Function | Description |
|----------|-------------|
| validateTreeTokens(tree, tokens) | Validate all tokens in tree |
| validateElementTokens(element, tokens) | Validate single element tokens |
| validateColorTokens(props, tokens) | Validate color token references |
| validateTypographyTokens(props, tokens) | Validate typography tokens |
| validateSpacingTokens(props, tokens) | Validate spacing tokens |
Pattern Validation
| Function | Description |
|----------|-------------|
| validateTreePatterns(tree, patterns) | Validate all pattern refs in tree |
| validatePatternReference(element, patterns) | Validate single pattern ref |
| isPatternReference(element) | Check if element is a pattern |
| getPatternReferences(tree) | Get all pattern slugs from tree |
Template Validation
| Function | Description |
|----------|-------------|
| validateTemplate(template, options) | Full template validation |
| validateTemplateStructure(template) | Validate template array structure |
| validateTemplateBlockTypes(template, catalog) | Validate block types exist |
| validateTemplateNesting(template, catalog) | Validate nesting rules |
Types
| Type | Description |
|------|-------------|
| ValidateTreeOptions | Options for validateTree |
| ValidateTemplateOptions | Options for validateTemplate |
| TemplateValidationResult | Result from template validation |
License
MIT
