Skip to content

Renderers

All renderers are pure functions — they take a DiffResult (or XML strings for renderXml) and return a string.

detectFormat(input)

Detects the rendered format of a dmn-diff string output without parsing its content.

typescript
function detectFormat(input: string): DiffFormat

type DiffFormat = 'json' | 'semantic' | 'rows' | 'xml'

ANSI color codes are stripped before detection, so colored CLI output works as-is.

typescript
import { detectFormat } from '@veridtools/dmn-diff'

const output = execSync('dmn-diff before.dmn after.dmn').toString()
const format = detectFormat(output) // 'semantic' | 'rows' | 'json'

Detection rules:

  • json — trimmed input starts with {
  • xml — contains <?xml (present in all DMN files), or is exactly (no differences) (the renderXml no-change output)
  • rows — contains + [type] / - [type] lines, or is exactly (no changes) (the renderRows no-change output)
  • semantic — everything else, including No changes detected (the renderSemantic no-change output)

Use detectFormat when your tooling receives dmn-diff output from an external process and needs to know which parser to apply, or simply to validate that a pipe is producing the expected format.

Composing with tokenize

detectFormat and tokenize use the same detection logic. If you need both the format and the tokens, call them separately:

typescript
const format = detectFormat(output)  // 'json' | 'semantic' | 'rows'
const tokens = tokenize(output)      // DiffToken[]

renderSemantic(result, options?)

Default output mode. Human-readable prose with severity markers.

typescript
function renderSemantic(result: DiffResult, options?: RenderOptions): string

interface RenderOptions {
  color?: boolean  // default: false
}

Output includes:

  • Optional file header (from.dmn → to.dmn)
  • Warning count for breaking changes
  • Per-change lines with + (added), - (removed), ~ (modified)
  • Field-level details with ⚠ BREAKING / (cosmetic) markers
  • Summary line: N added · N modified · N removed · N unchanged

Pass { color: true } to enable ANSI color output (the CLI does this automatically when writing to a TTY).

renderRows(result, options?)

Row-diff table with + / - prefixes.

typescript
function renderRows(result: DiffResult, options?: RenderOptions): string

Each field change produces two rows — one for the old value (prefixed -) and one for the new value (prefixed +). Accepts the same RenderOptions as renderSemantic.

renderJson(result)

Serializes the full DiffResult to indented JSON.

typescript
function renderJson(result: DiffResult): string

Equivalent to JSON.stringify(result, null, 2). Suitable for piping to jq or other tools.

renderXml(fromXml, toXml)

Raw line-by-line diff of the original XML strings. Includes DMNDI and all attributes.

typescript
function renderXml(fromXml: string, toXml: string): string

Note: this renderer takes the raw XML strings, not a DiffResult. Use it when you need to inspect layout or attribute-level changes that the semantic diff ignores.

Lines prefixed with + appear only in toXml, lines with - only in fromXml, lines with (two spaces) are common.

tokenize(input)

Converts a DiffResult — or a rendered string — into an ordered stream of DiffToken[]. Tokens are the structured intermediate representation between diff logic and any formatter.

typescript
function tokenize(input: DiffResult | string): DiffToken[]

From a DiffResult

Use this when building a custom renderer (HTML, React, Monaco decorations) without re-implementing diff logic. All semantic information is preserved in the tokens — no access to the original XML needed.

typescript
import { diff, tokenize } from '@veridtools/dmn-diff'

const tokens = tokenize(diff(fromXml, toXml))

for (const token of tokens) {
  if (token.type === 'modified') {
    for (const fc of token.fieldChanges) {
      console.log(fc.field, fc.severity, fc.from, '→', fc.to)
    }
  }
}

From a rendered string

tokenize also accepts the string output of any renderer and parses it back into tokens. The format is detected automatically:

  • JSON (renderJson output) — lossless round-trip; all fields including path and parentId are preserved
  • Semantic (renderSemantic output) — recovers element types, ids, field names, values, and severities
  • Rows (renderRows output) — same as semantic; reconstructs modified tokens by pairing -/+ field lines

ANSI color codes are stripped automatically, so colored CLI output works as-is.

typescript
import { tokenize } from '@veridtools/dmn-diff'
import { execSync } from 'child_process'

// Parse the output of an external dmn-diff invocation
const output = execSync('dmn-diff before.dmn after.dmn --json').toString()
const tokens = tokenize(output)

const breaking = tokens.filter(
  (t) => t.type === 'modified' && t.fieldChanges.some((f) => f.severity === 'breaking'),
)

Lossy formats

Parsing from semantic or rows text is lossy — path and parentId are not present in those outputs and will be empty strings / absent in the resulting tokens. Use JSON output when you need full fidelity.

Token order

header? → (no-changes | breaking-summary? → added|removed|modified… → summary)

renderSemantic and renderRows use tokenize() internally. renderJson and renderXml do not — they operate at a different layer.

Released under the MIT License.