dorfteich/fixtures/import
Claude Fable 5 09abda3ada
Some checks failed
CI / Lint, typecheck, test (push) Failing after 52s
CI / Auth e2e pack (push) Has been skipped
CI / Import/export fidelity gate (push) Has been skipped
CI / Build container images (push) Has been skipped
CD / Build and push images (push) Failing after 1m36s
CD / Deploy to Test (push) Has been skipped
CD / Smoke tests against Test (push) Has been skipped
CD / Promote to Int (push) Has been skipped
Obsidian vault transform module (#116)
Pure functions from vault ZIP to import plan — no DB, no DI:

- parseVaultZip: fflate unzip with the plugin-package protections
  (zip-slip rejection, incremental unpacked ceiling 256 MiB,
  parameterized for tests); dot-directories like .obsidian/ skipped;
  deterministic ordering.
- extractFrontmatter: leading --- block, tags:/tag: in scalar, inline-
  array, and block-list forms; strip mode drops the block, preserve
  re-emits it as a fenced yaml code block.
- extractInlineTags: fence- and inline-code-aware #tag / #nested/tag
  extraction and removal (headings and pure numbers untouched).
- rewriteLinks: [[Name]], [[Name|Display]], [[Name#Heading]] (fragment
  stripped), [[folder/Name]] (path match beats basename) → the FINAL
  slug with the human name as display; unresolvable → slugified
  phantom; ![[img]] and relative ![](path) → vault-asset: placeholders
  the uploader resolves (#117); non-image embeds → italic filename +
  page attachment; SVG deliberately stays an attachment (never inline,
  security.md); note embeds degrade to plain wikilinks.
- planFolders: folder chains merged at the deepest levels to fit
  MAX_PAGE_DEPTH below the mount page (merged titles read c/d).
- planSlugs: -n suffixing against existing ∪ batch; duplicate
  basenames resolve to the lexicographically first vault path.
- planVaultImport ties it together into containers + notes + the
  referenced-asset set.

Fixture vault under fixtures/import/obsidian-vault/ (umlauts,
duplicate basenames, nested tags, deep folders, embeds, code traps);
13 unit tests colocated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 16:51:31 +02:00
..
obsidian-vault Obsidian vault transform module (#116) 2026-07-14 16:51:31 +02:00
article.docx Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
article.docx.expected.md Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
article.odt Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
article.odt.expected.md Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
article.src.html Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
formatting.docx Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
formatting.docx.expected.md Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
formatting.odt Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
formatting.odt.expected.md Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
formatting.src.html Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
README.md Add import/export fidelity gate to CI (#69) 2026-07-10 13:59:10 +02:00

Import fixture corpus (issue #63, ADR 0009)

Representative .docx/.odt documents and the Markdown our import pipeline is expected to produce from them. import.fixtures.test.ts runs the real two-pass pandoc conversion over each and asserts the result, so a change in behaviour (ours or pandoc's) surfaces as a snapshot diff to review — not a silent regression. This suite is part of the CI fidelity gate (issue #69); see ../README.md for the fidelity contract and the fixture-first bug process (how a fidelity bug becomes a new corpus fixture).

Files

For each document <name> and format <ext> (docx, odt):

  • <name>.<ext> — the source document.
  • <name>.<ext>.expected.md — the Markdown the pipeline produces, with every embedded image's data: URI normalised to the literal data:embedded-image (the base64 payload is volatile and not what the snapshot is pinning).

article covers headings, paragraphs, bold/italic, a link, a bullet list with nesting, an ordered list, an embedded image, and a table. formatting covers strikethrough, inline code, a blockquote, and three levels of nesting.

Fidelity notes (structure, not layout — ADR 0009)

  • ODT images lose their alt text and ODT tables lose their header row: pandoc's HTML→ODT writer does not encode either, so the source documents genuinely lack them. The DOCX variants keep both. This is a pinned pandoc limitation, not an import bug — extend the corpus rather than chasing it.

Limits (ADR 0009)

An uploaded document may be at most 25 MiB (MAX_CONVERSION_INPUT_BYTES), and each of the two conversion passes may run for at most 60 s (CONVERSION_TIMEOUT_MS). A ~50-page document converts well inside that ceiling (import.fixtures.test.ts asserts it); a document that exceeds the timeout fails the job with converter_timeout.

Regenerating

The documents and snapshots are generated with the pinned pandoc/core:3.6 (the production sidecar) so the snapshots match CI; a different pandoc version wraps lists and pads tables differently. scripts/gen-import-fixtures.mjs regenerates everything against a reachable pandoc sidecar (PANDOC_URL).