@salesforce/metadata-plugins 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE.txt +27 -0
  2. package/README.md +121 -0
  3. package/dist/index.d.ts +25 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +45 -0
  6. package/dist/plugins/flexipage/FlexipageParser.d.ts +39 -0
  7. package/dist/plugins/flexipage/FlexipageParser.d.ts.map +1 -0
  8. package/dist/plugins/flexipage/FlexipageParser.js +124 -0
  9. package/dist/plugins/flexipage/FlexipageVisualizer.d.ts +19 -0
  10. package/dist/plugins/flexipage/FlexipageVisualizer.d.ts.map +1 -0
  11. package/dist/plugins/flexipage/FlexipageVisualizer.js +27 -0
  12. package/dist/plugins/flexipage/transformer/FlexipageToUemTransformer.d.ts +55 -0
  13. package/dist/plugins/flexipage/transformer/FlexipageToUemTransformer.d.ts.map +1 -0
  14. package/dist/plugins/flexipage/transformer/FlexipageToUemTransformer.js +302 -0
  15. package/dist/plugins/flexipage/transformer/FlexipageTransformerUtils.d.ts +34 -0
  16. package/dist/plugins/flexipage/transformer/FlexipageTransformerUtils.d.ts.map +1 -0
  17. package/dist/plugins/flexipage/transformer/FlexipageTransformerUtils.js +73 -0
  18. package/dist/plugins/flexipage/types/FlexipageMetadata.d.ts +76 -0
  19. package/dist/plugins/flexipage/types/FlexipageMetadata.d.ts.map +1 -0
  20. package/dist/plugins/flexipage/types/FlexipageMetadata.js +7 -0
  21. package/dist/plugins/flexipage/ui/assets/index-DUDC29Wu.js +55 -0
  22. package/dist/plugins/flexipage/ui/assets/index-U3SB2gLS.css +1 -0
  23. package/dist/plugins/flexipage/ui/index.html +16 -0
  24. package/dist/plugins/schema/SchemaParser.d.ts +80 -0
  25. package/dist/plugins/schema/SchemaParser.d.ts.map +1 -0
  26. package/dist/plugins/schema/SchemaParser.js +474 -0
  27. package/dist/plugins/schema/SchemaVisualizer.d.ts +42 -0
  28. package/dist/plugins/schema/SchemaVisualizer.d.ts.map +1 -0
  29. package/dist/plugins/schema/SchemaVisualizer.js +46 -0
  30. package/dist/plugins/schema/types/SchemaERDData.d.ts +91 -0
  31. package/dist/plugins/schema/types/SchemaERDData.d.ts.map +1 -0
  32. package/dist/plugins/schema/types/SchemaERDData.js +7 -0
  33. package/dist/plugins/schema/ui/assets/index-BbY653nW.js +62 -0
  34. package/dist/plugins/schema/ui/assets/index-CbNHuvPl.css +1 -0
  35. package/dist/plugins/schema/ui/index.html +14 -0
  36. package/dist/shared/uem/transformer/ITransformer.d.ts +58 -0
  37. package/dist/shared/uem/transformer/ITransformer.d.ts.map +1 -0
  38. package/dist/shared/uem/transformer/ITransformer.js +7 -0
  39. package/dist/shared/uem/transformer/TransformerRegistry.d.ts +54 -0
  40. package/dist/shared/uem/transformer/TransformerRegistry.d.ts.map +1 -0
  41. package/dist/shared/uem/transformer/TransformerRegistry.js +74 -0
  42. package/dist/shared/uem/transformer/UemBasedVisualizer.d.ts +43 -0
  43. package/dist/shared/uem/transformer/UemBasedVisualizer.d.ts.map +1 -0
  44. package/dist/shared/uem/transformer/UemBasedVisualizer.js +62 -0
  45. package/dist/shared/uem/types/UemMetadata.d.ts +84 -0
  46. package/dist/shared/uem/types/UemMetadata.d.ts.map +1 -0
  47. package/dist/shared/uem/types/UemMetadata.js +7 -0
  48. package/dist/shared/utils/uemTreeUtils.d.ts +51 -0
  49. package/dist/shared/utils/uemTreeUtils.d.ts.map +1 -0
  50. package/dist/shared/utils/uemTreeUtils.js +89 -0
  51. package/dist/shared/utils/vizDependentPathsHelper.d.ts +53 -0
  52. package/dist/shared/utils/vizDependentPathsHelper.d.ts.map +1 -0
  53. package/dist/shared/utils/vizDependentPathsHelper.js +108 -0
  54. package/package.json +111 -0
