@10up/block-renderer-block-schemas
v0.1.7
Published
Block.json parser and Zod schema generator for WordPress blocks
Readme
@10up/block-renderer-block-schemas
Parse WordPress block.json files and generate Zod validation schemas. This package handles the complex mapping between WordPress block attribute definitions and runtime-validated Zod schemas.
Installation
npm install @10up/block-renderer-block-schemas
# or
pnpm add @10up/block-renderer-block-schemasOverview
WordPress blocks define their attributes in block.json files using a specific schema. This package:
- Type Mapping - Converts WordPress attribute types (
string,rich-text,object, etc.) to Zod schemas - Supports Resolution - Determines which attributes are auto-generated by the
supportsconfiguration - Style Schema Generation - Creates properly typed schemas for the complex
styleattribute - Global Attributes - Handles always-present attributes like
lock,metadata, andclassName - Definition Generation - Combines all of the above into complete
BlockDefinitionobjects
Usage
Generate Block Definition
The main entry point - creates a complete BlockDefinition from a block.json object:
import { generateBlockDefinition } from '@10up/block-renderer-block-schemas';
const blockJson = {
name: 'core/paragraph',
title: 'Paragraph',
attributes: {
content: { type: 'rich-text', source: 'rich-text' },
dropCap: { type: 'boolean', default: false }
},
supports: {
color: { background: true, text: true },
typography: { fontSize: true }
}
};
const definition = generateBlockDefinition(blockJson);
// definition.schema validates: content, dropCap, backgroundColor, textColor,
// fontSize, style, lock, metadata, classNameGenerator Options
interface GeneratorOptions {
/** Include supports-generated attributes (default: true) */
includeSupportsAttributes?: boolean;
/** Include global attributes - lock, metadata (default: true) */
includeGlobalAttributes?: boolean;
/** Include className attribute (default: true) */
includeClassName?: boolean;
}
const definition = generateBlockDefinition(blockJson, {
includeSupportsAttributes: true,
includeGlobalAttributes: false, // Skip lock/metadata
includeClassName: true,
});Generate Multiple Definitions
import { generateBlockDefinitions } from '@10up/block-renderer-block-schemas';
const blockJsons = [paragraphBlock, headingBlock, groupBlock];
const catalog = generateBlockDefinitions(blockJsons);
// Returns Map<string, BlockDefinition>
const paragraphDef = catalog.get('core/paragraph');Type Mapping
Maps WordPress attribute types to Zod schemas:
import { mapTypeToZod } from '@10up/block-renderer-block-schemas';
mapTypeToZod('string'); // z.string()
mapTypeToZod('number'); // z.number()
mapTypeToZod('integer'); // z.number().int()
mapTypeToZod('boolean'); // z.boolean()
mapTypeToZod('rich-text'); // z.string()
mapTypeToZod('object'); // z.record(z.unknown())
mapTypeToZod('array'); // z.array(z.unknown())
mapTypeToZod('null'); // z.null()Union Types
WordPress attributes can have multiple types:
import { createUnionSchema } from '@10up/block-renderer-block-schemas';
// { type: ['string', 'number'] }
createUnionSchema(['string', 'number']); // z.union([z.string(), z.number()])Attribute to Schema
Full attribute definition to Zod schema:
import { attributeToZodSchema, attributesToZodSchema } from '@10up/block-renderer-block-schemas';
// Single attribute with enum
attributeToZodSchema({
type: 'string',
enum: ['left', 'center', 'right'],
default: 'left'
});
// z.union([z.literal('left'), z.literal('center'), z.literal('right')]).default('left').optional()
// Multiple attributes
const schema = attributesToZodSchema({
content: { type: 'string' },
level: { type: 'number', default: 2 }
});
// z.object({ content: z.string().optional(), level: z.number().default(2).optional() })Supports Resolution
WordPress supports configuration auto-generates certain attributes. This package resolves them:
import { resolveSupportsToAttributes } from '@10up/block-renderer-block-schemas';
const supports = {
anchor: true,
align: ['wide', 'full'],
color: { background: true, text: true, gradients: true },
typography: { fontSize: true, fontFamily: true },
border: { color: true, radius: true },
shadow: true
};
const attributes = resolveSupportsToAttributes(supports);
// Returns attribute definitions for:
// - anchor: string
// - align: enum ['wide', 'full']
// - backgroundColor: string
// - textColor: string
// - gradient: string
// - fontSize: string
// - fontFamily: string
// - borderColor: string
// - shadow: stringStyle Schema
The style attribute has a complex nested structure. This package generates properly typed schemas:
import { createStyleSchema } from '@10up/block-renderer-block-schemas';
const styleSchema = createStyleSchema({
color: { background: true, text: true },
typography: { fontSize: true, lineHeight: true },
spacing: { padding: true, margin: true },
border: { color: true, radius: true }
});
// Validates:
// {
// color: { background?: string, text?: string },
// typography: { fontSize?: string, lineHeight?: string },
// spacing: {
// padding?: { top?: string, right?: string, bottom?: string, left?: string },
// margin?: { top?: string, right?: string, bottom?: string, left?: string }
// },
// border: { color?: string, radius?: string | { topLeft?, topRight?, bottomLeft?, bottomRight? } }
// }Layout Schema
For blocks with layout support:
import { createLayoutSchema } from '@10up/block-renderer-block-schemas';
const layoutSchema = createLayoutSchema({ layout: true });
// Validates:
// {
// type?: 'constrained' | 'flex' | 'flow' | 'grid',
// justifyContent?: string,
// orientation?: 'horizontal' | 'vertical',
// flexWrap?: 'wrap' | 'nowrap',
// contentSize?: string,
// wideSize?: string,
// columnCount?: number,
// minimumColumnWidth?: string
// }Global Attributes
Attributes that exist on every block:
import {
lockSchema,
metadataSchema,
getGlobalAttributeDefinitions,
getGlobalAttributeSchemas,
getClassNameAttribute,
getClassNameSchema,
} from '@10up/block-renderer-block-schemas';
// Lock attribute - controls block locking
lockSchema.parse({ move: false, remove: true });
// Metadata attribute - block bindings, name, overrides
metadataSchema.parse({
name: 'my-block-instance',
bindings: {
content: { source: 'core/post-meta', args: { key: 'my_meta' } }
}
});
// Get all global attribute definitions
const globals = getGlobalAttributeDefinitions();
// { lock: {...}, metadata: {...} }
// className depends on supports.customClassName
const classNameAttr = getClassNameAttribute({ customClassName: true });
// { className: { type: 'string' } }Block Detection Utilities
Dynamic Block Detection
import { isDynamicBlock } from '@10up/block-renderer-block-schemas';
isDynamicBlock({ name: 'core/paragraph' }); // false
isDynamicBlock({ name: 'core/latest-posts' }); // true
isDynamicBlock({ name: 'my/block', render: 'file:./render.php' }); // trueDynamic blocks are server-rendered and include:
- Blocks with a
renderproperty in block.json - Known dynamic core blocks (archives, latest-posts, query, search, etc.)
Inner Blocks Detection
import { hasInnerBlocksSupport } from '@10up/block-renderer-block-schemas';
hasInnerBlocksSupport({ name: 'core/paragraph' }); // false
hasInnerBlocksSupport({ name: 'core/group' }); // true
hasInnerBlocksSupport({ name: 'my/block', allowedBlocks: ['core/paragraph'] }); // trueRequired Attributes
Some core blocks require specific attributes to render meaningful output. For example, core/image needs a url attribute - without it, the block renders nothing.
This information cannot be determined from block.json alone, so we maintain a static list of required attributes for core blocks:
import {
CORE_REQUIRED_ATTRIBUTES,
getRequiredAttributes,
hasRequiredAttributes,
} from '@10up/block-renderer-block-schemas';
// Get required attributes for a specific block
getRequiredAttributes('core/image'); // ['url']
getRequiredAttributes('core/video'); // ['src']
getRequiredAttributes('core/embed'); // ['url']
getRequiredAttributes('core/pattern'); // ['slug']
// Check if a block has required attributes
hasRequiredAttributes('core/image'); // true
hasRequiredAttributes('core/paragraph'); // false
// Full list of blocks with required attributes
console.log(CORE_REQUIRED_ATTRIBUTES);
// {
// 'core/image': ['url'],
// 'core/video': ['src'],
// 'core/audio': ['src'],
// 'core/file': ['href'],
// 'core/embed': ['url'],
// 'core/pattern': ['slug'],
// 'core/template-part': ['slug'],
// 'core/shortcode': ['text'],
// 'core/html': ['content'],
// 'core/block': ['ref'],
// 'core/navigation-link': ['label', 'url'],
// 'core/social-link': ['service'],
// }When generating schemas, required attributes are automatically marked as non-optional in the Zod schema, ensuring validation fails if they're missing.
Complete Exports
Functions
| Function | Description |
|----------|-------------|
| generateBlockDefinition(blockJson, options?) | Generate complete BlockDefinition from block.json |
| generateBlockDefinitions(blockJsons, options?) | Generate definitions for multiple blocks |
| mapTypeToZod(type) | Map single WordPress type to Zod schema |
| createUnionSchema(types) | Create Zod union from multiple types |
| attributeToZodSchema(attr, options?) | Convert attribute definition to Zod schema |
| attributesToZodSchema(attrs, options?) | Convert all attributes to Zod object schema |
| resolveSupportsToAttributes(supports) | Get generated attributes from supports |
| createStyleSchema(supports) | Create Zod schema for style attribute |
| createLayoutSchema(supports) | Create Zod schema for layout attribute |
| getGlobalAttributeDefinitions() | Get lock/metadata attribute definitions |
| getGlobalAttributeSchemas() | Get lock/metadata Zod schemas |
| getClassNameAttribute(supports) | Get className attribute if enabled |
| getClassNameSchema(supports) | Get className Zod schema if enabled |
| isDynamicBlock(blockJson) | Check if block is server-rendered |
| hasInnerBlocksSupport(blockJson) | Check if block supports InnerBlocks |
| getRequiredAttributes(blockName) | Get required attributes for a core block |
| hasRequiredAttributes(blockName) | Check if a block has required attributes |
Types
| Type | Description |
|------|-------------|
| GeneratorOptions | Options for generateBlockDefinition |
| StyleAttributeShape | TypeScript interface for style attribute |
| AttributeSchemaOptions | Options for attributeToZodSchema |
| AttributesSchemaOptions | Options for attributesToZodSchema |
Constants
| Constant | Description |
|----------|-------------|
| CORE_REQUIRED_ATTRIBUTES | Map of block names to required attribute names |
Schemas
| Schema | Description |
|--------|-------------|
| lockSchema | Zod schema for lock attribute |
| metadataSchema | Zod schema for metadata attribute |
License
MIT
