@wpkernel/pipeline v0.12.1-beta.3
@wpkernel/pipeline / createHelper
Function: createHelper()
function createHelper<TContext, TInput, TOutput, TReporter, TKind>(options): Helper<TContext, TInput, TOutput, TReporter, TKind>;Creates a pipeline helper-the fundamental building block of WPKernel's code generation system.
Overview
Helpers are composable, dependency-aware transformation units that power the entire framework:
- CLI package: Generates PHP resources, actions, blocks, and bindings via helper chains
- PHP Driver: Transforms PHP AST nodes through fragment helpers
- Core: Orchestrates resource definitions and action middleware
Each helper is a pure, immutable descriptor that declares:
- What it does: Fragment transformations or artifact building
- When it runs: Priority ordering and dependency relationships
- How it integrates: Mode (extend/replace/before/after) and rollback behavior
Key Concepts
Helper Kinds
fragment: Modifies AST nodes in-place (e.g., add PHP opening tag, inject imports)builder: Produces final artifacts from fragments (e.g., write files, format code)
Execution Modes
extend(default): Add to existing transformations; multiple helpers with same key can coexistoverride: Only one override helper per key is allowed; prevents duplicate override registrations
Note: Mode primarily affects registration validation. For execution ordering, use priority and dependsOn.
Dependency Resolution
The pipeline automatically:
- Topologically sorts helpers based on
dependsOndeclarations - Validates dependency chains and reports missing/circular dependencies
- Ensures helpers run in correct order regardless of registration sequence
Architecture
Helpers form directed acyclic graphs (DAGs) where each node represents a transformation and edges represent dependencies. The pipeline executes helpers in topological order, ensuring all dependencies complete before dependent helpers run.
This design enables:
- Composability: Combine helpers from different packages without conflicts
- Extensibility: Third-party helpers integrate seamlessly via dependency declarations
- Reliability: Rollback support ensures atomic operations across helper chains
- Observability: Built-in diagnostics and reporter integration for debugging
Type Parameters
TContext
TContext
TInput
TInput
TOutput
TOutput
TReporter
TReporter extends PipelineReporter = PipelineReporter
TKind
TKind extends HelperKind = HelperKind
Parameters
options
CreateHelperOptions<TContext, TInput, TOutput, TReporter, TKind>
Returns
Helper<TContext, TInput, TOutput, TReporter, TKind>
Examples
import { createHelper } from '@wpkernel/pipeline';
// Add PHP opening tag to generated files
const addPHPTag = createHelper({
key: 'add-php-opening-tag',
kind: 'fragment',
mode: 'extend',
priority: 100, // Run early in pipeline
origin: 'wp-kernel-core',
apply: ({ fragment }) => {
fragment.children.unshift({
kind: 'text',
text: '<?php\n',
});
},
});// This helper depends on namespace detection running first
const addNamespaceDeclaration = createHelper({
key: 'add-namespace',
kind: 'fragment',
dependsOn: ['detect-namespace'], // Won't run until this completes
apply: ({ fragment, context }) => {
const ns = context.detectedNamespace;
fragment.children.push({
kind: 'namespace',
name: ns,
});
},
});import { createPipelineCommit, createPipelineRollback } from '@wpkernel/pipeline';
const writeFileHelper = createHelper({
key: 'write-file',
kind: 'builder',
apply: ({ draft, context }) => {
const path = context.outputPath;
const backup = readFileSync(path, 'utf-8'); // Capture current state
writeFileSync(path, draft);
return {
commit: createPipelineCommit(
() => context.reporter.info(`Wrote ${path}`)
),
rollback: createPipelineRollback(
() => writeFileSync(path, backup), // Restore on error
() => context.reporter.warn(`Rolled back ${path}`)
),
};
},
});const formatCodeHelper = createHelper({
key: 'format-code',
kind: 'builder',
dependsOn: ['write-file'],
apply: async ({ artifact, context }) => {
try {
const formatted = await prettier.format(artifact, {
parser: 'php',
});
return { artifact: formatted };
} catch (error) {
context.reporter.error('Formatting failed', { error });
throw error;
}
},
});