@salesforce/metadata-visualizer-web 1.0.1

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 (66) hide show
  1. package/LICENSE.txt +27 -0
  2. package/README.md +269 -0
  3. package/dist/WebVisualizationEngine.d.ts +165 -0
  4. package/dist/WebVisualizationEngine.d.ts.map +1 -0
  5. package/dist/WebVisualizationEngine.js +284 -0
  6. package/dist/WebVisualizationEngine.js.map +1 -0
  7. package/dist/createWebVisualizationEngine.d.ts +27 -0
  8. package/dist/createWebVisualizationEngine.d.ts.map +1 -0
  9. package/dist/createWebVisualizationEngine.js +91 -0
  10. package/dist/createWebVisualizationEngine.js.map +1 -0
  11. package/dist/design-system/platform.css +623 -0
  12. package/dist/errors/index.d.ts +25 -0
  13. package/dist/errors/index.d.ts.map +1 -0
  14. package/dist/errors/index.js +31 -0
  15. package/dist/errors/index.js.map +1 -0
  16. package/dist/index.d.ts +22 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +18 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/internal/CompositeFileSystem.d.ts +28 -0
  21. package/dist/internal/CompositeFileSystem.d.ts.map +1 -0
  22. package/dist/internal/CompositeFileSystem.js +82 -0
  23. package/dist/internal/CompositeFileSystem.js.map +1 -0
  24. package/dist/internal/assetInliner.d.ts +30 -0
  25. package/dist/internal/assetInliner.d.ts.map +1 -0
  26. package/dist/internal/assetInliner.js +126 -0
  27. package/dist/internal/assetInliner.js.map +1 -0
  28. package/dist/internal/constants.d.ts +20 -0
  29. package/dist/internal/constants.d.ts.map +1 -0
  30. package/dist/internal/constants.js +34 -0
  31. package/dist/internal/constants.js.map +1 -0
  32. package/dist/internal/htmlPipeline.d.ts +50 -0
  33. package/dist/internal/htmlPipeline.d.ts.map +1 -0
  34. package/dist/internal/htmlPipeline.js +86 -0
  35. package/dist/internal/htmlPipeline.js.map +1 -0
  36. package/dist/pluginAssets/BundledPluginAssetReader.d.ts +34 -0
  37. package/dist/pluginAssets/BundledPluginAssetReader.d.ts.map +1 -0
  38. package/dist/pluginAssets/BundledPluginAssetReader.js +77 -0
  39. package/dist/pluginAssets/BundledPluginAssetReader.js.map +1 -0
  40. package/dist/plugins/flexipage/ui/assets/index-BAFqMU7k.js +48 -0
  41. package/dist/plugins/flexipage/ui/assets/index-U3SB2gLS.css +1 -0
  42. package/dist/plugins/flexipage/ui/index.html +16 -0
  43. package/dist/plugins/schema/ui/assets/index-DCLgZby3.css +1 -0
  44. package/dist/plugins/schema/ui/assets/index-Ho7jg9o_.js +70 -0
  45. package/dist/plugins/schema/ui/index.html +14 -0
  46. package/dist/types/HttpAsset.d.ts +18 -0
  47. package/dist/types/HttpAsset.d.ts.map +1 -0
  48. package/dist/types/HttpAsset.js +8 -0
  49. package/dist/types/HttpAsset.js.map +1 -0
  50. package/dist/types/PluginDataUpdateMessage.d.ts +24 -0
  51. package/dist/types/PluginDataUpdateMessage.d.ts.map +1 -0
  52. package/dist/types/PluginDataUpdateMessage.js +8 -0
  53. package/dist/types/PluginDataUpdateMessage.js.map +1 -0
  54. package/dist/types/PluginInfo.d.ts +20 -0
  55. package/dist/types/PluginInfo.d.ts.map +1 -0
  56. package/dist/types/PluginInfo.js +8 -0
  57. package/dist/types/PluginInfo.js.map +1 -0
  58. package/dist/types/VisualizeOutcome.d.ts +19 -0
  59. package/dist/types/VisualizeOutcome.d.ts.map +1 -0
  60. package/dist/types/VisualizeOutcome.js +8 -0
  61. package/dist/types/VisualizeOutcome.js.map +1 -0
  62. package/dist/types/WebAdapterOptions.d.ts +22 -0
  63. package/dist/types/WebAdapterOptions.d.ts.map +1 -0
  64. package/dist/types/WebAdapterOptions.js +8 -0
  65. package/dist/types/WebAdapterOptions.js.map +1 -0
  66. package/package.json +77 -0
