How the packages fit together
packages/ holds ten libraries, published internally under the @morph-mapper/* scope. Together they power the template editor: a tool for taking a source file (PDF, table, XML, text, email, or JSON) and visually building a mapping into structured output data. This page is a map of how those ten libraries depend on one another, based on their actual imports, so you know which package to open for a given change.
At a glance
typesis the shared data model almost everything else imports.context,utils,shared-i18nare small, standalone foundations.ui,schema-serialization,pluginsbuild on the foundations only.file-viewerrenders the source file;node-inputsandnode-logicbuild the node editor on top of it.- Jump straight to Where do I look for X? if you already know what you're trying to change.
The dependency graph
Grouping the packages by who they import from @morph-mapper/* gives four layers. This diagram (and the breakdown below it) reflects the imports found in source today — not a design document nobody's kept in sync with the code.
shared-i18n has no arrows because nothing in packages/ imports it — it's consumed directly by the apps. Click any box to jump to that package's reference. Full detail on each edge:
Foundations — no dependencies on sibling packages
types— the shared data model: tree nodes, entry types, schema variants, graph/port shapes, and the Zod DTOs for operators/templates/users. Nearly every other package imports from here.utils— generic helpers (getKeys,getEntries,parseOutput,replaceEscapedCharacter, ...) used across the codebase.context— one factory,createContext, for pairing a Zustand store with a React Provider scoped to a subtree.shared-i18n— i18next bootstrap and translation strings. Not imported by any other package here; it's consumed directly by apps.
Built on the foundations only
ui— shared presentational components. Importstypes(e.g.isZodEnum) andutils(e.g.parseOutput).schema-serialization— converts thetypestree model to and from a JSON-safe form. Importstypesandutils.plugins— the plugin framework and the built-in plugins. Importstypes(TreeNode,EntryType,SchemaVariant) andutils, but notcontext— plugin state is a single global Zustand store (useGlobalPluginStore) rather than a per-subtree one. See Plugin framework for why.
The file being mapped
file-viewer— renders the source file and lets the user select parts of it. Importstypes(to pick a viewer bySchemaVariant) andcontext(its store is created with@morph-mapper/context'screateContext).
The node editor's input layer
node-inputs— maps theInputenum (fromtypes) to form components. Importsuifor icon actions and, notably,file-viewer'suseFileInteractionhook — some inputs (text selector, cell selector) let the user click directly into the file view to fill a field.node-logic— per-filetype rule sets that decide what a node can do. Importstypes,utils, andnode-inputs(it referencesInputvalues when describing which widget a rule's option should render with).
Where do I look for X?
| I want to... | Start in |
|---|---|
| Change what a node in the graph is allowed to do for a given file type | node-logic |
| Add a new kind of form input for a node's configuration | node-inputs |
| Change how a source file is displayed or selected | file-viewer, file-viewer selection |
| Write or modify a plugin | plugins framework, built-in plugins |
| Change the shape of a tree node, entry, or schema variant | types data model |
| Change how a template is saved to or loaded from the database | schema-serialization |
| Add or change a shared UI component (button, badge, cell) | ui |
| Add a new scoped store for a package | context |
Look up a term you don't recognize (TreeNode, SchemaVariant, PathMode, ...) | Glossary |
Exact signatures
This guide describes relationships, not APIs. For function signatures, types, and props, see the Reference section, generated from source via TypeDoc.