@@ -0,0 +1 @@
1
+ .react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #777;--xy-background-pattern-lines-color-default: #777;--xy-background-pattern-cross-color-default: #777;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color, var(--xy-edge-label-color-default))}.field-row{display:flex;align-items:center;justify-content:space-between;padding:6px var(--mv-spacing-sm);font-size:var(--mv-font-size-xs);font-family:var(--mv-font-family);border-bottom:1px solid color-mix(in srgb,var(--mv-separator) 40%,transparent);position:relative;transition:background var(--mv-transition-fast)}.field-row--hoverable{cursor:help}.field-row--hovered{background:var(--mv-bg-surface-hover)}.field-row__name{display:flex;align-items:center;gap:var(--mv-spacing-xs);min-width:0;flex:1}.field-row__api-name{color:var(--mv-text-primary);font-weight:var(--mv-font-weight-medium);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.field-row__api-name--relationship{font-weight:var(--mv-font-weight-semibold);color:var(--mv-interactive-primary)}.field-row__type{color:var(--mv-text-secondary);font-family:var(--mv-font-family-mono);font-size:var(--mv-font-size-xs);font-weight:var(--mv-font-weight-normal);flex-shrink:0;margin-left:var(--mv-spacing-sm)}.field-row__tooltip{position:fixed;z-index:10000;transform:translate(-50%,calc(-100% - 8px));background:var(--mv-bg-elevated);color:var(--mv-text-primary);padding:var(--mv-spacing-sm) var(--mv-spacing-md);border-radius:var(--mv-radius-md);font-size:var(--mv-font-size-xs);font-family:var(--mv-font-family);line-height:var(--mv-line-height-normal);max-width:280px;box-shadow:var(--mv-panel-shadow);pointer-events:none;white-space:normal;border:1px solid var(--mv-border-default)}.field-row__handle{width:6px!important;height:6px!important;background:var(--mv-edge-neutral)!important;border:none!important;opacity:0;transition:opacity var(--mv-transition-fast);top:50%!important;right:0!important;transform:translate(50%,-50%)!important}.field-row:hover .field-row__handle{opacity:1}.field-row:last-child{border-bottom:none!important}.object-card{background-color:var(--mv-bg-surface);background-image:linear-gradient(var(--mv-bg-primary),var(--mv-bg-primary));position:relative;border-radius:var(--mv-radius-md);min-width:240px;max-width:280px;box-shadow:var(--mv-panel-shadow);font-size:var(--mv-font-size-xs);overflow:visible;border:1px solid var(--mv-border-default);transition:border-color var(--mv-transition-fast),box-shadow var(--mv-transition-fast),opacity var(--mv-transition-base);opacity:1}.object-card--inactive{opacity:.6}.object-card--active{outline:2px solid var(--mv-interactive-primary)!important;outline-offset:4px!important;box-shadow:var(--mv-shadow-xl)!important;opacity:1}.object-card__active-badge{position:absolute;top:-36px;left:50%;transform:translate(-50%);background:var(--mv-interactive-primary);color:var(--mv-button-primary-fg);padding:2px var(--mv-spacing-md);border-radius:var(--mv-radius-md);font-size:var(--mv-font-size-2xs);font-weight:var(--mv-font-weight-bold);font-family:var(--mv-font-family);white-space:nowrap;box-shadow:var(--mv-shadow-md);z-index:20;border:1px solid var(--mv-interactive-primary);letter-spacing:.5px;max-width:280px;overflow:hidden;text-overflow:ellipsis}.object-card--standard{border-top:4px solid var(--mv-accent-logic)}.object-card--custom{border-top:4px solid var(--mv-accent-data)}.object-card__header{padding:var(--mv-spacing-sm);display:flex;flex-direction:column;align-items:center;justify-content:center;background:transparent;border-bottom:1px solid color-mix(in srgb,var(--mv-separator) 40%,transparent);gap:2px}.object-card__title{color:var(--mv-text-primary);font-weight:var(--mv-font-weight-bold);font-size:var(--mv-font-size-sm);font-family:var(--mv-font-family);line-height:var(--mv-line-height-tight);text-align:center;word-break:break-all}.object-card__subtitle{font-size:var(--mv-font-size-xs);color:var(--mv-text-secondary);font-family:var(--mv-font-family);line-height:var(--mv-line-height-tight);text-align:center}.object-card__subtitle-prefix{color:var(--mv-text-muted);font-size:var(--mv-font-size-2xs);text-transform:uppercase;letter-spacing:.5px}.object-card__fields{display:flex;flex-direction:column;width:100%}.object-card__handle{width:8px!important;height:8px!important;opacity:0!important;pointer-events:none!important}.object-card__handle--standard{background:var(--mv-accent-logic)!important}.object-card__handle--custom{background:var(--mv-accent-data)!important}.react-flow__edge circle{paint-order:stroke fill}.filter-panel{position:absolute;top:100%;right:0;margin-top:var(--mv-spacing-xs);width:280px;background:var(--mv-panel-bg);border:1px solid var(--mv-panel-border);border-radius:var(--mv-radius-lg);box-shadow:var(--mv-shadow-lg);z-index:100;overflow:hidden}.filter-panel__header{padding:var(--mv-spacing-sm) var(--mv-spacing-md);font-size:var(--mv-font-size-xs);font-weight:var(--mv-font-weight-semibold);color:var(--mv-text-secondary);letter-spacing:.5px;text-transform:uppercase;border-bottom:1px solid var(--mv-separator)}.filter-panel__body{padding:var(--mv-spacing-md);display:flex;flex-direction:column;gap:var(--mv-spacing-md)}.filter-panel__section-title{font-size:var(--mv-font-size-sm);font-weight:var(--mv-font-weight-semibold);color:var(--mv-text-primary);margin-bottom:var(--mv-spacing-sm)}.filter-panel__search{position:relative}.filter-panel__search-input{width:100%;padding:var(--mv-spacing-sm) var(--mv-spacing-md);padding-right:36px;background:var(--mv-bg-input);border:1px solid var(--mv-border-input);border-radius:var(--mv-radius-md);color:var(--mv-text-primary);font-size:var(--mv-font-size-sm);font-family:var(--mv-font-family);outline:none;transition:border-color var(--mv-transition-fast)}.filter-panel__search-input::placeholder{color:var(--mv-text-muted)}.filter-panel__search-input:focus{border-color:var(--mv-border-focus)}.filter-panel__search-icon{position:absolute;right:10px;top:50%;transform:translateY(-50%);color:var(--mv-text-muted);pointer-events:none}.filter-panel__checkboxes{display:flex;flex-direction:column;gap:var(--mv-spacing-sm)}.filter-panel__checkbox-label{display:flex;align-items:center;gap:var(--mv-spacing-sm);font-size:var(--mv-font-size-sm);color:var(--mv-text-primary);cursor:pointer}.filter-panel__checkbox{width:18px;height:18px;accent-color:var(--mv-interactive-primary);cursor:pointer;flex-shrink:0}.filter-panel__info-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:var(--mv-radius-full);border:1px solid var(--mv-text-muted);font-size:10px;color:var(--mv-text-muted);margin-left:var(--mv-spacing-xs);cursor:help}.filter-panel__toggles{display:flex;flex-direction:column;gap:var(--mv-spacing-md);padding-top:var(--mv-spacing-sm);border-top:1px solid var(--mv-separator)}.filter-panel__toggle-row{display:flex;align-items:center;gap:var(--mv-spacing-sm)}.filter-panel__toggle{position:relative;width:44px;height:24px;flex-shrink:0}.filter-panel__toggle input{opacity:0;width:0;height:0}.filter-panel__toggle-track{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--mv-text-muted);border-radius:var(--mv-radius-full);cursor:pointer;transition:background var(--mv-transition-fast)}.filter-panel__toggle input:checked+.filter-panel__toggle-track{background:var(--mv-interactive-primary)}.filter-panel__toggle-knob{position:absolute;top:2px;left:2px;width:20px;height:20px;background:#fff;border-radius:var(--mv-radius-full);transition:transform var(--mv-transition-fast);pointer-events:none;box-shadow:var(--mv-shadow-sm)}.filter-panel__toggle input:checked~.filter-panel__toggle-knob{transform:translate(20px)}.filter-panel__toggle-label{font-size:var(--mv-font-size-sm);color:var(--mv-text-primary);cursor:pointer}.filter-panel__footer{padding:var(--mv-spacing-sm) var(--mv-spacing-md) var(--mv-spacing-md)}.filter-panel__clear{background:none;border:none;color:var(--mv-interactive-primary);font-size:var(--mv-font-size-sm);cursor:pointer;padding:0;font-family:var(--mv-font-family)}.filter-panel__clear:hover{text-decoration:underline}.legend-panel{position:absolute;bottom:100%;right:0;margin-bottom:var(--mv-spacing-xs);width:200px;background:var(--mv-panel-bg);border:1px solid var(--mv-panel-border);border-radius:var(--mv-radius-lg);box-shadow:var(--mv-shadow-lg);z-index:100;overflow:hidden}.legend-panel__header{padding:var(--mv-spacing-sm) var(--mv-spacing-md);font-size:var(--mv-font-size-xs);font-weight:var(--mv-font-weight-semibold);color:var(--mv-text-secondary);letter-spacing:.5px;text-transform:uppercase;border-bottom:1px solid var(--mv-separator)}.legend-panel__body{padding:var(--mv-spacing-sm) 0}.legend-panel__item{display:flex;align-items:center;gap:var(--mv-spacing-md);padding:var(--mv-spacing-sm) var(--mv-spacing-md);font-size:var(--mv-font-size-sm);color:var(--mv-text-primary)}.legend-panel__icon{display:flex;align-items:center;justify-content:center;width:28px;flex-shrink:0}.legend-panel__swatch{width:20px;height:14px;border-radius:var(--mv-radius-sm)}.legend-panel__swatch--standard{background:var(--mv-accent-logic)}.legend-panel__swatch--custom{background:var(--mv-accent-data)}.legend-panel__swatch--active{background:transparent;border:2px solid var(--mv-interactive-primary)}.legend-panel__line--lookup{width:24px;border-top:3px dashed var(--mv-edge-neutral)}.legend-panel__line--master-detail{width:24px;border-top:3px solid var(--mv-edge-neutral)}.erd-zoom-bar{position:relative;background:var(--mv-panel-bg);border-radius:var(--mv-radius-sm);padding:var(--mv-spacing-xs) var(--mv-spacing-sm);box-shadow:var(--mv-shadow-md);border:1px solid var(--mv-panel-border);display:flex;align-items:center;gap:var(--mv-spacing-xs)}.erd-zoom-bar__btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:var(--mv-radius-md);background:transparent;color:var(--mv-text-secondary);cursor:pointer;padding:0;transition:background var(--mv-transition-fast),color var(--mv-transition-fast)}.erd-zoom-bar__btn:hover{background:var(--mv-bg-surface-hover);color:var(--mv-text-primary)}.erd-zoom-bar__btn--active{background:var(--mv-bg-surface-hover);color:var(--mv-interactive-primary)}.erd-zoom-bar__btn--disabled{opacity:.4;cursor:not-allowed}.erd-zoom-bar__level{font-size:var(--mv-font-size-sm);font-weight:var(--mv-font-weight-medium);color:var(--mv-text-primary);min-width:40px;text-align:center;-webkit-user-select:none;user-select:none}.erd-zoom-bar__divider{width:1px;height:20px;background:var(--mv-separator);margin:0 var(--mv-spacing-xs)}.schema-visualization{width:100vw;height:100vh;background:transparent;color:var(--mv-text-primary);font-family:var(--mv-font-family)}
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Schema ERD Visualizer</title>
7
+ <script type="module" crossorigin src="./assets/index-BbY653nW.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/index-CbNHuvPl.css">
9
+ <link rel="stylesheet" href="@dist/design-system/platform.css" data-platform-styles="true">
10
+ </head>
11
+ <body>
12
+ <div id="root"></div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+ import { UEMFragment, TransformMetadata } from '../types/UemMetadata.js';
8
+ /**
9
+ * Transformer interface for converting source metadata to UEM format
10
+ *
11
+ * @template TSource - The source metadata type (e.g., XML string, parsed object)
12
+ */
13
+ export interface ITransformer<TSource = string> {
14
+ /**
15
+ * Transform source metadata to UEM fragment
16
+ *
17
+ * @param source - The source metadata (e.g., XML content, parsed object)
18
+ * @param filePath - The file path of the source file (for context)
19
+ * @returns Promise resolving to the UEM fragment and transformation metadata
20
+ */
21
+ transform(source: TSource, filePath: string): Promise<{
22
+ fragment: UEMFragment;
23
+ metadata: TransformMetadata;
24
+ }>;
25
+ }
26
+ /**
27
+ * Transformer registry for managing transformers by file pattern
28
+ */
29
+ export interface ITransformerRegistry {
30
+ /**
31
+ * Register a transformer for a file pattern
32
+ *
33
+ * @param filePattern - File pattern (e.g., '*.flexipage-meta.xml', '.flow-meta.xml')
34
+ * @param transformer - The transformer instance
35
+ */
36
+ register(filePattern: string, transformer: ITransformer): void;
37
+ /**
38
+ * Get a transformer for a given file path
39
+ *
40
+ * @param filePath - The file path to match against registered patterns
41
+ * @returns The transformer if found, undefined otherwise
42
+ */
43
+ getTransformer(filePath: string): ITransformer | undefined;
44
+ /**
45
+ * Check if a transformer is registered for a file path
46
+ *
47
+ * @param filePath - The file path to check
48
+ * @returns True if a transformer is registered for this file
49
+ */
50
+ hasTransformer(filePath: string): boolean;
51
+ /**
52
+ * Get all registered file patterns
53
+ *
54
+ * @returns Array of registered file patterns
55
+ */
56
+ getRegisteredPatterns(): string[];
57
+ }
58
+ //# sourceMappingURL=ITransformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ITransformer.d.ts","sourceRoot":"","sources":["../../../../src/shared/uem/transformer/ITransformer.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEzE;;;;GAIG;AACH,MAAM,WAAW,YAAY,CAAC,OAAO,GAAG,MAAM;IAC5C;;;;;;OAMG;IACH,SAAS,CACP,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QACT,QAAQ,EAAE,WAAW,CAAC;QACtB,QAAQ,EAAE,iBAAiB,CAAC;KAC7B,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,GAAG,IAAI,CAAC;IAE/D;;;;;OAKG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IAE3D;;;;;OAKG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAE1C;;;;OAIG;IACH,qBAAqB,IAAI,MAAM,EAAE,CAAC;CACnC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+ export {};
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+ import { ITransformer, ITransformerRegistry } from './ITransformer.js';
8
+ /**
9
+ * Implementation of the transformer registry
10
+ */
11
+ export declare class TransformerRegistry implements ITransformerRegistry {
12
+ private transformers;
13
+ /**
14
+ * Register a transformer for a file pattern
15
+ *
16
+ * @param filePattern - File pattern (e.g., '*.flexipage-meta.xml', '.flow-meta.xml')
17
+ * @param transformer - The transformer instance
18
+ */
19
+ register(filePattern: string, transformer: ITransformer): void;
20
+ /**
21
+ * Get a transformer for a given file path
22
+ * Matches file patterns in order of registration (first match wins)
23
+ *
24
+ * @param filePath - The file path to match against registered patterns
25
+ * @returns The transformer if found, undefined otherwise
26
+ */
27
+ getTransformer(filePath: string): ITransformer | undefined;
28
+ /**
29
+ * Check if a transformer is registered for a file path
30
+ *
31
+ * @param filePath - The file path to check
32
+ * @returns True if a transformer is registered for this file
33
+ */
34
+ hasTransformer(filePath: string): boolean;
35
+ /**
36
+ * Get all registered file patterns
37
+ *
38
+ * @returns Array of registered file patterns
39
+ */
40
+ getRegisteredPatterns(): string[];
41
+ /**
42
+ * Check if a file path matches a pattern
43
+ *
44
+ * @param filePath - The file path to check
45
+ * @param pattern - The pattern to match (e.g., '*.flexipage-meta.xml', '.flow-meta.xml')
46
+ * @returns True if the file path matches the pattern
47
+ */
48
+ private matchesPattern;
49
+ }
50
+ /**
51
+ * Global transformer registry instance
52
+ */
53
+ export declare const transformerRegistry: TransformerRegistry;
54
+ //# sourceMappingURL=TransformerRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransformerRegistry.d.ts","sourceRoot":"","sources":["../../../../src/shared/uem/transformer/TransformerRegistry.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEvE;;GAEG;AACH,qBAAa,mBAAoB,YAAW,oBAAoB;IAC9D,OAAO,CAAC,YAAY,CAAwC;IAE5D;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,GAAG,IAAI;IAI9D;;;;;;OAMG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAS1D;;;;;OAKG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIzC;;;;OAIG;IACH,qBAAqB,IAAI,MAAM,EAAE;IAIjC;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;CAQvB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,qBAA4B,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+ /**
8
+ * Implementation of the transformer registry
9
+ */
10
+ export class TransformerRegistry {
11
+ constructor() {
12
+ this.transformers = new Map();
13
+ }
14
+ /**
15
+ * Register a transformer for a file pattern
16
+ *
17
+ * @param filePattern - File pattern (e.g., '*.flexipage-meta.xml', '.flow-meta.xml')
18
+ * @param transformer - The transformer instance
19
+ */
20
+ register(filePattern, transformer) {
21
+ this.transformers.set(filePattern, transformer);
22
+ }
23
+ /**
24
+ * Get a transformer for a given file path
25
+ * Matches file patterns in order of registration (first match wins)
26
+ *
27
+ * @param filePath - The file path to match against registered patterns
28
+ * @returns The transformer if found, undefined otherwise
29
+ */
30
+ getTransformer(filePath) {
31
+ for (const [pattern, transformer] of this.transformers.entries()) {
32
+ if (this.matchesPattern(filePath, pattern)) {
33
+ return transformer;
34
+ }
35
+ }
36
+ return undefined;
37
+ }
38
+ /**
39
+ * Check if a transformer is registered for a file path
40
+ *
41
+ * @param filePath - The file path to check
42
+ * @returns True if a transformer is registered for this file
43
+ */
44
+ hasTransformer(filePath) {
45
+ return this.getTransformer(filePath) !== undefined;
46
+ }
47
+ /**
48
+ * Get all registered file patterns
49
+ *
50
+ * @returns Array of registered file patterns
51
+ */
52
+ getRegisteredPatterns() {
53
+ return Array.from(this.transformers.keys());
54
+ }
55
+ /**
56
+ * Check if a file path matches a pattern
57
+ *
58
+ * @param filePath - The file path to check
59
+ * @param pattern - The pattern to match (e.g., '*.flexipage-meta.xml', '.flow-meta.xml')
60
+ * @returns True if the file path matches the pattern
61
+ */
62
+ matchesPattern(filePath, pattern) {
63
+ // Handle wildcard patterns (e.g., *.flexipage-meta.xml)
64
+ if (pattern.startsWith('*')) {
65
+ return filePath.endsWith(pattern.slice(1));
66
+ }
67
+ // Handle exact match or suffix match (e.g., .flexipage-meta.xml)
68
+ return filePath === pattern || filePath.endsWith(pattern);
69
+ }
70
+ }
71
+ /**
72
+ * Global transformer registry instance
73
+ */
74
+ export const transformerRegistry = new TransformerRegistry();
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+ import { IVisualizationPlugin, MetadataPluginInfo, IMetadataParser, IPlatformContext } from '@salesforce/metadata-core-sdk';
8
+ import { UemMetadata } from '../types/UemMetadata.js';
9
+ import { ITransformer } from './ITransformer.js';
10
+ /**
11
+ * Base class for visualizers that use transformers to convert metadata to UEM format
12
+ *
13
+ * This class handles common functionality for UEM-based visualizers:
14
+ * - Automatic transformer registration
15
+ * - Standard parser initialization
16
+ * - Common logging and lifecycle management
17
+ */
18
+ export declare abstract class UemBasedVisualizer implements IVisualizationPlugin<UemMetadata> {
19
+ protected abstract readonly transformer: ITransformer;
20
+ abstract readonly parser: IMetadataParser<UemMetadata>;
21
+ private readonly pluginMetadata;
22
+ private logger?;
23
+ private transformerRegistered;
24
+ constructor(metadata: MetadataPluginInfo);
25
+ /**
26
+ * Get plugin metadata information.
27
+ * Framework calls this during plugin registration.
28
+ */
29
+ getMetadataPluginInfo(): MetadataPluginInfo;
30
+ /**
31
+ * Check if this visualizer can handle the given file path
32
+ */
33
+ canHandle(filePath: string): boolean;
34
+ /**
35
+ * Initialize the visualizer with platform context
36
+ */
37
+ initialize(context: IPlatformContext): Promise<void>;
38
+ /**
39
+ * Dispose of the visualizer
40
+ */
41
+ dispose?(): void;
42
+ }
43
+ //# sourceMappingURL=UemBasedVisualizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UemBasedVisualizer.d.ts","sourceRoot":"","sources":["../../../../src/shared/uem/transformer/UemBasedVisualizer.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAEjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD;;;;;;;GAOG;AACH,8BAAsB,kBAAmB,YAAW,oBAAoB,CAAC,WAAW,CAAC;IACnF,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC;IACtD,kBAAyB,MAAM,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;IAE9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,MAAM,CAAC,CAAU;IACzB,OAAO,CAAC,qBAAqB,CAAS;gBAE1B,QAAQ,EAAE,kBAAkB;IAIxC;;;OAGG;IACH,qBAAqB,IAAI,kBAAkB;IAI3C;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IASpC;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB1D;;OAEG;IACH,OAAO,CAAC,IAAI,IAAI;CAGjB"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+ import { transformerRegistry } from './TransformerRegistry.js';
8
+ /**
9
+ * Base class for visualizers that use transformers to convert metadata to UEM format
10
+ *
11
+ * This class handles common functionality for UEM-based visualizers:
12
+ * - Automatic transformer registration
13
+ * - Standard parser initialization
14
+ * - Common logging and lifecycle management
15
+ */
16
+ export class UemBasedVisualizer {
17
+ constructor(metadata) {
18
+ this.transformerRegistered = false;
19
+ this.pluginMetadata = metadata;
20
+ }
21
+ /**
22
+ * Get plugin metadata information.
23
+ * Framework calls this during plugin registration.
24
+ */
25
+ getMetadataPluginInfo() {
26
+ return this.pluginMetadata;
27
+ }
28
+ /**
29
+ * Check if this visualizer can handle the given file path
30
+ */
31
+ canHandle(filePath) {
32
+ return this.pluginMetadata.filePatterns.some((pattern) => {
33
+ if (pattern.startsWith('*')) {
34
+ return filePath.endsWith(pattern.slice(1));
35
+ }
36
+ return filePath === pattern || filePath.endsWith(pattern);
37
+ });
38
+ }
39
+ /**
40
+ * Initialize the visualizer with platform context
41
+ */
42
+ async initialize(context) {
43
+ // Auto-register transformer for all file patterns (only once)
44
+ if (!this.transformerRegistered) {
45
+ this.pluginMetadata.filePatterns.forEach((pattern) => {
46
+ transformerRegistry.register(pattern, this.transformer);
47
+ });
48
+ this.transformerRegistered = true;
49
+ }
50
+ // Setup visualizer-specific logger
51
+ this.logger = context.logger.createChild(this.getMetadataPluginInfo().id);
52
+ this.logger.info(`${this.getMetadataPluginInfo().name} initialized with UEM transformer`);
53
+ // Pass context to parser
54
+ this.parser.setPlatformContext(context);
55
+ }
56
+ /**
57
+ * Dispose of the visualizer
58
+ */
59
+ dispose() {
60
+ this.logger?.info(`Disposing ${this.getMetadataPluginInfo().name}`);
61
+ }
62
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+ /**
8
+ * Type definitions for UEM metadata
9
+ *
10
+ * @author UEM Team
11
+ */
12
+ export interface UemMetadata {
13
+ filePath: string;
14
+ name?: string;
15
+ fragment: UEMFragment;
16
+ metadata: TransformMetadata;
17
+ }
18
+ export interface UEMFragment {
19
+ /** Block definition URI */
20
+ definition: string;
21
+ /** Must be "block" for root */
22
+ type: 'block';
23
+ /** Optional: Unique identifier for the node */
24
+ id?: string;
25
+ /** Optional: Data providers */
26
+ dataProviders?: DataProvider[];
27
+ /** Root/page-level attributes */
28
+ attributes?: Record<string, unknown>;
29
+ /** Child blocks, regions, or fields */
30
+ children?: (Block | Region | Field)[];
31
+ }
32
+ export interface Block {
33
+ definition: string;
34
+ type: 'block';
35
+ /** Optional: Unique identifier for the node */
36
+ id?: string;
37
+ attributes?: Record<string, unknown>;
38
+ children?: (Block | Region | Field)[];
39
+ /** Optional: Visibility rule for conditional rendering */
40
+ visibilityRule?: Record<string, any>;
41
+ }
42
+ export interface Region {
43
+ type: 'region';
44
+ name: string;
45
+ /** Optional: Unique identifier for the node */
46
+ id?: string;
47
+ children?: (Block | Region | Field)[];
48
+ }
49
+ export interface Field {
50
+ definition: string;
51
+ type: 'field';
52
+ /** Optional: Unique identifier for the node */
53
+ id?: string;
54
+ attributes?: Record<string, unknown>;
55
+ children?: (Block | Region | Field)[];
56
+ /** Optional: Visibility rule for conditional rendering */
57
+ visibilityRule?: Record<string, any>;
58
+ }
59
+ export interface DataProvider {
60
+ definition: string;
61
+ expressionKey: string;
62
+ attributes?: Record<string, unknown>;
63
+ }
64
+ export interface TransformMetadata {
65
+ /** Source metadata type */
66
+ sourceType: string;
67
+ /** Transformation timestamp */
68
+ transformedAt: string;
69
+ /** Number of blocks in UEM */
70
+ blockCount: number;
71
+ /** Any warnings during transformation */
72
+ warnings?: TransformWarning[];
73
+ }
74
+ export interface TransformWarning {
75
+ /** Warning type */
76
+ type: 'unsupported-component' | 'missing-property' | 'deprecated-feature' | 'custom';
77
+ /** Warning message */
78
+ message: string;
79
+ /** Path in source metadata */
80
+ sourcePath?: string;
81
+ /** Severity level */
82
+ severity: 'info' | 'warning' | 'error';
83
+ }
84
+ //# sourceMappingURL=UemMetadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UemMetadata.d.ts","sourceRoot":"","sources":["../../../../src/shared/uem/types/UemMetadata.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ;;;;GAIG;AAEH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,CAAC;IACtB,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IAEnB,+BAA+B;IAC/B,IAAI,EAAE,OAAO,CAAC;IAEd,+CAA+C;IAC/C,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,+BAA+B;IAC/B,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAE/B,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAErC,uCAAuC;IACvC,QAAQ,CAAC,EAAE,CAAC,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC;IACtC,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,CAAC,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC;IACtC,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,iBAAiB;IAChC,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IAEnB,+BAA+B;IAC/B,aAAa,EAAE,MAAM,CAAC;IAEtB,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IAEnB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB;IACnB,IAAI,EAAE,uBAAuB,GAAG,kBAAkB,GAAG,oBAAoB,GAAG,QAAQ,CAAC;IAErF,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAEhB,8BAA8B;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,qBAAqB;IACrB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;CACxC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+ export {};
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+ /**
8
+ * Tree node structure for UEM visualization
9
+ */
10
+ export interface TreeNode {
11
+ id: string;
12
+ type: 'block' | 'region' | 'dataProvider' | 'field';
13
+ definition?: string;
14
+ name?: string;
15
+ attributes?: Record<string, unknown>;
16
+ children?: TreeNode[];
17
+ }
18
+ /**
19
+ * Converts a UEM fragment node to a TreeNode structure with unique IDs
20
+ * @param node - The source node to convert
21
+ * @param parentId - The parent node's ID for ID generation
22
+ * @returns A TreeNode with unique IDs for the tree structure
23
+ */
24
+ export declare function convertToTreeNode(node: any, parentId?: string): TreeNode;
25
+ /**
26
+ * Formats a field key into a human-readable label
27
+ * Converts camelCase or snake_case to Title Case
28
+ * @param key - The field key to format
29
+ * @returns A formatted label string
30
+ * @example
31
+ * formatFieldLabel('myFieldName') // 'My Field Name'
32
+ * formatFieldLabel('my_field_name') // 'My Field Name'
33
+ */
34
+ export declare function formatFieldLabel(key: string): string;
35
+ /**
36
+ * Formats a field value for display in the UI
37
+ * @param value - The value to format
38
+ * @returns A string representation of the value
39
+ */
40
+ export declare function formatFieldValue(value: unknown): string;
41
+ /**
42
+ * Finds a node in the tree by its ID, returning both the node and its parent
43
+ * @param nodeId - The ID of the node to find
44
+ * @param rootNodes - Array of root nodes to search through
45
+ * @returns Object containing the found node and its parent (both null if not found)
46
+ */
47
+ export declare function findNodeById(nodeId: string, rootNodes: TreeNode[]): {
48
+ node: TreeNode | null;
49
+ parent: TreeNode | null;
50
+ };
51
+ //# sourceMappingURL=uemTreeUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uemTreeUtils.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/uemTreeUtils.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,GAAG,OAAO,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,SAAK,GAAG,QAAQ,CAapE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMpD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAevD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,QAAQ,EAAE,GACpB;IAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,CA2BpD"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+ /**
8
+ * Converts a UEM fragment node to a TreeNode structure with unique IDs
9
+ * @param node - The source node to convert
10
+ * @param parentId - The parent node's ID for ID generation
11
+ * @returns A TreeNode with unique IDs for the tree structure
12
+ */
13
+ export function convertToTreeNode(node, parentId = '') {
14
+ const id = `${parentId}-${node.definition || node.name || node.type}-${Math.random()}`;
15
+ return {
16
+ id,
17
+ type: node.type,
18
+ definition: node.definition,
19
+ name: node.name,
20
+ attributes: node.attributes,
21
+ children: node.children?.map((child, index) => convertToTreeNode(child, `${id}-${index}`)),
22
+ };
23
+ }
24
+ /**
25
+ * Formats a field key into a human-readable label
26
+ * Converts camelCase or snake_case to Title Case
27
+ * @param key - The field key to format
28
+ * @returns A formatted label string
29
+ * @example
30
+ * formatFieldLabel('myFieldName') // 'My Field Name'
31
+ * formatFieldLabel('my_field_name') // 'My Field Name'
32
+ */
33
+ export function formatFieldLabel(key) {
34
+ return key
35
+ .replace(/([A-Z])/g, ' $1')
36
+ .replace(/_/g, ' ')
37
+ .replace(/^./, (str) => str.toUpperCase())
38
+ .trim();
39
+ }
40
+ /**
41
+ * Formats a field value for display in the UI
42
+ * @param value - The value to format
43
+ * @returns A string representation of the value
44
+ */
45
+ export function formatFieldValue(value) {
46
+ if (value === null || value === undefined) {
47
+ return '-';
48
+ }
49
+ if (typeof value === 'boolean') {
50
+ return value ? 'Yes' : 'No';
51
+ }
52
+ if (typeof value === 'object') {
53
+ return JSON.stringify(value);
54
+ }
55
+ if (typeof value === 'string' && value.includes('{!$')) {
56
+ // It's a data binding
57
+ return value;
58
+ }
59
+ return String(value);
60
+ }
61
+ /**
62
+ * Finds a node in the tree by its ID, returning both the node and its parent
63
+ * @param nodeId - The ID of the node to find
64
+ * @param rootNodes - Array of root nodes to search through
65
+ * @returns Object containing the found node and its parent (both null if not found)
66
+ */
67
+ export function findNodeById(nodeId, rootNodes) {
68
+ const search = (current, parent = null) => {
69
+ if (current.id === nodeId) {
70
+ return { node: current, parent };
71
+ }
72
+ if (current.children) {
73
+ for (const child of current.children) {
74
+ const result = search(child, current);
75
+ if (result.node) {
76
+ return result;
77
+ }
78
+ }
79
+ }
80
+ return { node: null, parent: null };
81
+ };
82
+ for (const rootNode of rootNodes) {
83
+ const result = search(rootNode);
84
+ if (result.node) {
85
+ return result;
86
+ }
87
+ }
88
+ return { node: null, parent: null };
89
+ }