@salesforce/webapp-experimental 1.80.1 → 1.82.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/api/clients.js +72 -77
  2. package/dist/api/index.d.ts +4 -4
  3. package/dist/api/index.d.ts.map +1 -1
  4. package/dist/api/index.js +13 -11
  5. package/dist/api/utils/accounts.js +16 -30
  6. package/dist/api/utils/records.js +21 -20
  7. package/dist/api/utils/user.js +20 -28
  8. package/dist/app/index.d.ts +4 -4
  9. package/dist/app/index.d.ts.map +1 -1
  10. package/dist/app/index.js +7 -7
  11. package/dist/app/manifest.js +23 -37
  12. package/dist/app/org.js +45 -58
  13. package/dist/design/index.js +12 -19
  14. package/dist/design/interactions/interactionsController.d.ts +1 -6
  15. package/dist/design/interactions/interactionsController.d.ts.map +1 -1
  16. package/dist/index.d.ts +4 -4
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +25 -10
  19. package/dist/package.json.js +4 -0
  20. package/dist/proxy/handler.d.ts +2 -7
  21. package/dist/proxy/handler.d.ts.map +1 -1
  22. package/dist/proxy/handler.js +462 -523
  23. package/dist/proxy/index.d.ts +2 -2
  24. package/dist/proxy/index.d.ts.map +1 -1
  25. package/dist/proxy/index.js +7 -6
  26. package/dist/proxy/livePreviewScript.js +11 -26
  27. package/dist/proxy/routing.d.ts +1 -6
  28. package/dist/proxy/routing.d.ts.map +1 -1
  29. package/dist/proxy/routing.js +73 -103
  30. package/package.json +7 -6
  31. package/dist/api/clients.test.d.ts +0 -7
  32. package/dist/api/clients.test.d.ts.map +0 -1
  33. package/dist/api/clients.test.js +0 -167
  34. package/dist/api/graphql-operations-types.js +0 -44
  35. package/dist/api/utils/records.test.d.ts +0 -7
  36. package/dist/api/utils/records.test.d.ts.map +0 -1
  37. package/dist/api/utils/records.test.js +0 -190
  38. package/dist/api/utils/user.test.d.ts +0 -7
  39. package/dist/api/utils/user.test.d.ts.map +0 -1
  40. package/dist/api/utils/user.test.js +0 -108
  41. package/dist/design/interactions/communicationManager.js +0 -108
  42. package/dist/design/interactions/componentMatcher.js +0 -80
  43. package/dist/design/interactions/editableManager.js +0 -95
  44. package/dist/design/interactions/eventHandlers.js +0 -125
  45. package/dist/design/interactions/index.js +0 -47
  46. package/dist/design/interactions/interactionsController.js +0 -135
  47. package/dist/design/interactions/styleManager.js +0 -97
  48. package/dist/design/interactions/utils/cssUtils.js +0 -72
  49. package/dist/design/interactions/utils/sourceUtils.js +0 -99
  50. package/dist/proxy/livePreviewScript.test.d.ts +0 -7
  51. package/dist/proxy/livePreviewScript.test.d.ts.map +0 -1
  52. package/dist/proxy/livePreviewScript.test.js +0 -96
