@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/dist/index.js ADDED
@@ -0,0 +1,18 @@
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
+ * @salesforce/metadata-visualizer-web — Public API.
9
+ *
10
+ * Web/HTTP SDK for the Salesforce Metadata Visualizer framework. Lets any
11
+ * HTTP-style host (custom web services, browser applications, demo pages)
12
+ * plug a host-supplied IFileSystem into the framework and serve plugin
13
+ * visualizations to a browser without seeing plugin internals.
14
+ */
15
+ // Factory + engine.
16
+ export { createWebVisualizationEngine } from './createWebVisualizationEngine.js';
17
+ export { WebVisualizationEngine } from './WebVisualizationEngine.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ;;;;;;;GAOG;AAEH,oBAAoB;AACpB,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,28 @@
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 { IFileSystem } from '@salesforce/metadata-core-sdk';
8
+ /**
9
+ * Wrap a host `IFileSystem` so reads under `bundledRoot` resolve through
10
+ * `node:fs` against the adapter's bundled plugin assets, while every other
11
+ * call passes through to the host unchanged.
12
+ *
13
+ * Why this exists: the framework's `visualize(filePath)` flow uses
14
+ * `IPlatformContext.fileSystem` to BOTH parse the user's metadata file AND
15
+ * read the plugin's `index.html` (via HtmlVizGenerator). The web adapter
16
+ * needs the parser-side reads to go through the host's filesystem (so
17
+ * the host's restricted-path rules apply), and the plugin-asset reads to
18
+ * come from the adapter's bundle (so the host's filesystem is never asked
19
+ * for paths it doesn't know about).
20
+ *
21
+ * Only `readFile` and `exists` actually need bundled-side handling — every
22
+ * other `IFileSystem` method (path helpers, workspace ops, writeFile, etc.)
23
+ * is forwarded verbatim. We use a `Proxy` rather than a class with delegating
24
+ * stubs so the wrapper stays in sync automatically when `IFileSystem` grows
25
+ * new members.
26
+ */
27
+ export declare function createCompositeFileSystem(host: IFileSystem, bundledRoot: string): IFileSystem;
28
+ //# sourceMappingURL=CompositeFileSystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompositeFileSystem.d.ts","sourceRoot":"","sources":["../../src/internal/CompositeFileSystem.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAIJ,OAAO,KAAK,EAAE,WAAW,EAAU,MAAM,+BAA+B,CAAC;AAEzE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,CAiD7F"}
@@ -0,0 +1,82 @@
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 * as fs from 'node:fs/promises';
8
+ import * as path from 'node:path';
9
+ /**
10
+ * Wrap a host `IFileSystem` so reads under `bundledRoot` resolve through
11
+ * `node:fs` against the adapter's bundled plugin assets, while every other
12
+ * call passes through to the host unchanged.
13
+ *
14
+ * Why this exists: the framework's `visualize(filePath)` flow uses
15
+ * `IPlatformContext.fileSystem` to BOTH parse the user's metadata file AND
16
+ * read the plugin's `index.html` (via HtmlVizGenerator). The web adapter
17
+ * needs the parser-side reads to go through the host's filesystem (so
18
+ * the host's restricted-path rules apply), and the plugin-asset reads to
19
+ * come from the adapter's bundle (so the host's filesystem is never asked
20
+ * for paths it doesn't know about).
21
+ *
22
+ * Only `readFile` and `exists` actually need bundled-side handling — every
23
+ * other `IFileSystem` method (path helpers, workspace ops, writeFile, etc.)
24
+ * is forwarded verbatim. We use a `Proxy` rather than a class with delegating
25
+ * stubs so the wrapper stays in sync automatically when `IFileSystem` grows
26
+ * new members.
27
+ */
28
+ export function createCompositeFileSystem(host, bundledRoot) {
29
+ const bundledRootNormalized = path.resolve(bundledRoot);
30
+ const isBundled = (p) => {
31
+ if (!p) {
32
+ return false;
33
+ }
34
+ const abs = path.isAbsolute(p) ? path.normalize(p) : path.resolve(p);
35
+ return abs === bundledRootNormalized || abs.startsWith(bundledRootNormalized + path.sep);
36
+ };
37
+ const readFile = async (filePath) => {
38
+ if (!isBundled(filePath)) {
39
+ return host.readFile(filePath);
40
+ }
41
+ try {
42
+ return { success: true, data: await fs.readFile(filePath, 'utf-8') };
43
+ }
44
+ catch (err) {
45
+ return { success: false, error: asError(err) };
46
+ }
47
+ };
48
+ const exists = async (filePath) => {
49
+ if (!isBundled(filePath)) {
50
+ return host.exists(filePath);
51
+ }
52
+ try {
53
+ await fs.stat(filePath);
54
+ return true;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ };
60
+ return new Proxy(host, {
61
+ get(target, prop) {
62
+ if (prop === 'readFile') {
63
+ return readFile;
64
+ }
65
+ if (prop === 'exists') {
66
+ return exists;
67
+ }
68
+ const value = target[prop];
69
+ // Bind methods to the host so `this` resolves correctly inside them.
70
+ return typeof value === 'function'
71
+ ? value.bind(target)
72
+ : value;
73
+ },
74
+ });
75
+ }
76
+ function asError(value) {
77
+ if (value && typeof value === 'object' && 'message' in value) {
78
+ return value;
79
+ }
80
+ return new Error(String(value));
81
+ }
82
+ //# sourceMappingURL=CompositeFileSystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompositeFileSystem.js","sourceRoot":"","sources":["../../src/internal/CompositeFileSystem.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAiB,EAAE,WAAmB;IAC9E,MAAM,qBAAqB,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAExD,MAAM,SAAS,GAAG,CAAC,CAAS,EAAW,EAAE;QACvC,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACrE,OAAO,GAAG,KAAK,qBAAqB,IAAI,GAAG,CAAC,UAAU,CAAC,qBAAqB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3F,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAgB,EAA2B,EAAE;QACnE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;QACvE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,KAAK,EAAE,QAAgB,EAAoB,EAAE;QAC1D,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE;QACrB,GAAG,CAAC,MAAmB,EAAE,IAAqB;YAC5C,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBACxB,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,MAAM,KAAK,GAAI,MAAsD,CAAC,IAAI,CAAC,CAAC;YAC5E,qEAAqE;YACrE,OAAO,OAAO,KAAK,KAAK,UAAU;gBAChC,CAAC,CAAE,KAAyC,CAAC,IAAI,CAAC,MAAM,CAAC;gBACzD,CAAC,CAAC,KAAK,CAAC;QACZ,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QAC7D,OAAO,KAAc,CAAC;IACxB,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,30 @@
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 { BundledPluginAssetReader } from '../pluginAssets/BundledPluginAssetReader.js';
8
+ /**
9
+ * Asset reader interface - the minimal contract needed for asset inlining.
10
+ */
11
+ type AssetReader = Pick<BundledPluginAssetReader, 'readPluginAsset' | 'readPluginIndexHtml' | 'readDesignSystemCss'>;
12
+ /**
13
+ * Inline all external assets (JS, CSS) referenced in a plugin's HTML into
14
+ * a single self-contained HTML document. This eliminates the waterfall of
15
+ * HTTP requests when loading a plugin in an iframe.
16
+ *
17
+ * Transformations:
18
+ * - <script src="./assets/index.js"> → <script>...inlined code...</script>
19
+ * - <link href="./assets/index.css"> → <style>...inlined css...</style>
20
+ * - Fonts/images in CSS remain as relative paths (or convert to data: URLs)
21
+ *
22
+ * @param html - Plugin's index.html content
23
+ * @param pluginId - Plugin identifier for asset resolution
24
+ * @param assetReader - Reader to fetch plugin assets
25
+ * @param platformCss - Optional platform CSS to inline (from @dist/ references)
26
+ * @returns HTML with all assets inlined
27
+ */
28
+ export declare function inlineAssets(html: string, pluginId: string, assetReader: AssetReader, platformCss?: string): Promise<string>;
29
+ export {};
30
+ //# sourceMappingURL=assetInliner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetInliner.d.ts","sourceRoot":"","sources":["../../src/internal/assetInliner.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AAE5F;;GAEG;AACH,KAAK,WAAW,GAAG,IAAI,CACrB,wBAAwB,EACxB,iBAAiB,GAAG,qBAAqB,GAAG,qBAAqB,CAClE,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,WAAW,EACxB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAajB"}
@@ -0,0 +1,126 @@
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
+ * Inline all external assets (JS, CSS) referenced in a plugin's HTML into
9
+ * a single self-contained HTML document. This eliminates the waterfall of
10
+ * HTTP requests when loading a plugin in an iframe.
11
+ *
12
+ * Transformations:
13
+ * - <script src="./assets/index.js"> → <script>...inlined code...</script>
14
+ * - <link href="./assets/index.css"> → <style>...inlined css...</style>
15
+ * - Fonts/images in CSS remain as relative paths (or convert to data: URLs)
16
+ *
17
+ * @param html - Plugin's index.html content
18
+ * @param pluginId - Plugin identifier for asset resolution
19
+ * @param assetReader - Reader to fetch plugin assets
20
+ * @param platformCss - Optional platform CSS to inline (from @dist/ references)
21
+ * @returns HTML with all assets inlined
22
+ */
23
+ export async function inlineAssets(html, pluginId, assetReader, platformCss) {
24
+ // First, inline platform CSS (@dist/ references)
25
+ if (platformCss) {
26
+ html = inlinePlatformCss(html, platformCss);
27
+ }
28
+ // Inline all <script src="..."> tags
29
+ html = await inlineScripts(html, pluginId, assetReader);
30
+ // Inline all <link rel="stylesheet" href="..."> tags
31
+ html = await inlineStylesheets(html, pluginId, assetReader);
32
+ return html;
33
+ }
34
+ /**
35
+ * Replace @dist/ link tags with inlined platform CSS.
36
+ */
37
+ function inlinePlatformCss(html, platformCss) {
38
+ // Match: <link ... href="@dist/design-system/platform.css" ...>
39
+ const linkPattern = /<link\b[^>]*?\bhref=["']@dist\/[^"']*["'][^>]*?>/gi;
40
+ return html.replace(linkPattern, () => {
41
+ return `<style data-source="platform-css">\n${escapeForStyleTag(platformCss)}\n</style>`;
42
+ });
43
+ }
44
+ /**
45
+ * Escape a JS payload so it cannot prematurely close the surrounding <script> tag.
46
+ * Browsers terminate <script> on the literal substring `</script` (case-insensitive,
47
+ * regardless of whether a `>` follows), so any occurrence inside the payload — common
48
+ * in templated HTML strings, regex literals, or React server output — must be broken.
49
+ * `<\/script` is semantically identical in JS source but invisible to the HTML parser.
50
+ */
51
+ function escapeForScriptTag(code) {
52
+ return code.replace(/<\/script/gi, '<\\/script');
53
+ }
54
+ /**
55
+ * Escape a CSS payload so it cannot prematurely close the surrounding <style> tag.
56
+ * Same hazard as escapeForScriptTag, but for `</style`. Replaced with `<\/style`,
57
+ * which CSS tokenizers ignore (the backslash is a valid CSS escape character).
58
+ */
59
+ function escapeForStyleTag(css) {
60
+ return css.replace(/<\/style/gi, '<\\/style');
61
+ }
62
+ /**
63
+ * Inline all <script src="..."> tags that reference relative paths.
64
+ * Resolves each unique tag to its replacement asynchronously, then runs a single
65
+ * global regex pass so duplicate tags (e.g. shared vendor chunks) are all rewritten.
66
+ */
67
+ async function inlineScripts(html, pluginId, assetReader) {
68
+ // Match: <script ... src="..." ...>
69
+ const scriptPattern = /<script\b([^>]*?\bsrc=["'])([^"']+)(["'][^>]*?)>/gi;
70
+ const replacements = new Map();
71
+ for (const tagMatch of html.matchAll(scriptPattern)) {
72
+ const fullTag = tagMatch[0];
73
+ const url = tagMatch[2];
74
+ if (replacements.has(fullTag) || isAbsoluteOrRooted(url)) {
75
+ continue;
76
+ }
77
+ const assetPath = url.startsWith('./') ? url.slice(2) : url;
78
+ try {
79
+ const bytes = await assetReader.readPluginAsset(pluginId, assetPath);
80
+ const code = escapeForScriptTag(new TextDecoder('utf-8').decode(bytes));
81
+ const inlineScript = fullTag.includes('type="module"')
82
+ ? `<script type="module">\n${code}\n</script>`
83
+ : `<script>\n${code}\n</script>`;
84
+ replacements.set(fullTag, inlineScript);
85
+ }
86
+ catch (err) {
87
+ // eslint-disable-next-line no-console
88
+ console.warn(`[assetInliner] Failed to inline script: ${assetPath}`, err);
89
+ // Leave fullTag absent from replacements so the original tag is preserved
90
+ }
91
+ }
92
+ // Single global pass: every occurrence of every resolved tag is rewritten.
93
+ return html.replace(scriptPattern, (fullTag) => replacements.get(fullTag) ?? fullTag);
94
+ }
95
+ /**
96
+ * Inline all <link rel="stylesheet" href="..."> tags that reference relative paths.
97
+ * Same single-pass strategy as inlineScripts to handle duplicate stylesheet refs.
98
+ */
99
+ async function inlineStylesheets(html, pluginId, assetReader) {
100
+ // Match: <link ... rel="stylesheet" ... href="..." ...>
101
+ const linkPattern = /<link\b[^>]*?\brel=["']stylesheet["'][^>]*?\bhref=["']([^"']+)["'][^>]*?>/gi;
102
+ const replacements = new Map();
103
+ for (const tagMatch of html.matchAll(linkPattern)) {
104
+ const fullTag = tagMatch[0];
105
+ const url = tagMatch[1];
106
+ if (replacements.has(fullTag) || isAbsoluteOrRooted(url)) {
107
+ continue;
108
+ }
109
+ const assetPath = url.startsWith('./') ? url.slice(2) : url;
110
+ try {
111
+ const bytes = await assetReader.readPluginAsset(pluginId, assetPath);
112
+ const css = escapeForStyleTag(new TextDecoder('utf-8').decode(bytes));
113
+ replacements.set(fullTag, `<style data-source="${assetPath}">\n${css}\n</style>`);
114
+ }
115
+ catch (err) {
116
+ // eslint-disable-next-line no-console
117
+ console.warn(`[assetInliner] Failed to inline stylesheet: ${assetPath}`, err);
118
+ }
119
+ }
120
+ return html.replace(linkPattern, (fullTag) => replacements.get(fullTag) ?? fullTag);
121
+ }
122
+ function isAbsoluteOrRooted(url) {
123
+ // http(s)://, //cdn..., data:, blob:, /already-rooted
124
+ return /^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith('//') || url.startsWith('/');
125
+ }
126
+ //# sourceMappingURL=assetInliner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetInliner.js","sourceRoot":"","sources":["../../src/internal/assetInliner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
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
+ * Bootstrap script for browser-iframe hosts.
9
+ *
10
+ * Defines `window.__ExtensionHostPostMessage` as a thin wrapper around
11
+ * `window.parent.postMessage(msg, '*')`. The embedding host's parent
12
+ * window is responsible for relaying the message to its server (e.g. via
13
+ * a `POST /visualize` REST call).
14
+ *
15
+ * Self-checks at runtime that the script is actually running inside a
16
+ * frame; logs an error if not, since `__ExtensionHostPostMessage` would
17
+ * otherwise post to the same window.
18
+ */
19
+ export declare const BROWSER_IFRAME_BOOTSTRAP: string;
20
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/internal/constants.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,QAc7B,CAAC"}
@@ -0,0 +1,34 @@
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
+ * Bootstrap script for browser-iframe hosts.
9
+ *
10
+ * Defines `window.__ExtensionHostPostMessage` as a thin wrapper around
11
+ * `window.parent.postMessage(msg, '*')`. The embedding host's parent
12
+ * window is responsible for relaying the message to its server (e.g. via
13
+ * a `POST /visualize` REST call).
14
+ *
15
+ * Self-checks at runtime that the script is actually running inside a
16
+ * frame; logs an error if not, since `__ExtensionHostPostMessage` would
17
+ * otherwise post to the same window.
18
+ */
19
+ export const BROWSER_IFRAME_BOOTSTRAP = `
20
+ <script>
21
+ (function() {
22
+ if (window.parent === window) {
23
+ console.error('[browser-bootstrap] Not running inside a frame; __ExtensionHostPostMessage needs a parent window.');
24
+ return;
25
+ }
26
+ Object.defineProperty(window, '__ExtensionHostPostMessage', {
27
+ value: function(msg) { window.parent.postMessage(msg, '*'); },
28
+ writable: false,
29
+ configurable: false
30
+ });
31
+ })();
32
+ </script>
33
+ `.trim();
34
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/internal/constants.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;CAcvC,CAAC,IAAI,EAAE,CAAC"}
@@ -0,0 +1,50 @@
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
+ * Pure HTML transforms that prepare a plugin's `index.html` for delivery to
9
+ * an iframe under a host's URL prefixes. No I/O. No host imports.
10
+ *
11
+ * The three transforms are applied by `WebVisualizationEngine.getPluginIndexHtml`
12
+ * in this order:
13
+ * 1. rewriteDistPlaceholders — turn `@dist/...` into URLs under the
14
+ * consumer's `platformAssetBaseUrl` (the platform CSS specifically).
15
+ * 2. rewritePluginAssetUrls — turn the plugin's relative asset URLs
16
+ * (`./assets/index-abc.js`, `./fonts/x.woff2`, etc.) into absolute
17
+ * URLs under `pluginUiBaseUrl`.
18
+ * 3. injectBootstrap — splice the host bridge's bootstrap
19
+ * `<script>` into the document so plugins can postMessage to host.
20
+ */
21
+ /**
22
+ * Inject the host-bridge bootstrap `<script>` into the document. Tries
23
+ * `</head>` first, falls back to `</body>`, and prepends if neither exists.
24
+ */
25
+ export declare function injectBootstrap(html: string, scriptTag: string): string;
26
+ /**
27
+ * Rewrite `@dist/` placeholders in the plugin's HTML to URLs under the
28
+ * consumer's platform-asset base URL. Plugins emit `<link href="@dist/design-system/platform.css">`
29
+ * as a host-portable indirection. The web adapter resolves it to
30
+ * `<base>/design-system/platform.css`, where `<base>` is the consumer-supplied
31
+ * `platformAssetBaseUrl`.
32
+ */
33
+ export declare function rewriteDistPlaceholders(html: string, platformAssetBaseUrl: string): string;
34
+ /**
35
+ * Rewrite the plugin's RELATIVE asset URLs to absolute URLs under
36
+ * `pluginUiBaseUrl`. Today, plugin builds emit:
37
+ *
38
+ * <script type="module" crossorigin src="./assets/index-abc.js"></script>
39
+ * <link rel="stylesheet" crossorigin href="./assets/index-abc.css">
40
+ *
41
+ * They may also emit `./fonts/...`, `./images/...`, or other relative
42
+ * paths in the future. We rewrite ANY relative path on `<script src>`
43
+ * and `<link href>` (i.e., starts with `./` or `assets/`-style without
44
+ * leading slash) to `<base>/<original>`.
45
+ *
46
+ * The "assets/" path segment lives only in this file. The consumer's
47
+ * route handlers never see it.
48
+ */
49
+ export declare function rewritePluginAssetUrls(html: string, pluginUiBaseUrl: string): string;
50
+ //# sourceMappingURL=htmlPipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"htmlPipeline.d.ts","sourceRoot":"","sources":["../../src/internal/htmlPipeline.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ;;;;;;;;;;;;;GAaG;AAEH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAQvE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAG1F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CA4BpF"}
@@ -0,0 +1,86 @@
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
+ * Pure HTML transforms that prepare a plugin's `index.html` for delivery to
9
+ * an iframe under a host's URL prefixes. No I/O. No host imports.
10
+ *
11
+ * The three transforms are applied by `WebVisualizationEngine.getPluginIndexHtml`
12
+ * in this order:
13
+ * 1. rewriteDistPlaceholders — turn `@dist/...` into URLs under the
14
+ * consumer's `platformAssetBaseUrl` (the platform CSS specifically).
15
+ * 2. rewritePluginAssetUrls — turn the plugin's relative asset URLs
16
+ * (`./assets/index-abc.js`, `./fonts/x.woff2`, etc.) into absolute
17
+ * URLs under `pluginUiBaseUrl`.
18
+ * 3. injectBootstrap — splice the host bridge's bootstrap
19
+ * `<script>` into the document so plugins can postMessage to host.
20
+ */
21
+ /**
22
+ * Inject the host-bridge bootstrap `<script>` into the document. Tries
23
+ * `</head>` first, falls back to `</body>`, and prepends if neither exists.
24
+ */
25
+ export function injectBootstrap(html, scriptTag) {
26
+ if (html.includes('</head>')) {
27
+ return html.replace('</head>', `${scriptTag}\n</head>`);
28
+ }
29
+ if (html.includes('</body>')) {
30
+ return html.replace('</body>', `${scriptTag}\n</body>`);
31
+ }
32
+ return `${scriptTag}\n${html}`;
33
+ }
34
+ /**
35
+ * Rewrite `@dist/` placeholders in the plugin's HTML to URLs under the
36
+ * consumer's platform-asset base URL. Plugins emit `<link href="@dist/design-system/platform.css">`
37
+ * as a host-portable indirection. The web adapter resolves it to
38
+ * `<base>/design-system/platform.css`, where `<base>` is the consumer-supplied
39
+ * `platformAssetBaseUrl`.
40
+ */
41
+ export function rewriteDistPlaceholders(html, platformAssetBaseUrl) {
42
+ const base = stripTrailingSlash(platformAssetBaseUrl);
43
+ return html.replace(/@dist\//g, `${base}/`);
44
+ }
45
+ /**
46
+ * Rewrite the plugin's RELATIVE asset URLs to absolute URLs under
47
+ * `pluginUiBaseUrl`. Today, plugin builds emit:
48
+ *
49
+ * <script type="module" crossorigin src="./assets/index-abc.js"></script>
50
+ * <link rel="stylesheet" crossorigin href="./assets/index-abc.css">
51
+ *
52
+ * They may also emit `./fonts/...`, `./images/...`, or other relative
53
+ * paths in the future. We rewrite ANY relative path on `<script src>`
54
+ * and `<link href>` (i.e., starts with `./` or `assets/`-style without
55
+ * leading slash) to `<base>/<original>`.
56
+ *
57
+ * The "assets/" path segment lives only in this file. The consumer's
58
+ * route handlers never see it.
59
+ */
60
+ export function rewritePluginAssetUrls(html, pluginUiBaseUrl) {
61
+ const base = stripTrailingSlash(pluginUiBaseUrl);
62
+ // Match <script ... src="..."> and <link ... href="..."> attributes.
63
+ // We rewrite only paths that look relative; we leave absolute URLs and
64
+ // already-absolute paths alone. The trailing closing-quote is included
65
+ // in the replacement, so we don't need a separate capture for it.
66
+ const rewrite = (match, prefix, quote, url) => {
67
+ if (isAbsoluteOrRooted(url)) {
68
+ return match;
69
+ }
70
+ const cleaned = url.startsWith('./') ? url.slice(2) : url;
71
+ return `${prefix}${quote}${base}/${cleaned}${quote}`;
72
+ };
73
+ // Process <script src="..."> tags.
74
+ html = html.replace(/(<script\b[^>]*?\bsrc=)(["'])([^"']+)\2/gi, (m, p, q, u) => rewrite(m, p, q, u));
75
+ // Process <link href="..."> tags.
76
+ html = html.replace(/(<link\b[^>]*?\bhref=)(["'])([^"']+)\2/gi, (m, p, q, u) => rewrite(m, p, q, u));
77
+ return html;
78
+ }
79
+ function isAbsoluteOrRooted(url) {
80
+ // http(s)://, //cdn..., data:, blob:, /already-rooted
81
+ return /^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith('//') || url.startsWith('/');
82
+ }
83
+ function stripTrailingSlash(s) {
84
+ return s.endsWith('/') ? s.slice(0, -1) : s;
85
+ }
86
+ //# sourceMappingURL=htmlPipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"htmlPipeline.js","sourceRoot":"","sources":["../../src/internal/htmlPipeline.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ;;;;;;;;;;;;;GAaG;AAEH;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,SAAiB;IAC7D,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,WAAW,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,WAAW,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,GAAG,SAAS,KAAK,IAAI,EAAE,CAAC;AACjC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,oBAA4B;IAChF,MAAM,IAAI,GAAG,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;IACtD,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,eAAuB;IAC1E,MAAM,IAAI,GAAG,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAEjD,qEAAqE;IACrE,uEAAuE;IACvE,uEAAuE;IACvE,kEAAkE;IAClE,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,MAAc,EAAE,KAAa,EAAE,GAAW,EAAU,EAAE;QACpF,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC1D,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;IACvD,CAAC,CAAC;IAEF,mCAAmC;IACnC,IAAI,GAAG,IAAI,CAAC,OAAO,CACjB,2CAA2C,EAC3C,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CACpE,CAAC;IAEF,kCAAkC;IAClC,IAAI,GAAG,IAAI,CAAC,OAAO,CACjB,0CAA0C,EAC1C,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CACpE,CAAC;IAEF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,sDAAsD;IACtD,OAAO,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACzF,CAAC;AAED,SAAS,kBAAkB,CAAC,CAAS;IACnC,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,34 @@
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
+ * Plugin asset reader for the web adapter.
9
+ *
10
+ * Reads plugin React builds and the platform CSS from a bundled `dist/`
11
+ * directory, populated by `scripts/copy-plugin-assets.mjs` at build time.
12
+ * The adapter has zero runtime dependency on `@salesforce/metadata-plugins`
13
+ * — this reader only touches paths under its constructor-provided
14
+ * `bundledRoot`.
15
+ *
16
+ * Layout under `bundledRoot`:
17
+ * <root>/plugins/<pluginId>/ui/index.html
18
+ * <root>/plugins/<pluginId>/ui/assets/...
19
+ * <root>/design-system/platform.css
20
+ */
21
+ export declare class BundledPluginAssetReader {
22
+ private readonly bundledRoot;
23
+ /**
24
+ * @param bundledRoot Absolute path to the directory containing the
25
+ * `plugins/` and `design-system/` subdirs. The factory in
26
+ * `createWebVisualizationEngine` resolves this to the package's own
27
+ * `dist/` at runtime; tests pass a tempdir.
28
+ */
29
+ constructor(bundledRoot: string);
30
+ readPluginIndexHtml(pluginId: string): Promise<string>;
31
+ readPluginAsset(pluginId: string, relativePath: string): Promise<Uint8Array>;
32
+ readDesignSystemCss(): Promise<string>;
33
+ }
34
+ //# sourceMappingURL=BundledPluginAssetReader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BundledPluginAssetReader.d.ts","sourceRoot":"","sources":["../../src/pluginAssets/BundledPluginAssetReader.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAOJ;;;;;;;;;;;;;GAaG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IAErC;;;;;OAKG;gBACS,WAAW,EAAE,MAAM;IAIzB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAetD,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAe5E,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;CAW7C"}
@@ -0,0 +1,77 @@
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 * as fs from 'node:fs/promises';
8
+ import * as path from 'node:path';
9
+ import { REACT_UI_DIR_NAME } from '@salesforce/metadata-core-sdk';
10
+ import { AssetNotFoundError, PluginNotFoundError } from '../errors/index.js';
11
+ /**
12
+ * Plugin asset reader for the web adapter.
13
+ *
14
+ * Reads plugin React builds and the platform CSS from a bundled `dist/`
15
+ * directory, populated by `scripts/copy-plugin-assets.mjs` at build time.
16
+ * The adapter has zero runtime dependency on `@salesforce/metadata-plugins`
17
+ * — this reader only touches paths under its constructor-provided
18
+ * `bundledRoot`.
19
+ *
20
+ * Layout under `bundledRoot`:
21
+ * <root>/plugins/<pluginId>/ui/index.html
22
+ * <root>/plugins/<pluginId>/ui/assets/...
23
+ * <root>/design-system/platform.css
24
+ */
25
+ export class BundledPluginAssetReader {
26
+ /**
27
+ * @param bundledRoot Absolute path to the directory containing the
28
+ * `plugins/` and `design-system/` subdirs. The factory in
29
+ * `createWebVisualizationEngine` resolves this to the package's own
30
+ * `dist/` at runtime; tests pass a tempdir.
31
+ */
32
+ constructor(bundledRoot) {
33
+ this.bundledRoot = bundledRoot;
34
+ }
35
+ async readPluginIndexHtml(pluginId) {
36
+ const indexPath = path.join(this.bundledRoot, 'plugins', pluginId, REACT_UI_DIR_NAME, 'index.html');
37
+ try {
38
+ return await fs.readFile(indexPath, 'utf-8');
39
+ }
40
+ catch (err) {
41
+ throw mapEnoent(err, () => new PluginNotFoundError(pluginId));
42
+ }
43
+ }
44
+ async readPluginAsset(pluginId, relativePath) {
45
+ const assetPath = path.join(this.bundledRoot, 'plugins', pluginId, REACT_UI_DIR_NAME, relativePath);
46
+ try {
47
+ return await fs.readFile(assetPath);
48
+ }
49
+ catch (err) {
50
+ throw mapEnoent(err, () => new AssetNotFoundError(pluginId, relativePath));
51
+ }
52
+ }
53
+ async readDesignSystemCss() {
54
+ const cssPath = path.join(this.bundledRoot, 'design-system', 'platform.css');
55
+ try {
56
+ return await fs.readFile(cssPath, 'utf-8');
57
+ }
58
+ catch (err) {
59
+ throw mapEnoent(err, () => new Error(`Platform CSS not found in bundled dist (looked at ${cssPath})`));
60
+ }
61
+ }
62
+ }
63
+ function mapEnoent(err, build) {
64
+ // We avoid `instanceof Error` here because cross-realm errors (e.g. errors
65
+ // thrown by node:fs/promises and observed by a CommonJS-compiled test) can
66
+ // fail the prototype check even though they are functionally Error objects.
67
+ // Duck-type on `code` and gracefully wrap anything else.
68
+ const code = err?.code;
69
+ if (code === 'ENOENT') {
70
+ return build();
71
+ }
72
+ if (err && typeof err === 'object' && 'message' in err) {
73
+ return err;
74
+ }
75
+ return new Error(String(err));
76
+ }
77
+ //# sourceMappingURL=BundledPluginAssetReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BundledPluginAssetReader.js","sourceRoot":"","sources":["../../src/pluginAssets/BundledPluginAssetReader.ts"],"names":[],"mappings":"AAAA;;;;;IAKI;AAEJ,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE7E;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,wBAAwB;IAGnC;;;;;OAKG;IACH,YAAY,WAAmB;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,QAAgB;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CACzB,IAAI,CAAC,WAAW,EAChB,SAAS,EACT,QAAQ,EACR,iBAAiB,EACjB,YAAY,CACb,CAAC;QACF,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,YAAoB;QAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CACzB,IAAI,CAAC,WAAW,EAChB,SAAS,EACT,QAAQ,EACR,iBAAiB,EACjB,YAAY,CACb,CAAC;QACF,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,kBAAkB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC;QAC7E,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,SAAS,CACb,GAAG,EACH,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,qDAAqD,OAAO,GAAG,CAAC,CACjF,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAED,SAAS,SAAS,CAAC,GAAY,EAAE,KAAkB;IACjD,2EAA2E;IAC3E,2EAA2E;IAC3E,4EAA4E;IAC5E,yDAAyD;IACzD,MAAM,IAAI,GAAI,GAAoC,EAAE,IAAI,CAAC;IACzD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,KAAK,EAAE,CAAC;IACjB,CAAC;IACD,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;QACvD,OAAO,GAAY,CAAC;IACtB,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAChC,CAAC"}