Files
adf-codec/MIGRATION.md
T
lilleman 6e9e38776f
CI / gate (push) Successful in 38s
CI / publish (push) Has been skipped
Review nits: deactivate the openers a nested link dooms, and pin the refusal order
2026-09-19 02:02:01 +02:00

3.1 KiB

Migrating

From 0.1.0 to 0.2.0

Directives moved under the !adf: prefix. 0.2.0 reads 0.1.0's spelling without an error, turning each directive into text and each carried node into an adf code block. Before 0.2.0 reads any 0.1.0 markdown, convert what is stored or in flight (an open editor, a queue) with the recipe below, and rewrite markdown your code writes or matches (templates, prompts, patterns) by the spelling table. Stored ADF needs no change.

Convert markdown

Read it with 0.1.0 and write it with 0.2.0, installed side by side:

npm install @larvit/adf-codec@0.2.0 adf-codec-0.1@npm:@larvit/adf-codec@0.1.0
import { adfToMarkdown } from '@larvit/adf-codec'
import { markdownToAdf as markdownToAdf010 } from 'adf-codec-0.1'

function migrateMarkdown(stored: string) {
  const parsed = markdownToAdf010(stored)
  return parsed.ok ? adfToMarkdown(parsed.value) : parsed
}
  • Convert each document once: a second pass can return ok while turning the directives into text. Stop 0.1.0 writing first, and record which documents are converted.
  • A refusal carrying position is 0.1.0's parse, which refused that markdown before too. One without is 0.2.0's emit: store the document markdownToAdf010 read as ADF rather than keeping the unconverted markdown.

Spellings

0.1.0 0.2.0
:::panel info … :::, the fence longer per nesting level !adf:panel info … !adf:/panel at any depth
::media {id=a type=file} !adf:media {id=a type=file}
::taskItem TODO {localId=i}: an empty caption, decisionItem, paragraph or taskItem, or an empty heading carrying localId !adf:taskItem TODO {localId=i} then !adf:/taskItem
:mention[@Mikael]{id=5b10a2} !adf:mention[@Mikael]{id=5b10a2}
the adf code fence and :adf{json="…"} the carry code fence and !adf:carry{json="…"}
\: keeps a directive literal \!adf: keeps a directive literal
:adf{json="…"} carrying a link for its collection, id or occurrenceKey !adf:link[text]{attrs}

A colon run and :name[ are plain text now, and adf an ordinary code block language; text holding an unescaped !adf: and a carry fence are claimed instead.

Error codes

unspellable-link leaves ConvertErrorCode: a switch naming it stops compiling, and the link it named converts.

Input 0.1.0 0.2.0
a link whose href or title no CommonMark escape spells, on emit unspellable-link spells !adf:link[text]{attrs}
a link whose text already holds one ([<https://example.com/>](/v)) drops the outer link leaves the outer brackets literal text
a leaf node given a body (media, listBreak) unsupported-node-shape malformed-directive
a node with a block body written as a leaf (panel) unsupported-node-shape malformed-directive
an empty node the ::taskItem spelling row names, written as a leaf parses malformed-directive
an empty node the ::taskItem spelling row names, written with a closer unsupported-node-shape parses