@judo/model-parser
v0.1.1
Published
XMI/XML parser for JUDO UI models
Readme
@judo/model-parser
XMI/XML parser for JUDO UI models
Purpose
Parses ECore-based XMI/XML model files into typed TypeScript objects (Application and its subtree), applying EMF default values, type discrimination, boolean/numeric coercion, and containment tree building. This is a pure data-processing layer with zero React dependencies.
Architecture Layer
Layer 1 (Foundation) — converts raw XML into the typed model objects consumed by all higher layers.
Dependencies
@judo/model-api— TypeScript type definitionsfast-xml-parser— XML parsing engine
File Structure
src/
├── index.ts # Public barrel exports
├── parser.ts # Core XML→Application[] parser
├── containment-builder.ts # Visual element tree builder + parent refs
├── emf-defaults.ts # EMF default value constants & applicators
├── reference-resolver.ts # XMI cross-reference indexer/resolver
├── type-discriminator.ts # xsi:type → @type mapping
├── parser.test.ts
├── parser.performance.test.ts
├── containment-builder.test.ts
├── emf-defaults.test.ts
├── reference-resolver.test.ts
└── type-discriminator.test.tsExports Summary
Core Parser
| Export | Kind | Description |
| -------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| parseModel(xml) | function | Main entry point. Parses an XMI/XML string into Application[]. Handles both multi-actor (<xmi:XMI> wrapper) and single-actor (direct <ui:Application> root) formats. |
| parseModelWithOptions(xml, options?) | function | Advanced parse. Returns ParseResult with element index and optional reference validation errors. |
| ModelParseError | class | Error thrown when XML structure is invalid. Includes a path field. |
| ModelReferenceError | class | Error thrown when a cross-reference cannot be resolved. Carries sourceId and targetRef. |
| ParseOptions | interface | Options for parseModelWithOptions (validateReferences, preserveRawAttributes). |
| ParseResult | interface | Extended parse result: applications, element index map, and validation errors. |
| ParseError | interface | Describes a parse/validation error (type, message, elementId, referencedId, path). |
Reference Resolver
| Export | Kind | Description |
| ------------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| ReferenceResolver | class | Indexes parsed elements by xmi:id and resolves cross-references. Methods: indexElement(), resolve(), getIndex(), clear(), indexTree(). |
Containment Builder
| Export | Kind | Description |
| --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| buildContainmentTree(container) | function | Recursively builds a visual element containment tree from a parsed container. Processes Flex, TabController, Table, Link, ButtonGroup, and all input types. |
| attachParentReferences(root, parent?) | function | Mutates a visual tree by attaching __parent back-references for upward navigation. |
| getParent(element) | function | Retrieves the __parent reference from a visual element. Returns undefined if none attached. |
Type Discriminator
| Export | Kind | Description |
| --------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| TYPE_MAP | constant | Maps ~85 fully-qualified XMI xsi:type values to simplified @type strings. |
| discriminateType(element) | function | Looks up xsi:type in TYPE_MAP. Falls back to stripping the namespace prefix. Returns string \| undefined. |
| inferTypeFromTag(tagName) | function | Infers a type from an XML tag name when xsi:type is absent. |
EMF Defaults (~30 default constant objects)
Default value constants for all visual element types, inputs, structural elements, and data types:
| Category | Examples |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Visual elements | VISUAL_ELEMENT_DEFAULTS, FLEX_DEFAULTS, PAGE_CONTAINER_DEFAULTS, TABLE_DEFAULTS, LINK_DEFAULTS |
| Inputs | INPUT_DEFAULTS, TEXT_INPUT_DEFAULTS, TEXT_AREA_DEFAULTS, NUMERIC_INPUT_DEFAULTS, DATE_TIME_INPUT_DEFAULTS, TIME_INPUT_DEFAULTS, CHECKBOX_DEFAULTS, SWITCH_DEFAULTS |
| Structural | PAGE_DEFINITION_DEFAULTS, APPLICATION_DEFAULTS, ACTION_DEFAULTS, ACTION_DEFINITION_DEFAULTS, CONFIRMATION_DEFAULTS, OPTION_DEFAULTS |
| Data | CLASS_TYPE_DEFAULTS, RELATION_TYPE_DEFAULTS, ATTRIBUTE_TYPE_DEFAULTS, OPERATION_TYPE_DEFAULTS, REFERENCE_TYPE_DEFAULTS, BINARY_TYPE_DEFAULTS |
| Sub-elements | SIZE_DEFAULTS, SIZE_CONSTRAINT_DEFAULTS, FRAME_DEFAULTS |
Applicator functions:
| Function | Description |
| ---------------------------------------------- | ---------------------------------------------------------------------- |
| applyTypeDefaults(element, type) | Applies EMF defaults based on @type. Only sets undefined properties. |
| applyPropertyDefaults(element, propertyName) | Applies defaults to contained objects based on property name. |
| applyActionDefinitionDefaults(element) | Applies defaults to any action definition element. |
| applyPageDefinitionDefaults(element) | Applies defaults to page definition elements. |
| applyActionDefaults(element) | Applies defaults to action elements. |
Mapping constants:
| Constant | Description |
| ----------------------- | ------------------------------------------------------------------- |
| TYPE_DEFAULTS_MAP | Maps @type discriminators to their default objects (~42 entries). |
| PROPERTY_DEFAULTS_MAP | Maps property names to their default objects. |
Key Patterns
- Two-pass parsing: XML is first parsed by
fast-xml-parser, then a second pass adds@typediscriminators, applies EMF defaults, coerces types, and setseContainerback-references - In-place mutation for performance: All default application and coercion functions mutate objects in place (safe because they're freshly parsed transients)
- EMF default inheritance chain: Default constants use spread inheritance mirroring the ECore type hierarchy (
VISUAL_ELEMENT_DEFAULTS→FLEX_DEFAULTS→PAGE_CONTAINER_DEFAULTS) - Explicit boolean/numeric property sets: Curated sets of property names drive targeted coercion from
"true"/"false"→booleanand numeric strings →number eContainerback-references: DuringtransformElement, every nested child gets aneContainerproperty pointing to its parent, enabling EMF-style upward containment navigation. Additionally,attachParentReferencessets__parentfor explicit parent navigation viagetParent()- Dual format support: Handles both
<xmi:XMI>wrapper (multi-actor) and bare<ui:Application>root (single-actor) model formats - Tag-name-driven array coercion: Ensures collection properties are always arrays even when the XML contains a single child element