package/LICENSE.txt ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2026, Salesforce.com, inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice, this
11
+ list of conditions and the following disclaimer in the documentation and/or
12
+ other materials provided with the distribution.
13
+
14
+ * Neither the name of Salesforce.com nor the names of its contributors may be
15
+ used to endorse or promote products derived from this software without specific
16
+ prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,269 @@
1
+ # @salesforce/metadata-visualizer-web
2
+
3
+ Web/HTTP SDK for the Salesforce Metadata Visualizer framework (`@salesforce/metadata-visualizer-core`). Lets any HTTP-based host (custom web services, browser applications, demo pages) plug a host-supplied filesystem into the framework and serve plugin visualizations to a browser.
4
+
5
+ This package mirrors the role `visualizer-vscode-ext` plays for VS Code: it owns the host-specific plumbing (postMessage bootstrap, plugin asset bundling, `@dist/` URL rewriting) and exposes a small façade so consumers never see plugin internals.
6
+
7
+ ## Interfaces the host must implement
8
+
9
+ The SDK is built around the principle of _interface inversion_: we define small contracts in `core-sdk`, and each host (browser application, VS Code, others) implements them. The SDK does not impose a transport, a router, or a filesystem layout — it just consumes what the host supplies and returns blobs the host can serve.
10
+
11
+ There is **exactly one** interface the host must implement: `IFileSystem`. The engine also accepts an optional `telemetry` hook; everything else is handled internally by the SDK.
12
+
13
+ ### Required: `IFileSystem` (from `@salesforce/metadata-core-sdk`)
14
+
15
+ This is the only interface the host _must_ implement. It is the host's bridge between the framework and the user-project files the host owns.
16
+
17
+ #### Why this is required
18
+
19
+ Plugin parsers (`SchemaParser`, `FlexipageParser`, future plugins) read the user's metadata files through this interface. The host implements it once against its existing I/O layer — delegating to your project service's file operations, which should enforce path traversal guards, restricted-path rules (`.git`, `.sf`, `node_modules`, dotfiles), path length limits, and per-project isolation.
20
+
21
+ #### Methods to implement
22
+
23
+ | Method | What it does | Implementation notes |
24
+ | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
25
+ | `readFile(path)` | Read a file as a UTF-8 string. Returns `Result<string>`. | Delegate to your file I/O layer. Wrap path validation errors into `{ success: false, error }`. |
26
+ | `writeFile(path, content)` | Write a file. Returns `Result<void>`. | Plugins do not write today; you can throw or stub. |
27
+ | `exists(path)` | Whether a file or directory exists. Returns `Promise<boolean>`. | Use your project service's path resolution + file system checks. |
28
+ | `getMetadata(path)` | Returns `{ path, fileName, extension }`. | Pure path operations + stat for existence. |
29
+ | `readDirectory(path)` | Lists directory entries with `{ name, isFile }`. | Delegate to your directory listing implementation. |
30
+ | `findFiles(pattern, maxResults?)` | Workspace-wide glob (e.g. `**/*.object-meta.xml`). | Pattern language is minimatch with POSIX separators, anchored at the workspace root. Schema plugin uses this to discover related objects. |
31
+ | `getWorkspaceRoot()` | Absolute path of the project root. | One project per `IFileSystem` instance — construct one per request bound to that request's project. |
32
+ | `normalizePath`, `separator`, `basename`, `dirname`, `join`, `extname`, `parse`, `relative`, `resolve`, `isAbsolute` | Pure string operations. | Delegate to Node's `path` module. |
33
+
34
+ The full type definition lives at `@salesforce/metadata-core-sdk` → `IFileSystem`.
35
+
36
+ ### Optional: `telemetry` (`ITelemetry` from `@salesforce/metadata-core-sdk`)
37
+
38
+ A telemetry hook for tracking usage and errors, passed to `createWebVisualizationEngine` alongside `fileSystem`. If the host doesn't supply it, the SDK falls back to a no-op implementation.
39
+
40
+ ---
41
+
42
+ ## What the host gets back from the SDK
43
+
44
+ After implementing `IFileSystem` and constructing the engine via `createWebVisualizationEngine`, the host calls these methods. The `WebVisualizationEngine` class provides five core methods:
45
+
46
+ ### Core API Methods
47
+
48
+ | Method | Returns | Use Case |
49
+ | -------------------------------------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
50
+ | `getPlugin(metadataFilePath)` | `PluginInfo \| null` | Resolve a metadata file path to its registered plugin (returns `id`, `displayName`, etc.) |
51
+ | `visualizeMetadata(pluginId)` | `{ bundle: HttpAsset<string> \| null, error: PluginError \| null }` | Generate a fully self-contained HTML shell for the plugin's UI (no parsing — UI only) |
52
+ | `getParsedMetadata(metadataFilePath)` | `VisualizeOutcome` — `{ result, error }` | Parse metadata and return structured data without generating HTML |
53
+ | `getUpdatedParsedMetadata(metadataFilePath)` | `{ error, pluginDataUpdateMessage }` | Generate update message for posting to existing plugin iframe (live updates) |
54
+ | `dispose()` | `void` | Release all resources (call on shutdown) |
55
+
56
+ ### Method Details
57
+
58
+ **Two-step flow.** UI generation and metadata parsing are separate calls. `visualizeMetadata` produces the static plugin UI shell (no file I/O, no parsing); the loaded iframe then requests parsed data via `postMessage`, which the host serves from `getParsedMetadata`. Use `getPlugin(filePath)` to resolve a metadata file to its plugin ID before calling `visualizeMetadata`.
59
+
60
+ **`getPlugin(metadataFilePath)`** — Resolve plugin for a file:
61
+
62
+ - Matches the file path against registered plugin file patterns
63
+ - Returns `PluginInfo` (with `id`) on match, `null` otherwise
64
+ - Synchronous and side-effect-free
65
+
66
+ **`visualizeMetadata(pluginId)`** — Generate UI shell:
67
+
68
+ - Returns fully self-contained HTML with all assets (JS, CSS, platform styles) inlined
69
+ - **No metadata parsing occurs** — this generates the static plugin UI only
70
+ - Zero additional HTTP requests needed
71
+ - Perfect for iframe embedding: `<iframe srcdoc="..."></iframe>`
72
+ - The loaded plugin iframe requests its data separately via postMessage
73
+ - Error handling: Check `error` field first, then use `bundle`
74
+
75
+ **`getParsedMetadata(metadataFilePath)`** — Parse metadata only:
76
+
77
+ - Returns parsed metadata as structured data
78
+ - Use for REST endpoints, data analysis, validation, and as the data source for plugin postMessage requests
79
+ - No HTML generation overhead
80
+
81
+ **`getUpdatedParsedMetadata(metadataFilePath)`** — Live updates:
82
+
83
+ - Parses file and generates `PluginDataUpdateMessage` ready for iframe postMessage
84
+ - Use with file watchers to push updates to already-loaded visualizations
85
+ - Plugins listen via `onDataUpdate` from `HostCommunicationUtils`
86
+
87
+ ---
88
+
89
+ ## Integration walkthrough
90
+
91
+ This section explains how a web host integrates the SDK end-to-end. The actual route plumbing depends on your framework conventions (Express, Fastify, etc.). The shape below shows the integration pattern at the seams.
92
+
93
+ ### Step 1 — Implement `IFileSystem`
94
+
95
+ The host writes a single class that wraps its existing file I/O layer. Each method delegates to your existing file operations. The class is constructed per request, bound to that request's project root.
96
+
97
+ ```ts
98
+ // Host implementation — sketch only
99
+ class MyHostFileSystem implements IFileSystem {
100
+ constructor(private readonly projectDir: string) {}
101
+ // readFile, findFiles, exists, getMetadata, readDirectory →
102
+ // delegate to your file service
103
+ // pure-string helpers (basename, join, etc.) → delegate to node:path
104
+ // getWorkspaceRoot() → return this.projectDir
105
+ }
106
+ ```
107
+
108
+ ### Step 2 — Construct the engine per request
109
+
110
+ For each incoming HTTP request that needs visualization:
111
+
112
+ ```ts
113
+ const fileSystem = new MyHostFileSystem(projectDir);
114
+ const engine = await createWebVisualizationEngine({ fileSystem });
115
+ // Use the engine, then dispose when the request ends.
116
+ ```
117
+
118
+ Per-request construction is acceptable for prototypes because plugin loading is cheap. Production hosts can cache engines per project if profiling shows it matters.
119
+
120
+ ### Step 3 — Wire HTTP routes
121
+
122
+ The host adds visualizer routes to its service using the five core `WebVisualizationEngine` methods:
123
+
124
+ #### Route 1: Generate HTML Bundle
125
+
126
+ ```ts
127
+ app.post('/visualizer/bundle', async (req, res) => {
128
+ const { filePath } = req.body;
129
+
130
+ // Resolve file → plugin first; visualizeMetadata takes a pluginId, not a path.
131
+ const pluginInfo = engine.getPlugin(filePath);
132
+ if (!pluginInfo) {
133
+ return res.status(415).json({ error: 'No plugin found for this file type' });
134
+ }
135
+
136
+ const { bundle, error } = await engine.visualizeMetadata(pluginInfo.id);
137
+
138
+ if (error) {
139
+ const status = error.category === 'Configuration' ? 415 : 500;
140
+ return res.status(status).json({
141
+ error: error.message,
142
+ category: error.category,
143
+ context: error.context,
144
+ });
145
+ }
146
+
147
+ res.type(bundle.contentType).set('Cache-Control', bundle.cacheControl).send(bundle.body);
148
+ });
149
+ ```
150
+
151
+ **Use case:** Generate the plugin UI shell for iframe embedding. Returns fully self-contained HTML with all assets inlined. Note: this generates the UI only — the loaded iframe requests parsed metadata separately via postMessage, served by the parse route below.
152
+
153
+ #### Route 2: Parse Metadata
154
+
155
+ ```ts
156
+ app.post('/visualizer/parse', async (req, res) => {
157
+ const { filePath } = req.body;
158
+ const outcome = await engine.getParsedMetadata(filePath);
159
+
160
+ if (outcome.error) {
161
+ return res.status(500).json({
162
+ error: outcome.error.message,
163
+ category: outcome.error.category,
164
+ });
165
+ }
166
+
167
+ res.json({
168
+ data: outcome.result.data,
169
+ metadata: outcome.result.metadata,
170
+ filePath: outcome.result.filePath,
171
+ });
172
+ });
173
+ ```
174
+
175
+ **Use case:** Data-only endpoint. Plugins request this via postMessage; useful for validation, analysis, and structured data access.
176
+
177
+ #### Route 3: Live Updates
178
+
179
+ ```ts
180
+ app.post('/visualizer/update', async (req, res) => {
181
+ const { filePath } = req.body;
182
+ const { error, pluginDataUpdateMessage } = await engine.getUpdatedParsedMetadata(filePath);
183
+
184
+ if (error) {
185
+ return res.status(500).json({ error: error.message });
186
+ }
187
+
188
+ // Return message for host to post to iframe
189
+ res.json({ updateMessage: pluginDataUpdateMessage, success: true });
190
+ });
191
+
192
+ // File watcher integration (server-side)
193
+ fileWatcher.on('change', async (filePath) => {
194
+ const { pluginDataUpdateMessage } = await engine.getUpdatedParsedMetadata(filePath);
195
+ if (pluginDataUpdateMessage) {
196
+ // Send to connected clients via WebSocket
197
+ wss.clients.forEach((client) => {
198
+ client.send(JSON.stringify(pluginDataUpdateMessage));
199
+ });
200
+ }
201
+ });
202
+ ```
203
+
204
+ **Use case:** Push updates to already-loaded iframe when file content changes. Plugins listen via `onDataUpdate`:
205
+
206
+ ```tsx
207
+ import { onDataUpdate } from '@salesforce/metadata-core-sdk/utils/HostCommunicationUtils';
208
+
209
+ useEffect(() => {
210
+ const unsubscribe = onDataUpdate((freshData) => {
211
+ setData(freshData); // Re-render with updated data
212
+ });
213
+ return unsubscribe;
214
+ }, []);
215
+ ```
216
+
217
+ ### Step 4 — Wire the browser side
218
+
219
+ The host's UI mounts an `<iframe>` whose `src` is the bundle URL above. Because the iframe is same-origin (everything served from your domain), the bootstrap script the SDK injected can `postMessage` cleanly to the parent window. The parent UI listens for those messages and proxies `REQUEST_PLUGIN_DATA` back to the parse endpoint, then posts `PLUGIN_DATA_RESPONSE` back into the iframe.
220
+
221
+ This relay logic lives entirely on the host's side. The package gives the iframe a working `__ExtensionHostPostMessage` and an HTML document; the host decides what listens to those messages on the parent.
222
+
223
+ ---
224
+
225
+ ## Architecture rules enforced by tests
226
+
227
+ The SDK has two strict architectural rules — both checked at test time:
228
+
229
+ 1. **No runtime dependency on `@salesforce/metadata-plugins`.** Plugin React builds are bundled into the SDK's own `dist/plugins/` at build time via `scripts/copy-plugin-assets.mjs` — same pattern the VS Code adapter uses with webpack `CopyPlugin`. The plugins package is referenced only at the workspace root's `devDependencies`. Consumers' `npm install` never pulls plugins in directly.
230
+ 2. **No `vscode` import.** This is a browser-host SDK; VS Code-flavored code stays in `visualizer-vscode-ext`.
231
+
232
+ Both are enforced by `src/__tests__/architecture.test.ts`.
233
+
234
+ ---
235
+
236
+ ## Development
237
+
238
+ ```bash
239
+ npm run build # tsc + scripts/copy-plugin-assets.mjs (populates dist/plugins/, dist/design-system/)
240
+ npm test # jest with coverage
241
+ npm run typecheck # tsc --noEmit
242
+ npm run lint
243
+ ```
244
+
245
+ Build runs from the workspace root — `@salesforce/metadata-plugins` lives in the root's `devDependencies` and the build script resolves it from there. Building the package outside the workspace is not supported.
246
+
247
+ ## Public API summary
248
+
249
+ ### Core Class
250
+
251
+ - `WebVisualizationEngine` — Main class with five methods:
252
+ - `getPlugin(metadataFilePath)` — Resolve a file path to its registered plugin
253
+ - `visualizeMetadata(pluginId)` — Generate the plugin UI shell (HTML bundle, no parsing)
254
+ - `getParsedMetadata(metadataFilePath)` — Parse metadata only
255
+ - `getUpdatedParsedMetadata(metadataFilePath)` — Generate update message for live updates
256
+ - `dispose()` — Release resources
257
+ - `createWebVisualizationEngine(opts)` — Async factory function
258
+
259
+ ### Supporting Types
260
+
261
+ - `HttpAsset<T>` — Response wrapper: `{ contentType, body, cacheControl }`
262
+ - `PluginInfo` — Plugin metadata: `{ id, displayName, filePatterns, priority? }`
263
+ - `VisualizeOutcome` — Parse result: `{ result, error }`. The `error` field is a `PluginError` from `@salesforce/metadata-core-sdk`.
264
+ - `PluginDataUpdateMessage<T = unknown>` — Update message for postMessage: `{ type: 'PLUGIN_DATA_UPDATE', payload: PluginDataResponse<T> }`. Generic `T` lets plugin code with a known data shape opt into type-safety; consumers can narrow on `message.type` in a discriminated-union switch.
265
+ - `WebAdapterOptions` — Engine constructor options: `{ fileSystem, telemetry? }`
266
+
267
+ ## License
268
+
269
+ BSD-3-Clause.
@@ -0,0 +1,165 @@
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 type { PluginError } from '@salesforce/metadata-core-sdk';
8
+ import type { PluginManager, VisualizationEngine } from '@salesforce/metadata-visualizer-core';
9
+ import { BundledPluginAssetReader } from './pluginAssets/BundledPluginAssetReader.js';
10
+ import type { HttpAsset } from './types/HttpAsset.js';
11
+ import type { PluginInfo } from './types/PluginInfo.js';
12
+ import type { VisualizeOutcome } from './types/VisualizeOutcome.js';
13
+ import type { PluginDataUpdateMessage } from './types/PluginDataUpdateMessage.js';
14
+ /**
15
+ * Internal construction parameters used by the factory. Not part of the
16
+ * public API — consumers always go through `createWebVisualizationEngine`.
17
+ *
18
+ * @internal
19
+ */
20
+ export interface WebVisualizationEngineDeps {
21
+ framework: VisualizationEngine;
22
+ pluginManager: PluginManager;
23
+ pluginAssetReader: BundledPluginAssetReader;
24
+ }
25
+ /**
26
+ * Browser/HTTP platform adapter for the visualization framework.
27
+ * Provides methods to generate self-contained HTML bundles and parse metadata
28
+ * for embedding in iframes. All methods are safe to call concurrently.
29
+ */
30
+ export declare class WebVisualizationEngine {
31
+ private readonly framework;
32
+ private readonly pluginManager;
33
+ private readonly assetReader;
34
+ /** Tracks whether dispose() has been called to prevent use-after-dispose */
35
+ private disposed;
36
+ /** Per-file monotonic counter for fileId. Date.now() collides under sub-ms concurrent calls. */
37
+ private readonly fileIdCounters;
38
+ /**
39
+ * Construct an engine.
40
+ *
41
+ * **Use `createWebVisualizationEngine()` instead.** This constructor is exposed
42
+ * only for the factory and internal tests, and it asserts an ownership contract
43
+ * that is easy to misuse:
44
+ *
45
+ * - The injected `framework` (and its `ErrorManager`) is **owned** by the
46
+ * resulting engine. Calling `dispose()` tears it down — including any error
47
+ * listeners registered by other code on the same instance.
48
+ * - Therefore the framework must be dedicated to this engine. Sharing one
49
+ * `VisualizationEngine` between a `WebVisualizationEngine` and another
50
+ * adapter (e.g. the VS Code adapter) will break the other adapter when this
51
+ * engine is disposed.
52
+ *
53
+ * @internal
54
+ */
55
+ constructor(deps: WebVisualizationEngineDeps);
56
+ /**
57
+ * Generate a complete HTML bundle for a plugin's visualization UI.
58
+ * Returns a self-contained HTML file with all assets (JS, CSS, platform styles) inlined,
59
+ * ready to be embedded in an iframe. No metadata parsing occurs — this generates the static UI shell.
60
+ *
61
+ * @param pluginId - ID of the registered plugin to generate bundle for
62
+ * @returns Object containing the bundle (null if failed) and error (null if successful)
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const { bundle, error } = await engine.visualizeMetadata('flexipage-visualizer');
67
+ * if (error) {
68
+ * console.error('Bundle generation failed:', error.message);
69
+ * res.status(error.category === 'Configuration' ? 404 : 500).json({ error: error.message });
70
+ * } else if (bundle) {
71
+ * res.type(bundle.contentType).send(bundle.body);
72
+ * }
73
+ * ```
74
+ */
75
+ visualizeMetadata(pluginId: string): Promise<{
76
+ bundle: HttpAsset<string> | null;
77
+ error: PluginError | null;
78
+ }>;
79
+ /**
80
+ * Parse a metadata file and return the visualization outcome.
81
+ * Finds the appropriate plugin by file pattern, parses the file, and returns structured data.
82
+ * Handles error capturing for concurrent-safe execution (multiple calls won't interfere).
83
+ *
84
+ * @param metadataFilePath - Path to the metadata file to parse
85
+ * @returns VisualizeOutcome containing either parsed result or error
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * const outcome = await engine.getParsedMetadata('force-app/main/default/flexipages/Home.flexipage');
90
+ * if (outcome.error) {
91
+ * console.error('Parse failed:', outcome.error.message);
92
+ * } else {
93
+ * console.log('Parsed data:', outcome.result.data);
94
+ * }
95
+ * ```
96
+ */
97
+ getParsedMetadata(metadataFilePath: string): Promise<VisualizeOutcome>;
98
+ /**
99
+ * Parse metadata and generate an update message for posting to an existing plugin iframe.
100
+ * Use this when file content changes and you need to push updates to a loaded iframe
101
+ * without regenerating the entire bundle. Plugins receive updates via onDataUpdate().
102
+ *
103
+ * @param metadataFilePath - Path to the metadata file to parse
104
+ * @returns Object containing error (if any) and pluginDataUpdateMessage (null if parsing failed)
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * // File watcher integration
109
+ * watcher.on('change', async (filePath) => {
110
+ * const { error, pluginDataUpdateMessage } = await engine.getUpdatedParsedMetadata(filePath);
111
+ * if (pluginDataUpdateMessage) {
112
+ * iframeWindow.postMessage(pluginDataUpdateMessage, '*');
113
+ * }
114
+ * });
115
+ * ```
116
+ */
117
+ getUpdatedParsedMetadata(metadataFilePath: string): Promise<{
118
+ error: PluginError | null;
119
+ pluginDataUpdateMessage: PluginDataUpdateMessage | null;
120
+ }>;
121
+ /**
122
+ * Release all resources held by the engine.
123
+ * After calling this method, the engine instance should not be used.
124
+ * Safe to call multiple times (idempotent).
125
+ *
126
+ * **Disposes the underlying framework.** The engine takes ownership of the
127
+ * `VisualizationEngine` passed to its constructor (or built by the factory),
128
+ * including its `ErrorManager`. Do not share that framework with another
129
+ * adapter — it will be torn down here.
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * process.on('SIGTERM', () => {
134
+ * engine.dispose();
135
+ * process.exit(0);
136
+ * });
137
+ * ```
138
+ */
139
+ dispose(): void;
140
+ /**
141
+ * Create a PLUGIN_DATA_UPDATE message for posting to a loaded plugin iframe.
142
+ * Per-file monotonic counter guarantees a unique, ordered fileId per update,
143
+ * even under sub-millisecond concurrent calls (Date.now() can collide).
144
+ *
145
+ * @param outcome - Visualization outcome with parsed data
146
+ * @returns Message ready to be posted via iframe.contentWindow.postMessage(), or null if parsing failed
147
+ */
148
+ private createDataUpdateMessage;
149
+ /**
150
+ * Find the registered plugin that handles a given file.
151
+ * Matches file against plugin patterns (e.g., *.flexipage, *.object, *-meta.xml).
152
+ *
153
+ * @param metadataFile - Filename (e.g., 'Home.flexipage') or full path to match
154
+ * @returns PluginInfo if a matching plugin is found, null otherwise
155
+ */
156
+ getPlugin(metadataFile: string): PluginInfo | null;
157
+ /**
158
+ * Verify a plugin is registered before attempting to use it.
159
+ * Prevents asset read failures for non-existent plugins.
160
+ */
161
+ private requireKnownPlugin;
162
+ /** Guards against use-after-dispose by throwing an error */
163
+ private assertNotDisposed;
164
+ }
165
+ //# sourceMappingURL=WebVisualizationEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebVisualizationEngine.d.ts","sourceRoot":"","sources":["../src/WebVisualizationEngine.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAI/F,OAAO,EAAE,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AACtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAElF;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,aAAa,EAAE,aAAa,CAAC;IAC7B,iBAAiB,EAAE,wBAAwB,CAAC;CAC7C;AAED;;;;GAIG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2B;IACvD,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAS;IACzB,gGAAgG;IAChG,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAE5D;;;;;;;;;;;;;;;;OAgBG;gBACS,IAAI,EAAE,0BAA0B;IAM5C;;;;;;;;;;;;;;;;;;OAkBG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QACjD,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QACjC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;KAC3B,CAAC;IA0DF;;;;;;;;;;;;;;;;;OAiBG;IACG,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyC5E;;;;;;;;;;;;;;;;;;OAkBG;IACG,wBAAwB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC;QAChE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;QAC1B,uBAAuB,EAAE,uBAAuB,GAAG,IAAI,CAAC;KACzD,CAAC;IASF;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,IAAI,IAAI;IAUf;;;;;;;OAOG;IACH,OAAO,CAAC,uBAAuB;IAsB/B;;;;;;OAMG;IACH,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAKlD;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAI1B,4DAA4D;IAC5D,OAAO,CAAC,iBAAiB;CAK1B"}