> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# Understanding walkerOS Mapping

## Overview[​](#overview "Direct link to Overview")

Mapping transforms data at multiple points in the walkerOS flow:

1. **Source → Collector**: Transform raw input (HTTP requests, dataLayer pushes) into walkerOS events
2. **Collector → Destination**: Transform walkerOS events into vendor-specific formats

**Core principle:** Mapping is the universal transformation layer. Same strategies work everywhere in the flow.

## Core Functions[​](#core-functions "Direct link to Core Functions")

See [packages/core/src/mapping.ts](https://github.com/elbwalker/walkerOS/blob/main/packages/core/src/mapping.ts) for implementation.

| Function                                        | Purpose                                     |
| ----------------------------------------------- | ------------------------------------------- |
| `getMappingEvent(event, rules)`                 | Find mapping rule for an event              |
| `getMappingValue(value, data, options)`         | Transform a value using mapping config      |
| `processEventMapping(event, config, collector)` | Unified processing for sources/destinations |

### processEventMapping Flow[​](#processeventmapping-flow "Direct link to processEventMapping Flow")

```
1. Apply config.policy (modifies event)

2. Find matching rule via getMappingEvent()

3. Apply rule.policy (modifies event)

4. Transform config.data (global)

5. Check rule.ignore (short-circuits if true)

5b. Read rule.silent (informational - destination honors it)

6. Override event.name if rule.name

7. Transform rule.data (event-specific)
```

***

## Configuration Hierarchy[​](#configuration-hierarchy "Direct link to Configuration Hierarchy")

### Mapping.Config (Top Level)[​](#mappingconfig-top-level "Direct link to Mapping.Config (Top Level)")

```
interface Config {

  consent?: Consent; // Required consent for ALL events

  data?: Value; // Global data transformation

  include?: string[]; // Event sections to flatten into context.data

  policy?: Policy; // Pre-processing for ALL events

  mapping?: Rules; // Event-specific rules

}
```

#### Mapping.Config.include[​](#mappingconfiginclude "Direct link to Mapping.Config.include")

`include` lists event sections to **flatten** into the destination's `PushContext.data` before the rule runs. Sections are top-level keys of the event (`globals`, `user`, `consent`, `data`, `context`, `nested`, `source`, `custom`). The runtime helper `flattenIncludeSections` (in `packages/core/src/include.ts`) handles the merge.

Use this when your mapping needs values from multiple event sections without plumbing each path through a `key:`/`map:` config. `include` is also available on `Mapping.Rule` (rule-level overrides config-level).

```
{

  include: ['globals', 'user'],

  mapping: {

    page: {

      view: {

        // user.id and globals.* are now reachable via top-level paths in

        // data/key/map values, e.g. `key: 'id'` for user.id.

        data: { map: { user_id: 'id', site: 'language' } },

      },

    },

  },

}
```

### Mapping.Rule (Per Event)[​](#mappingrule-per-event "Direct link to Mapping.Rule (Per Event)")

```
interface Rule {

  name?: string; // Override event name

  data?: Value; // Event-specific data transformation

  include?: string[]; // Event sections to flatten into context.data (rule-level)

  ignore?: boolean; // Skip this event entirely (no processing, no push)

  silent?: boolean; // Process settings side effects, skip destination default push

  policy?: Policy; // Event-specific pre-processing

  condition?: Function; // Match condition (for arrays)

  consent?: Consent; // Required consent for this rule

  settings?: unknown; // Custom event configuration

  batch?: number; // Batch size for grouping

  extend?: RulePatch; // Config-layer merge onto a package-shipped default rule

  remove?: string[]; // Output-layer: dotted paths stripped from the final payload

}
```

#### `extend` and `remove` (patching package-shipped rules)[​](#extend-and-remove-patching-package-shipped-rules "Direct link to extend-and-remove-patching-package-shipped-rules")

Some packages ship their own default mapping rules. A user rule at the same key normally replaces the default in full. Two keywords change that:

* **`extend`** (config layer): a partial rule deep-merged onto the package-shipped default at init, before any event is evaluated. A `null` value clears an inherited field. Lets you add or override one field while keeping the rest.
* **`remove`** (output layer): dotted paths stripped from the produced payload after evaluation, applied last. Useful for dropping PII or vendor-reserved fields without rewriting the full rule.

A rule with **neither** keyword keeps the standard replace behavior.

See the [website mapping docs](https://www.walkeros.io/docs/mapping/rule.md#patching-package-shipped-rules) for the authoritative reference and the GA4 example.

```
{

  "purchase": {

    "extend": {

      "data": { "map": { "affiliation": "params.ep.affiliation" } }

    },

    "remove": ["currency"]

  }

}
```

### Silent vs Ignore[​](#silent-vs-ignore "Direct link to Silent vs Ignore")

Both flags control rule behavior but have different semantics:

* `ignore: true` - the rule matched but **nothing happens**. No data transform, no destination call, no side effects. Use for suppression.
* `silent: true` - the rule matched and the destination `push()` **is** called. `settings.identify`, `settings.revenue`, `settings.group`, etc. still run. Only the destination's default forwarding call (e.g. `track()`, `capture()`, `event()`) is suppressed. Use for "identify without an event" style flows.

If both flags are set on the same rule, `ignore` wins.

Common use case: a `user login` event that should call `amplitude.identify()` but should not create a separate `track("user login")` event in Amplitude.

### Mapping.ValueConfig (Value Extraction)[​](#mappingvalueconfig-value-extraction "Direct link to Mapping.ValueConfig (Value Extraction)")

```
interface ValueConfig {

  key?: string; // Extract from path

  value?: Primitive; // Static fallback value

  fn?: Function; // Custom transformation

  map?: Record; // Object transformation

  loop?: [path, config]; // Array transformation

  set?: Value[]; // Create array from values

  condition?: Function; // Conditional extraction

  consent?: Consent; // Consent-gated extraction

  validate?: Function; // Value validation

}
```

***

## Event Matching[​](#event-matching "Direct link to Event Matching")

Match events to transformation rules by entity and action.

```
const mapping = {

  // Exact match: "product view" → view_item

  product: {

    view: { name: 'view_item' },

    add: { name: 'add_to_cart' },

  },



  // Wildcard action: "foo *" → foo_interaction

  foo: {

    '*': { name: 'foo_interaction' },

  },



  // Wildcard entity: "* click" → generic_click

  '*': {

    click: { name: 'generic_click' },

  },

};
```

### Conditional Mapping (Array)[​](#conditional-mapping-array "Direct link to Conditional Mapping (Array)")

Array of rules - first matching condition wins:

```
order: {

  complete: [

    {

      condition: (event) => event.data?.value > 100,

      name: 'high_value_purchase',

    },

    { name: 'purchase' }, // Fallback (no condition)

  ],

}
```

**JSON with $code:**

```
{

  "order": {

    "complete": [

      {

        "condition": "$code:(event) => event.data?.value > 100",

        "name": "high_value_purchase"

      },

      { "name": "purchase" }

    ]

  }

}
```

***

## Value Mapping Strategies[​](#value-mapping-strategies "Direct link to Value Mapping Strategies")

Common patterns shown below. For detailed examples of all 12 strategies, see [value-strategies.md](https://github.com/elbwalker/walkerOS/blob/main/skills/walkeros-understanding-mapping/value-strategies.md).

### Essential Patterns[​](#essential-patterns "Direct link to Essential Patterns")

```
// Key extraction (string shorthand)

'data.price'                              // → event.data.price



// Key with fallback

{ key: 'data.currency', value: 'USD' }    // Use USD if missing



// Static value

{ value: 'USD' }



// Function transform

{ fn: (event) => event.data.price * 100 } // Convert to cents



// Object map

{ map: { item_id: 'data.id', item_name: 'data.name' } }



// Array loop

{ loop: ['nested', { map: { item_id: 'data.id' } }] }



// Loop with "this" (single item as array)

{ loop: ['this', { map: { item_id: 'data.id' } }] }



// Set (create array)

{ set: ['data.id'] }                      // → ["SKU-123"]



// Fallback chain: Value[] at any value position (first defined value wins)

[{ key: 'data.sku' }, { key: 'data.id' }, { value: 'unknown' }]



// Consent-gated

{ key: 'user.email', consent: { marketing: true } }



// Validate

{ key: 'data.email', validate: (v) => v.includes('@') }
```

***

## Policy (Pre-Processing)[​](#policy-pre-processing "Direct link to Policy (Pre-Processing)")

Policy modifies the event BEFORE mapping rules are applied. Use for:

* Adding computed fields
* Normalizing data structure
* Consent-gated field injection

### Config-Level Policy[​](#config-level-policy "Direct link to Config-Level Policy")

Applied to ALL events:

```
config: {

  policy: {

    'user_data.external_id': 'user.id',

    'custom_data.server_processed': { value: true },

  },

  mapping: { /* ... */ }

}
```

### Event-Level Policy[​](#event-level-policy "Direct link to Event-Level Policy")

Applied after config policy, only for specific event:

```
mapping: {

  order: {

    complete: {

      policy: {

        'enriched.total_cents': {

          fn: (event) => Math.round(event.data.total * 100)

        }

      },

      name: 'purchase',

      data: { /* ... */ }

    }

  }

}
```

### Policy with Consent[​](#policy-with-consent "Direct link to Policy with Consent")

```
{

  "policy": {

    "user_data.em": {

      "key": "user.email",

      "consent": { "marketing": true }

    }

  }

}
```

***

## Rule Features[​](#rule-features "Direct link to Rule Features")

### Ignore Events[​](#ignore-events "Direct link to Ignore Events")

```
mapping: {

  test: { '*': { ignore: true } },  // Ignore all test events

}
```

### Batch Processing[​](#batch-processing "Direct link to Batch Processing")

To batch **all** of a destination's events, set `config.batch` (no mapping rule needed):

```
config: {

  batch: { size: 5 },  // Flush after every 5 events (a bare number is the wait window in ms)

}
```

A rule-level `batch` batches only that entity-action into its own buffer and overrides `config.batch` per field:

```
mapping: {

  order: {

    complete: {

      batch: { wait: 1000 },  // Only order complete batches, with a 1s debounce

    }

  }

}
```

### Custom Settings[​](#custom-settings "Direct link to Custom Settings")

```
mapping: {

  order: {

    complete: {

      name: 'purchase',

      settings: { priority: 'high', retryCount: 3 }

    }

  }

}
```

***

## $code: Prefix (JSON Configs)[​](#code-prefix-json-configs "Direct link to $code: Prefix (JSON Configs)")

The `$code:` prefix enables JavaScript functions in JSON configurations:

```
{

  "fn": "$code:(event) => event.data.price * 100",

  "condition": "$code:(event) => event.data?.value > 100",

  "validate": "$code:(value) => value > 0"

}
```

**Important:** The `$code:` prefix is processed by the CLI bundler. It converts JSON strings to actual JavaScript functions during build.

### Function Signatures[​](#function-signatures "Direct link to Function Signatures")

All mapping callbacks share `(value, context)`. The second argument is a `Mapping.Context` object (see "Context object" below).

| Context             | Signature                     |
| ------------------- | ----------------------------- |
| `fn`                | `(value, context) => result`  |
| `condition` (value) | `(value, context) => boolean` |
| `condition` (rule)  | `(event, context) => boolean` |
| `validate`          | `(value, context) => boolean` |
| `loop` condition    | `(value, context) => boolean` |

One-arg signatures like `(value) => value.toUpperCase()` continue to work, TypeScript ignores the unused second arg.

### Context object[​](#context-object "Direct link to Context object")

| Field       | Type                            | Required | Description                                |
| ----------- | ------------------------------- | -------- | ------------------------------------------ |
| `event`     | `WalkerOS.DeepPartialEvent`     | yes      | The root event being mapped                |
| `mapping`   | `Mapping.Value \| Mapping.Rule` | yes      | The surrounding mapping config (or rule)   |
| `collector` | `Collector.Instance`            | yes      | Active collector, use for `push` and queue |
| `logger`    | `Logger.Instance`               | yes      | Use for `info`/`warn`/`error`/`debug`      |
| `consent`   | `WalkerOS.Consent` (optional)   | no       | Resolved consent at this evaluation point  |

***

## Quick Reference[​](#quick-reference "Direct link to Quick Reference")

### Value Extraction Cheatsheet[​](#value-extraction-cheatsheet "Direct link to Value Extraction Cheatsheet")

| Pattern                       | Result                         |
| ----------------------------- | ------------------------------ |
| `"data.id"`                   | Extract `event.data.id`        |
| `{ value: "USD" }`            | Static `"USD"`                 |
| `{ key: "x", value: "y" }`    | Extract `x`, fallback to `"y"` |
| `{ fn: (e) => ... }`          | Custom function                |
| `{ map: {...} }`              | Object transformation          |
| `{ loop: ["nested", {...}] }` | Array transformation           |
| `{ loop: ["this", {...}] }`   | Single-item as array           |
| `{ set: ["a", "b"] }`         | Create array `[valA, valB]`    |
| `[m1, m2, m3]`                | Fallback chain                 |
| `{ consent: {...} }`          | Consent-gated                  |
| `{ condition: fn }`           | Conditional                    |
| `{ validate: fn }`            | Validated                      |

### Rule Features Cheatsheet[​](#rule-features-cheatsheet "Direct link to Rule Features Cheatsheet")

| Feature     | Purpose                                                                 |
| ----------- | ----------------------------------------------------------------------- |
| `name`      | Override event name                                                     |
| `data`      | Transform event data                                                    |
| `ignore`    | Skip event entirely (no processing, no push)                            |
| `silent`    | Run settings side effects, skip default forwarding                      |
| `policy`    | Pre-process event                                                       |
| `condition` | Match condition (arrays)                                                |
| `consent`   | Required consent                                                        |
| `settings`  | Custom configuration                                                    |
| `batch`     | Batch size                                                              |
| `extend`    | Config-layer merge onto a package-shipped default (null clears a field) |
| `remove`    | Output-layer: dotted paths stripped from the final payload              |

### Config Features Cheatsheet[​](#config-features-cheatsheet "Direct link to Config Features Cheatsheet")

| Feature   | Purpose                       |
| --------- | ----------------------------- |
| `consent` | Required consent (all events) |
| `data`    | Global data transformation    |
| `policy`  | Global pre-processing         |
| `mapping` | Event-specific rules          |

***

## Complete Examples[​](#complete-examples "Direct link to Complete Examples")

For full destination configuration examples (TypeScript + JSON), see [complete-examples.md](https://github.com/elbwalker/walkerOS/blob/main/skills/walkeros-understanding-mapping/complete-examples.md).

***

## Mapping at the Transformer Position[​](#mapping-at-the-transformer-position "Direct link to Mapping at the Transformer Position")

`Mapping.Config` accepts the same shape at three positions in the flow, but the semantic differs by position:

| Position    | What the mapping produces                                 |
| ----------- | --------------------------------------------------------- |
| Source      | A walkerOS event from raw input                           |
| Transformer | A mutated walkerOS event that continues through the chain |
| Destination | A vendor-shaped payload that the destination consumes     |

When a transformer step declares only a `mapping` (no `code`, no `package`), the collector synthesizes a push that runs `processEventMapping` against each event. Same keyword as the destination field, different semantic at this step position. See [walkeros-understanding-transformers](https://www.walkeros.io/skills/walkeros-understanding-transformers.md) for the pass-through-step model.

### Which fields apply at the transformer position[​](#which-fields-apply-at-the-transformer-position "Direct link to Which fields apply at the transformer position")

Only **event-mutating** fields run; vendor-payload fields are no-ops with a one-time init warning:

| Field                    | Transformer position                                                              |
| ------------------------ | --------------------------------------------------------------------------------- |
| `policy`                 | Applies, pre-processes the event before rule matching                             |
| `include`                | Applies, flattens event sections into mapping context                             |
| `mapping[].policy`       | Applies, per-event policy                                                         |
| `mapping[].name`         | Applies, **renames** the event (mutation is observable downstream)                |
| `mapping[].ignore`       | Applies, drops the event **from the chain entirely** (no downstream step sees it) |
| `mapping[].consent`      | Applies, consent gate                                                             |
| `data`, `mapping[].data` | Ignored at this position (event mutation does not produce a vendor payload)       |
| `mapping[].silent`       | Ignored at this position (destination-only concept)                               |

Note the `ignore: true` semantic shift: at a **destination** it skips delivery to that destination only; at a **transformer step** it drops the event from the chain so no downstream step (transformer or destination) sees it.

```
{

  "transformers": {

    "redactPII": {

      "mapping": {

        "policy": {

          "user.email": { "value": "[redacted]" }

        },

        "mapping": {

          "test": {

            "*": { "ignore": true }

          },

          "order": {

            "complete": { "name": "purchase" }

          }

        }

      }

    }

  }

}
```

## Where Mapping Lives[​](#where-mapping-lives "Direct link to Where Mapping Lives")

| Location                                   | Purpose                                   |
| ------------------------------------------ | ----------------------------------------- |
| Source config                              | Transform raw input → walkerOS events     |
| Transformer step config                    | Mutate walkerOS events in-flight          |
| Destination config                         | Transform walkerOS events → vendor format |
| `packages/core/src/mapping.ts`             | Core mapping functions                    |
| `packages/core/src/types/mapping.ts`       | Type definitions                          |
| `packages/cli/examples/flow-complete.json` | Comprehensive example (53 features)       |

***

## Related Skills[​](#related-skills "Direct link to Related Skills")

* [walkeros-understanding-events](https://www.walkeros.io/skills/walkeros-understanding-events.md) - Event structure
* [walkeros-understanding-destinations](https://www.walkeros.io/skills/walkeros-understanding-destinations.md) - Destination-side mapping
* [walkeros-understanding-transformers](https://www.walkeros.io/skills/walkeros-understanding-transformers.md) - Transformer-position mapping and pass-through-step variants
* [walkeros-mapping-configuration](https://www.walkeros.io/skills/walkeros-mapping-configuration.md) - Recipes and patterns

**Source Files:**

* [packages/core/src/mapping.ts](https://github.com/elbwalker/walkerOS/blob/main/packages/core/src/mapping.ts) - Implementation
* [packages/core/src/types/mapping.ts](https://github.com/elbwalker/walkerOS/blob/main/packages/core/src/types/mapping.ts) - Types

**Detailed References:**

* [value-strategies.md](https://github.com/elbwalker/walkerOS/blob/main/skills/walkeros-understanding-mapping/value-strategies.md) - All 12 value extraction strategies with examples
* [complete-examples.md](https://github.com/elbwalker/walkerOS/blob/main/skills/walkeros-understanding-mapping/complete-examples.md) - Full destination config examples

**Examples:**

* [packages/cli/examples/flow-complete.json](https://github.com/elbwalker/walkerOS/blob/main/packages/cli/examples/flow-complete.json) - Comprehensive example
* [packages/cli/examples/flow-complete.md](https://github.com/elbwalker/walkerOS/blob/main/packages/cli/examples/flow-complete.md) - Feature inventory