@@ -1,125 +0,0 @@
1
- /**
2
- * Copyright (c) 2026, Salesforce, Inc.,
3
- * All rights reserved.
4
- * For full license text, see the LICENSE.txt file
5
- */
6
- /**
7
- * Event Handlers Module
8
- * Handles mouse and click events for highlighting
9
- */
10
- import { findElementsBySourceLocation, getSourceFromDataAttributes } from "./utils/sourceUtils.js";
11
- export class EventHandlers {
12
- isInteractionsActive;
13
- componentMatcher;
14
- styleManager;
15
- editableManager;
16
- communicationManager;
17
- currentHighlightedElements;
18
- selectedElement;
19
- selectedElements;
20
- constructor(isInteractionsActive, componentMatcher, styleManager, editableManager, communicationManager) {
21
- this.isInteractionsActive = isInteractionsActive;
22
- this.componentMatcher = componentMatcher;
23
- this.styleManager = styleManager;
24
- this.editableManager = editableManager;
25
- this.communicationManager = communicationManager;
26
- this.currentHighlightedElements = [];
27
- this.selectedElement = null;
28
- this.selectedElements = [];
29
- // Bind methods to preserve 'this' context
30
- this.handleMouseOver = this.handleMouseOver.bind(this);
31
- this.handleMouseLeave = this.handleMouseLeave.bind(this);
32
- this.handleClick = this.handleClick.bind(this);
33
- }
34
- _findHighlightableElement(target) {
35
- return this.componentMatcher.findHighlightableElement(target);
36
- }
37
- handleMouseOver(e) {
38
- if (!this.isInteractionsActive()) {
39
- return;
40
- }
41
- e.stopPropagation();
42
- const target = e.target;
43
- if (target.nodeType !== 1 || target.tagName === "HTML" || target.tagName === "BODY") {
44
- return;
45
- }
46
- const element = this._findHighlightableElement(target);
47
- if (!element) {
48
- return;
49
- }
50
- if (this.currentHighlightedElements.includes(element) ||
51
- (this.selectedElement && this.selectedElement === element)) {
52
- return;
53
- }
54
- if (this.currentHighlightedElements.length > 0 &&
55
- !this.currentHighlightedElements[0].classList.contains("design-mode-selected")) {
56
- this.styleManager.unhighlightElements(this.currentHighlightedElements);
57
- this.currentHighlightedElements = [];
58
- }
59
- const allElements = findElementsBySourceLocation(getSourceFromDataAttributes(element));
60
- this.styleManager.highlightElements(allElements);
61
- this.currentHighlightedElements = allElements;
62
- }
63
- handleMouseLeave() {
64
- if (!this.isInteractionsActive()) {
65
- return;
66
- }
67
- if (this.currentHighlightedElements.length > 0 &&
68
- !this.currentHighlightedElements[0].classList.contains("design-mode-selected")) {
69
- this.styleManager.unhighlightElements(this.currentHighlightedElements);
70
- this.currentHighlightedElements = [];
71
- }
72
- }
73
- handleClick(e) {
74
- if (!this.isInteractionsActive()) {
75
- return;
76
- }
77
- e.preventDefault();
78
- e.stopPropagation();
79
- const target = e.target;
80
- if (target.nodeType !== 1 || target.tagName === "HTML" || target.tagName === "BODY") {
81
- return;
82
- }
83
- const element = this._findHighlightableElement(target);
84
- if (!element) {
85
- return;
86
- }
87
- if (this.selectedElement && this.selectedElement === element) {
88
- return;
89
- }
90
- // Deselect previous element and its same elements
91
- if (this.selectedElement) {
92
- this.styleManager.deselectElements(this.selectedElements);
93
- this.editableManager.removeEditable(this.selectedElement);
94
- }
95
- // Remove highlight from current highlighted elements
96
- if (this.currentHighlightedElements.length > 0) {
97
- this.styleManager.unhighlightElements(this.currentHighlightedElements);
98
- this.currentHighlightedElements = [];
99
- }
100
- // Select new element and all elements at the same source location
101
- this.selectedElement = element;
102
- const allElements = findElementsBySourceLocation(getSourceFromDataAttributes(element));
103
- this.selectedElements = allElements;
104
- this.styleManager.selectElements(allElements);
105
- // Make text elements editable
106
- this.editableManager.makeEditableIfText(element);
107
- // Notify extension
108
- this.communicationManager.notifyComponentSelected(element);
109
- }
110
- clearAll() {
111
- if (this.currentHighlightedElements.length > 0) {
112
- this.styleManager.unhighlightElements(this.currentHighlightedElements);
113
- this.currentHighlightedElements = [];
114
- }
115
- if (this.selectedElement) {
116
- this.styleManager.deselectElements(this.selectedElements);
117
- this.editableManager.removeEditable(this.selectedElement);
118
- this.selectedElement = null;
119
- this.selectedElements = [];
120
- }
121
- }
122
- getSelectedElement() {
123
- return this.selectedElement;
124
- }
125
- }
@@ -1,47 +0,0 @@
1
- /**
2
- * Copyright (c) 2026, Salesforce, Inc.,
3
- * All rights reserved.
4
- * For full license text, see the LICENSE.txt file
5
- */
6
- /**
7
- * Entry point for bundling the design mode interactions
8
- * This file is used by esbuild to create the bundled version
9
- */
10
- import { InteractionsController } from "./interactionsController.js";
11
- import { parseSourceLocation } from "./utils/sourceUtils.js";
12
- const interactions = new InteractionsController(true);
13
- if (typeof document !== "undefined") {
14
- if (document.readyState === "loading") {
15
- document.addEventListener("DOMContentLoaded", () => {
16
- interactions.initialize();
17
- });
18
- }
19
- else {
20
- interactions.initialize();
21
- }
22
- }
23
- // Expose global functions
24
- if (typeof window !== "undefined") {
25
- window.enableInteractions = function () {
26
- interactions.enable();
27
- };
28
- window.disableInteractions = function () {
29
- interactions.disable();
30
- };
31
- window.addEventListener("message", function (event) {
32
- const data = event.data;
33
- const typed = data && typeof data === "object" ? data : null;
34
- if (typed && typed.type === "style-change") {
35
- interactions.applyStyleChange(String(typed.property ?? ""), String(typed.value ?? ""), parseSourceLocation(typed.sourceLocation));
36
- }
37
- if (typed && typed.type === "text-change") {
38
- interactions.applyTextChange(String(typed.text ?? ""), parseSourceLocation(typed.sourceLocation));
39
- }
40
- if (typed && typed.type === "enable-interactions") {
41
- window.enableInteractions?.();
42
- }
43
- if (typed && typed.type === "disable-interactions") {
44
- window.disableInteractions?.();
45
- }
46
- });
47
- }
@@ -1,135 +0,0 @@
1
- /**
2
- * Copyright (c) 2026, Salesforce, Inc.,
3
- * All rights reserved.
4
- * For full license text, see the LICENSE.txt file
5
- */
6
- /**
7
- * Interactions Controller Module
8
- * Main controller that orchestrates all interaction modules
9
- */
10
- import { CommunicationManager } from "./communicationManager.js";
11
- import { ComponentMatcher } from "./componentMatcher.js";
12
- import { EditableManager } from "./editableManager.js";
13
- import { EventHandlers } from "./eventHandlers.js";
14
- import { StyleManager } from "./styleManager.js";
15
- import { findElementsBySourceLocation, getSourceFromDataAttributes, } from "./utils/sourceUtils.js";
16
- export class InteractionsController {
17
- enabled;
18
- isActive;
19
- componentMatcher;
20
- styleManager;
21
- communicationManager;
22
- editableManager;
23
- eventHandlers;
24
- constructor(enabled = true) {
25
- this.enabled = enabled;
26
- this.isActive = false;
27
- // Initialize modules
28
- this.componentMatcher = new ComponentMatcher({
29
- allowlist: [
30
- "div",
31
- "p",
32
- "span",
33
- "h1",
34
- "h2",
35
- "h3",
36
- "h4",
37
- "h5",
38
- "h6",
39
- "a",
40
- "button",
41
- "input",
42
- "select",
43
- "textarea",
44
- "label",
45
- "section",
46
- "article",
47
- "main",
48
- "aside",
49
- "header",
50
- "footer",
51
- "nav",
52
- "figure",
53
- "figcaption",
54
- "ul",
55
- "ol",
56
- "li",
57
- "table",
58
- "tr",
59
- "td",
60
- "th",
61
- "blockquote",
62
- "img",
63
- ],
64
- });
65
- this.styleManager = new StyleManager();
66
- this.communicationManager = new CommunicationManager();
67
- this.editableManager = new EditableManager(this.communicationManager);
68
- this.eventHandlers = new EventHandlers(() => this.isActive, this.componentMatcher, this.styleManager, this.editableManager, this.communicationManager);
69
- }
70
- /**
71
- * Initialize the design mode interactions
72
- */
73
- initialize() {
74
- if (!this.enabled) {
75
- console.log("Design Mode Interactions disabled");
76
- return;
77
- }
78
- console.log("Initializing Design Mode Interactions...");
79
- this.styleManager.addHighlightStyles();
80
- document.addEventListener("mouseover", this.eventHandlers.handleMouseOver);
81
- document.addEventListener("mouseleave", this.eventHandlers.handleMouseLeave);
82
- // Use capture phase so we run before links/buttons/dropdowns and can preventDefault/stopPropagation
83
- document.addEventListener("click", this.eventHandlers.handleClick, true);
84
- console.log("Design Mode Interactions initialized!");
85
- this.communicationManager.notifyInitializationComplete();
86
- }
87
- /**
88
- * Enable the design mode interactions
89
- */
90
- enable() {
91
- this.isActive = true;
92
- console.log("Design Mode Interactions enabled");
93
- }
94
- /**
95
- * Disable the design mode interactions
96
- */
97
- disable() {
98
- this.isActive = false;
99
- this.eventHandlers.clearAll();
100
- console.log("Design Mode Interactions disabled");
101
- }
102
- resolveTargets(sourceLocation) {
103
- let location = sourceLocation ?? null;
104
- if (!location?.fileName) {
105
- const selectedElement = this.eventHandlers.getSelectedElement();
106
- location = getSourceFromDataAttributes(selectedElement);
107
- }
108
- return location ? findElementsBySourceLocation(location) : [];
109
- }
110
- /**
111
- * Apply a style change to all elements at the given source location.
112
- * When sourceLocation is provided (undo/redo), it is used directly.
113
- * Otherwise the source location is read from the currently selected element.
114
- */
115
- applyStyleChange(property, value, sourceLocation) {
116
- for (const el of this.resolveTargets(sourceLocation)) {
117
- el.style[property] = value;
118
- }
119
- }
120
- applyTextChange(text, sourceLocation) {
121
- for (const el of this.resolveTargets(sourceLocation)) {
122
- el.textContent = text;
123
- }
124
- }
125
- /**
126
- * Cleanup and remove event listeners
127
- */
128
- destroy() {
129
- document.removeEventListener("mouseover", this.eventHandlers.handleMouseOver);
130
- document.removeEventListener("mouseleave", this.eventHandlers.handleMouseLeave);
131
- document.removeEventListener("click", this.eventHandlers.handleClick, true);
132
- this.styleManager.removeHighlightStyles();
133
- this.eventHandlers.clearAll();
134
- }
135
- }
@@ -1,97 +0,0 @@
1
- /**
2
- * Copyright (c) 2026, Salesforce, Inc.,
3
- * All rights reserved.
4
- * For full license text, see the LICENSE.txt file
5
- */
6
- /**
7
- * Style Manager Module
8
- * Handles CSS injection and style management for highlighting
9
- */
10
- export class StyleManager {
11
- styleId;
12
- stylesAdded;
13
- constructor() {
14
- this.styleId = "design-mode-styles";
15
- this.stylesAdded = false;
16
- }
17
- /**
18
- * Add CSS styles for highlighting to the document
19
- */
20
- addHighlightStyles() {
21
- if (this.stylesAdded) {
22
- return;
23
- }
24
- const style = document.createElement("style");
25
- style.id = this.styleId;
26
- style.textContent = this._getStyles();
27
- document.head.appendChild(style);
28
- this.stylesAdded = true;
29
- }
30
- /**
31
- * Remove highlight styles from the document
32
- */
33
- removeHighlightStyles() {
34
- const style = document.getElementById(this.styleId);
35
- if (style) {
36
- style.remove();
37
- this.stylesAdded = false;
38
- }
39
- }
40
- /**
41
- * Get the CSS styles for highlighting
42
- * @private
43
- * @returns CSS styles
44
- */
45
- _getStyles() {
46
- return `
47
- .design-mode-highlight {
48
- outline: 4px dashed #007acc !important;
49
- outline-offset: -4px !important;
50
- transition: all 0.2s ease !important;
51
- position: relative !important;
52
- cursor: pointer !important;
53
- }
54
- .design-mode-selected {
55
- outline: 5px dashed #ff6b35 !important;
56
- outline-offset: -5px !important;
57
- position: relative !important;
58
- }
59
- `;
60
- }
61
- /**
62
- * Apply highlight class to one or more elements
63
- * @param elements - The elements to highlight
64
- */
65
- highlightElements(elements) {
66
- for (const el of elements) {
67
- el.classList.add("design-mode-highlight");
68
- }
69
- }
70
- /**
71
- * Remove highlight class from one or more elements
72
- * @param elements - The elements to unhighlight
73
- */
74
- unhighlightElements(elements) {
75
- for (const el of elements) {
76
- el.classList.remove("design-mode-highlight");
77
- }
78
- }
79
- /**
80
- * Apply selected class to one or more elements
81
- * @param elements - The elements to select
82
- */
83
- selectElements(elements) {
84
- for (const el of elements) {
85
- el.classList.add("design-mode-selected");
86
- }
87
- }
88
- /**
89
- * Remove selected class from one or more elements
90
- * @param elements - The elements to deselect
91
- */
92
- deselectElements(elements) {
93
- for (const el of elements) {
94
- el.classList.remove("design-mode-selected");
95
- }
96
- }
97
- }
@@ -1,72 +0,0 @@
1
- /**
2
- * Copyright (c) 2026, Salesforce, Inc.,
3
- * All rights reserved.
4
- * For full license text, see the LICENSE.txt file
5
- */
6
- /**
7
- * Get all style values relevant to UI controls for an element.
8
- * Each property returns { inline, computed } where inline is the raw
9
- * element.style value and computed is the browser-resolved value.
10
- * @param element - The HTML element to extract styles from
11
- * @returns Plain-object snapshot safe for postMessage
12
- */
13
- export function getElementStyles(element) {
14
- if (!element)
15
- return {};
16
- const computed = window.getComputedStyle(element);
17
- const inlineStyle = element.style;
18
- /**
19
- * Get inline and computed value for single-value property.
20
- * @param name - CSS property name
21
- * @param fallback - Alternate longhand key when browsers don't
22
- * populate the shorthand (e.g. borderStyle -> borderTopStyle)
23
- */
24
- const prop = (name, fallback) => ({
25
- inline: inlineStyle[name] || (fallback ? inlineStyle[fallback] : "") || "",
26
- computed: (fallback ? computed[fallback] : computed[name]) || "",
27
- });
28
- /**
29
- * Get inline and computed value for 4-side shorthand (e.g. padding) property.
30
- * Reconstructs the shorthand from individual sides when only longhands are
31
- * set (inlineStyle.padding is '' but inlineStyle.paddingTop has a value).
32
- */
33
- const box = (shorthand, top, right, bottom, left) => {
34
- let inlineValue = inlineStyle[shorthand] || "";
35
- if (!inlineValue) {
36
- const iT = inlineStyle[top] || "", iR = inlineStyle[right] || "", iB = inlineStyle[bottom] || "", iL = inlineStyle[left] || "";
37
- if (iT || iR || iB || iL) {
38
- inlineValue = `${iT || "0px"} ${iR || "0px"} ${iB || "0px"} ${iL || "0px"}`;
39
- }
40
- }
41
- return {
42
- inline: inlineValue,
43
- computed: `${computed[top] || ""} ${computed[right] || ""} ${computed[bottom] || ""} ${computed[left] || ""}`,
44
- };
45
- };
46
- return {
47
- width: prop("width"),
48
- minWidth: prop("minWidth"),
49
- maxWidth: prop("maxWidth"),
50
- height: prop("height"),
51
- minHeight: prop("minHeight"),
52
- maxHeight: prop("maxHeight"),
53
- overflow: prop("overflow"),
54
- padding: box("padding", "paddingTop", "paddingRight", "paddingBottom", "paddingLeft"),
55
- margin: box("margin", "marginTop", "marginRight", "marginBottom", "marginLeft"),
56
- backgroundColor: prop("backgroundColor"),
57
- borderWidth: box("borderWidth", "borderTopWidth", "borderRightWidth", "borderBottomWidth", "borderLeftWidth"),
58
- borderStyle: prop("borderStyle", "borderTopStyle"),
59
- borderColor: prop("borderColor", "borderTopColor"),
60
- borderRadius: box("borderRadius", "borderTopLeftRadius", "borderTopRightRadius", "borderBottomRightRadius", "borderBottomLeftRadius"),
61
- color: prop("color"),
62
- fontFamily: prop("fontFamily"),
63
- fontSize: prop("fontSize"),
64
- fontWeight: prop("fontWeight"),
65
- fontStyle: prop("fontStyle"),
66
- lineHeight: prop("lineHeight"),
67
- letterSpacing: prop("letterSpacing"),
68
- textAlign: prop("textAlign"),
69
- textDecoration: prop("textDecoration", "textDecorationLine"),
70
- textTransform: prop("textTransform"),
71
- };
72
- }
@@ -1,99 +0,0 @@
1
- /**
2
- * Copyright (c) 2026, Salesforce, Inc.,
3
- * All rights reserved.
4
- * For full license text, see the LICENSE.txt file
5
- */
6
- /**
7
- * Source/Label Utility Functions
8
- * Helper functions for extracting source metadata injected into DOM elements.
9
- */
10
- function parseOptionalInt(value) {
11
- if (value === null || value === undefined || value === "") {
12
- return null;
13
- }
14
- const parsed = Number.parseInt(String(value), 10);
15
- return Number.isFinite(parsed) ? parsed : null;
16
- }
17
- function parseSourceFileAttribute(value) {
18
- // Current injection format: "<file>:<line>:<col>".
19
- // Use a greedy file capture so Windows paths like "C:\foo\bar.tsx:12:34" work.
20
- const match = /^(.*):(\d+):(\d+)$/.exec(value);
21
- if (!match) {
22
- return { fileName: value, lineNumber: null, columnNumber: null };
23
- }
24
- return {
25
- fileName: match[1] ?? value,
26
- lineNumber: parseOptionalInt(match[2]),
27
- columnNumber: parseOptionalInt(match[3]),
28
- };
29
- }
30
- /**
31
- * Extract source location information from data attributes.
32
- * @param element - The DOM element
33
- * @returns Source location information, or null if missing.
34
- */
35
- export function getSourceFromDataAttributes(element) {
36
- if (!element) {
37
- return null;
38
- }
39
- const source = element.getAttribute("data-source-file") || null;
40
- if (!source) {
41
- return null;
42
- }
43
- return parseSourceFileAttribute(source);
44
- }
45
- /**
46
- * Find all DOM elements whose `data-source-file` attribute matches the given source location.
47
- * @param location - The source location to match against
48
- * @returns All matching elements (may be empty)
49
- */
50
- export function findElementsBySourceLocation(location) {
51
- const results = [];
52
- const elements = document.querySelectorAll("[data-source-file]");
53
- for (const el of elements) {
54
- const elSource = getSourceFromDataAttributes(el);
55
- if (elSource &&
56
- elSource.fileName === location.fileName &&
57
- elSource.lineNumber === location.lineNumber &&
58
- elSource.columnNumber === location.columnNumber) {
59
- results.push(el);
60
- }
61
- }
62
- return results;
63
- }
64
- /**
65
- * Derive a human-readable label from the injected source file name, if present.
66
- * @param element - The DOM element
67
- * @returns A label suitable for UI display
68
- */
69
- /**
70
- * Parse an untyped message payload object into a SourceLocation.
71
- * Used by the entry point to convert raw postMessage data into typed values.
72
- * @param sl - The raw source location object from a message payload
73
- * @returns A SourceLocation, or undefined if the input is not a valid object
74
- */
75
- export function parseSourceLocation(sl) {
76
- if (!sl || typeof sl !== "object")
77
- return undefined;
78
- const obj = sl;
79
- return {
80
- fileName: String(obj.sourceFile ?? ""),
81
- lineNumber: typeof obj.lineNumber === "number" ? obj.lineNumber : null,
82
- columnNumber: typeof obj.columnNumber === "number" ? obj.columnNumber : null,
83
- };
84
- }
85
- export function getLabelFromSource(element) {
86
- if (!element) {
87
- return "";
88
- }
89
- const source = element.getAttribute("data-source-file");
90
- if (!source) {
91
- return element.tagName ? element.tagName.toLowerCase() : "";
92
- }
93
- const { fileName } = parseSourceFileAttribute(source);
94
- // Support both POSIX and Windows-style separators.
95
- const parts = fileName.split(/[/\\]/);
96
- const baseName = parts[parts.length - 1] || fileName;
97
- console.log("baseName", baseName);
98
- return baseName;
99
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * Copyright (c) 2026, Salesforce, Inc.,
3
- * All rights reserved.
4
- * For full license text, see the LICENSE.txt file
5
- */
6
- export {};
7
- //# sourceMappingURL=livePreviewScript.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"livePreviewScript.test.d.ts","sourceRoot":"","sources":["../../src/proxy/livePreviewScript.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -1,96 +0,0 @@
1
- /**
2
- * Copyright (c) 2026, Salesforce, Inc.,
3
- * All rights reserved.
4
- * For full license text, see the LICENSE.txt file
5
- */
6
- import { describe, it, expect } from "vitest";
7
- import { injectLivePreviewScript } from "./handler.js";
8
- import { getLivePreviewScriptContent, LIVE_PREVIEW_SCRIPT_MARKER } from "./livePreviewScript.js";
9
- describe("getLivePreviewScriptContent", () => {
10
- it("should return a non-empty string", () => {
11
- const content = getLivePreviewScriptContent();
12
- expect(content).toBeTruthy();
13
- expect(typeof content).toBe("string");
14
- expect(content.length).toBeGreaterThan(100);
15
- });
16
- it("should contain the fetch interceptor", () => {
17
- const content = getLivePreviewScriptContent();
18
- expect(content).toContain("setupFetchInterceptorImmediate");
19
- expect(content).toContain("_vscodeIntercepted");
20
- });
21
- it("should contain the error deduplication logic", () => {
22
- const content = getLivePreviewScriptContent();
23
- expect(content).toContain("ERROR_DEDUP_WINDOW_MS");
24
- expect(content).toContain("getErrorHash");
25
- expect(content).toContain("recentErrors");
26
- });
27
- it("should contain the sendErrorToParent function", () => {
28
- const content = getLivePreviewScriptContent();
29
- expect(content).toContain("sendErrorToParent");
30
- });
31
- it("should contain the copy/paste bridge", () => {
32
- const content = getLivePreviewScriptContent();
33
- expect(content).toContain("sendCopyMessage");
34
- expect(content).toContain('command: "copy"');
35
- });
36
- it("should contain the iframeAlive heartbeat", () => {
37
- const content = getLivePreviewScriptContent();
38
- expect(content).toContain("iframeAlive");
39
- });
40
- it("should contain error listeners (window.error, unhandledrejection, console.error)", () => {
41
- const content = getLivePreviewScriptContent();
42
- expect(content).toContain('window.addEventListener(\n\t\t\t"error"');
43
- expect(content).toContain('window.addEventListener("unhandledrejection"');
44
- expect(content).toContain("console.error = function");
45
- });
46
- it("should wrap error details in a metadata object for postMessage", () => {
47
- const content = getLivePreviewScriptContent();
48
- expect(content).toContain("metadata:");
49
- expect(content).toContain("metadata: {");
50
- });
51
- });
52
- describe("LIVE_PREVIEW_SCRIPT_MARKER", () => {
53
- it("should be a non-empty string", () => {
54
- expect(LIVE_PREVIEW_SCRIPT_MARKER).toBeTruthy();
55
- expect(typeof LIVE_PREVIEW_SCRIPT_MARKER).toBe("string");
56
- });
57
- });
58
- describe("injectLivePreviewScript", () => {
59
- it("should inject script before </body>", () => {
60
- const html = "<html><body><div>Hello</div></body></html>";
61
- const result = injectLivePreviewScript(html);
62
- expect(result).toContain(LIVE_PREVIEW_SCRIPT_MARKER);
63
- expect(result.indexOf(LIVE_PREVIEW_SCRIPT_MARKER)).toBeLessThan(result.indexOf("</body>"));
64
- });
65
- it("should inject before </html> when no </body> is present", () => {
66
- const html = "<html><div>Hello</div></html>";
67
- const result = injectLivePreviewScript(html);
68
- expect(result).toContain(LIVE_PREVIEW_SCRIPT_MARKER);
69
- expect(result.indexOf(LIVE_PREVIEW_SCRIPT_MARKER)).toBeLessThan(result.indexOf("</html>"));
70
- });
71
- it("should append at the end when no </body> or </html>", () => {
72
- const html = "<div>Hello</div>";
73
- const result = injectLivePreviewScript(html);
74
- expect(result).toContain(LIVE_PREVIEW_SCRIPT_MARKER);
75
- expect(result).toContain("<div>Hello</div>");
76
- expect(result.endsWith("</script>")).toBe(true);
77
- });
78
- it("should prevent double injection", () => {
79
- const html = "<html><body><div>Hello</div></body></html>";
80
- const first = injectLivePreviewScript(html);
81
- const second = injectLivePreviewScript(first);
82
- expect(first).toBe(second);
83
- });
84
- it("should wrap script in <script> tags", () => {
85
- const html = "<html><body></body></html>";
86
- const result = injectLivePreviewScript(html);
87
- expect(result).toContain("<script>");
88
- expect(result).toContain("</script>");
89
- });
90
- it("should contain actual script content in the output", () => {
91
- const html = "<html><body></body></html>";
92
- const result = injectLivePreviewScript(html);
93
- expect(result).toContain("sendErrorToParent");
94
- expect(result).toContain("setupFetchInterceptorImmediate");
95
- });
96
- });