feat(pipeline): IDML parser and intermediate representation#77
Merged
PAMulligan merged 1 commit intoMay 21, 2026
Merged
Conversation
Closes #62. Foundational sub-issue for the InDesign-to-WordPress pipeline (#61). Ships: - `@flavian/pipeline` workspace package (new `packages/*` workspace; this is the first occupant) - `parseIdml(path)` / `parseIdmlBuffer(bytes)` — unzip via fflate, parse XML via fast-xml-parser, resolve Self/ParentStory cross-refs, validate the final shape with zod - IR covering Document, Spread, Page, Frame (discriminated union of TextFrame + ImageFrame), Story, Style, Swatch, Font, MasterSpread - Unit normalizer (pt/pc/mm/cm/in/px → px at configurable DPI, default 96) - Warning collector — non-fatal issues (missing optional resources, dangling style refs, unknown color spaces, empty stories) surface on the IR rather than throwing - CLI: `flavian-parse-idml <file.idml>` (JSON on stdout, warnings on stderr) - 20 tests via `node --test`: happy path (parses full IDML with swatches, fonts, styles, story, spread, master), three malformed cases called out in the issue (missing manifest throws; unknown style refs warn; empty stories produce empty run lists), plus unit conversion coverage Notes on language choice: the issue spec says `ir.ts` but the repo has zero TypeScript today. Used `.js` + JSDoc + zod instead to match the existing `.mjs` + node:test stack. `z.infer` gives any future TS consumer the types for free. Notes on fixtures: built programmatically by `tests/indesign/helpers/build-idml.js` — no binary blobs in git, no InDesign required to maintain or evolve them. The epic's AC for committed `.idml` files lives on #61, not here. CI: extended `pipeline-tests.yml` with a `packages/pipeline/**` path filter and a new job that runs `pnpm --filter @flavian/pipeline test`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #62. Foundational sub-issue for the InDesign-to-WordPress pipeline (#61).
Summary
@flavian/pipelineworkspace package (this PR creates thepackages/*workspace; it's the first occupant)parseIdml(path)/parseIdmlBuffer(bytes)— unzip viafflate, parse XML viafast-xml-parser, resolveSelf/ParentStorycross-references, validate the final shape withzodDocument,Spread,Page,Frame(discriminated union ofTextFrame+ImageFrame),Story,Style,Swatch,Font,MasterSpreadpt/pc/mm/cm/in/px→ px at configurable DPI (default 96)flavian-parse-idml <file.idml>(JSON on stdout, warnings on stderr)node:test: happy path + the three malformed cases the issue calls out (missing manifest throws; unknown style refs warn; empty stories give empty run lists) + unit-conversion coverageDecisions worth flagging
packages/pipeline/src/indesign/ir.ts, but the repo has zero TypeScript today (everything is.mjsESM + JSDoc +node:test). I used.js+ JSDoc + zod so the new package matches the rest of the repo.z.infer<typeof Document>gives any future TS consumer the types for free. Happy to migrate to TS if you'd rather.tests/indesign/helpers/build-idml.js— no binary blobs in git, no InDesign required to maintain them. The epic's "commit.idmlfixtures" AC lives on Add InDesign-to-WordPress conversion pipeline #61, not here.Acceptance criteria (from #62)
.idml, the parser produces a valid IR object that passes schema validation (zod)href+embeddedflag)process.stderr.writefor each)CI
pipeline-tests.ymlgot a new path filter (packages/pipeline/**andpnpm-workspace.yaml) and a new job that runspnpm --filter @flavian/pipeline testvia pnpm + Node 20. Existing bats jobs unchanged.Test plan
pnpm installfrom a clean clone succeeds (workspace resolution)pnpm --filter @flavian/pipeline testreports 20/20 passingnode packages/pipeline/bin/parse-idml.mjs <real-exported.idml>against a real IDML produces JSON with non-emptyswatches,styles, andspreadsPipeline Testsworkflow is green on this PR🤖 Generated with Claude Code