@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.
- package/LICENSE.txt +27 -0
- package/README.md +121 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/plugins/flexipage/FlexipageParser.d.ts +39 -0
- package/dist/plugins/flexipage/FlexipageParser.d.ts.map +1 -0
- package/dist/plugins/flexipage/FlexipageParser.js +124 -0
- package/dist/plugins/flexipage/FlexipageVisualizer.d.ts +19 -0
- package/dist/plugins/flexipage/FlexipageVisualizer.d.ts.map +1 -0
- package/dist/plugins/flexipage/FlexipageVisualizer.js +27 -0
- package/dist/plugins/flexipage/transformer/FlexipageToUemTransformer.d.ts +55 -0
- package/dist/plugins/flexipage/transformer/FlexipageToUemTransformer.d.ts.map +1 -0
- package/dist/plugins/flexipage/transformer/FlexipageToUemTransformer.js +302 -0
- package/dist/plugins/flexipage/transformer/FlexipageTransformerUtils.d.ts +34 -0
- package/dist/plugins/flexipage/transformer/FlexipageTransformerUtils.d.ts.map +1 -0
- package/dist/plugins/flexipage/transformer/FlexipageTransformerUtils.js +73 -0
- package/dist/plugins/flexipage/types/FlexipageMetadata.d.ts +76 -0
- package/dist/plugins/flexipage/types/FlexipageMetadata.d.ts.map +1 -0
- package/dist/plugins/flexipage/types/FlexipageMetadata.js +7 -0
- package/dist/plugins/flexipage/ui/assets/index-DUDC29Wu.js +55 -0
- package/dist/plugins/flexipage/ui/assets/index-U3SB2gLS.css +1 -0
- package/dist/plugins/flexipage/ui/index.html +16 -0
- package/dist/plugins/schema/SchemaParser.d.ts +80 -0
- package/dist/plugins/schema/SchemaParser.d.ts.map +1 -0
- package/dist/plugins/schema/SchemaParser.js +474 -0
- package/dist/plugins/schema/SchemaVisualizer.d.ts +42 -0
- package/dist/plugins/schema/SchemaVisualizer.d.ts.map +1 -0
- package/dist/plugins/schema/SchemaVisualizer.js +46 -0
- package/dist/plugins/schema/types/SchemaERDData.d.ts +91 -0
- package/dist/plugins/schema/types/SchemaERDData.d.ts.map +1 -0
- package/dist/plugins/schema/types/SchemaERDData.js +7 -0
- package/dist/plugins/schema/ui/assets/index-BbY653nW.js +62 -0
- package/dist/plugins/schema/ui/assets/index-CbNHuvPl.css +1 -0
- package/dist/plugins/schema/ui/index.html +14 -0
- package/dist/shared/uem/transformer/ITransformer.d.ts +58 -0
- package/dist/shared/uem/transformer/ITransformer.d.ts.map +1 -0
- package/dist/shared/uem/transformer/ITransformer.js +7 -0
- package/dist/shared/uem/transformer/TransformerRegistry.d.ts +54 -0
- package/dist/shared/uem/transformer/TransformerRegistry.d.ts.map +1 -0
- package/dist/shared/uem/transformer/TransformerRegistry.js +74 -0
- package/dist/shared/uem/transformer/UemBasedVisualizer.d.ts +43 -0
- package/dist/shared/uem/transformer/UemBasedVisualizer.d.ts.map +1 -0
- package/dist/shared/uem/transformer/UemBasedVisualizer.js +62 -0
- package/dist/shared/uem/types/UemMetadata.d.ts +84 -0
- package/dist/shared/uem/types/UemMetadata.d.ts.map +1 -0
- package/dist/shared/uem/types/UemMetadata.js +7 -0
- package/dist/shared/utils/uemTreeUtils.d.ts +51 -0
- package/dist/shared/utils/uemTreeUtils.d.ts.map +1 -0
- package/dist/shared/utils/uemTreeUtils.js +89 -0
- package/dist/shared/utils/vizDependentPathsHelper.d.ts +53 -0
- package/dist/shared/utils/vizDependentPathsHelper.d.ts.map +1 -0
- package/dist/shared/utils/vizDependentPathsHelper.js +108 -0
- 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,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,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
|
+
}
|