Write a transformer, initializer, or plugin
Extensions are host functions the mapping document calls by name. There are three kinds. Register them at construction:
const mapper = new Mapper({}, { initializers, transformers, plugins })Transformer
Section titled “Transformer”Synchronous. Reshapes a value mid-pipeline. Called by the transform
keyword, by name or as ordered steps:
const transformers = { slugify: (value) => typeof value === 'string' ? value .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/(^-+|-+$)/g, '') : value}/slug: { source: /name, transform: slugify }Signature: (value, context, options?) → value. An object step passes itself
as options.
Initializer
Section titled “Initializer”Synchronous. Runs early, before transforms and validation, and can supply a
value where the input has none. Called by the init keyword:
const initializers = { placeholder: (value) => (value === undefined ? 'TBD' : value)}/subtitle: { source: /subtitle, init: placeholder }Signature: (value, context) → value.
Plugin
Section titled “Plugin”Asynchronous. The only stage where I/O happens. Any descriptor key that names a registered plugin calls it, with that key’s value as options:
const plugins = { publishers: async (options, value) => { const directory = { p1: { name: 'Mapping Press', city: 'Utrecht' }, p2: { name: 'Pointer House', city: 'Reykjavík' } } return directory[value] }}/publisher: { source: /publisherId, publishers: { pointer: /name } }Signature: async (options, value, context) → value. pointer in the
options narrows the result. Multiple plugin keys on one descriptor chain in
document order.
Initializers and transformers must be synchronous. Plugins are the async
stage. All three receive the shared context and can read any scope or
append errors through it. For fetching data from services, see Fetch remote
data.