@salesforce-ui-embedding/internal-lightning-ui-embedding 2.2.7-rc.2

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.
@@ -0,0 +1,375 @@
1
+ function _defineProperty(e, r, t) {return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e;}function _toPropertyKey(t) {var i = _toPrimitive(t, "string");return "symbol" == typeof i ? i : i + "";}function _toPrimitive(t, r) {if ("object" != typeof t || !t) return t;var e = t[Symbol.toPrimitive];if (void 0 !== e) {var i = e.call(t, r || "default");if ("object" != typeof i) return i;throw new TypeError("@@toPrimitive must return a primitive value.");}return ("string" === r ? String : Number)(t);}function o(e) {
2
+ return typeof e == "object" && e !== null && !Array.isArray(e);
3
+ }
4
+ function c(e) {
5
+ return typeof e.id == "number" && Number.isInteger(e.id) && e.id >= 0;
6
+ }
7
+ function i(e) {
8
+ return o(e) && e.jsonrpc === "2.0";
9
+ }
10
+ function m(e) {
11
+ if (!i(e)) return false;
12
+ const t = e;
13
+ return c(t) && typeof t.method == "string";
14
+ }
15
+ function d(e) {
16
+ if (!i(e)) return false;
17
+ const t = e;
18
+ return !("id" in t) && typeof t.method == "string";
19
+ }
20
+ function p(e) {
21
+ if (!i(e)) return false;
22
+ const t = e;
23
+ return c(t) && "result" in t && !("error" in t) && !("method" in t);
24
+ }
25
+ function u(e) {
26
+ if (!i(e)) return false;
27
+ const t = e;
28
+ if (!c(t) || "result" in t || "method" in t) return false;
29
+ const s = t.error;
30
+ return o(s) && typeof s.code == "number";
31
+ }
32
+ function g(e) {
33
+ return p(e) || u(e);
34
+ }
35
+ class b {
36
+
37
+
38
+
39
+
40
+ /**
41
+ * Construct a JSON-RPC client bound to the given transport.
42
+ *
43
+ * @param transport - the transport to use.
44
+ */
45
+ constructor(_t) {_defineProperty(this, "nextRequestId", 1);_defineProperty(this, "pending", /* @__PURE__ */new Map());_defineProperty(this, "notificationHandlers", /* @__PURE__ */new Map());_defineProperty(this, "transport", void 0);
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+ /**
68
+ * Handle inbound JSON-RPC messages from the transport.
69
+ *
70
+ * Processes both responses (for requests) and notifications.
71
+ * Non-JSON-RPC payloads are silently ignored so that a shared transport
72
+ * can be used for multiple protocols without cross-talk.
73
+ */_defineProperty(this, "onMessage",
74
+ (t) => {
75
+ if (g(t)) {
76
+ const s = this.pending.get(t.id);
77
+ if (!s)
78
+ return;
79
+ this.pending.delete(t.id), this.onInboundMeta(t, t._meta), u(t) ? s.reject(new Error(t.error.message || "Request failed")) : s.resolve(t.result);
80
+ return;
81
+ }
82
+ if (d(t)) {
83
+ this.onInboundMeta(t, t._meta);
84
+ const s = this.notificationHandlers.get(t.method);
85
+ if (s) {
86
+ const n = t._meta;
87
+ s.forEach((r) => {
88
+ r(t.params, n);
89
+ });
90
+ }
91
+ }
92
+ });this.transport = _t, this.transport.onMessage(this.onMessage);} /**
93
+ * Register a handler for a specific JSON-RPC notification method.
94
+ *
95
+ * Subclasses can register handlers to process specific notification
96
+ * types. When a notification with the registered method is received,
97
+ * the handler will be invoked with the notification params.
98
+ *
99
+ * @param method - The notification method to handle (e.g.
100
+ * "ui/notifications/host-context-changed")
101
+ * @param handler - Callback function to process the notification params
102
+ *
103
+ * @example
104
+ * this.registerNotificationHandler("ui/notifications/host-context-changed", (params) => {
105
+ * this.handleHostContextChanged(params);
106
+ * });
107
+ */registerNotificationHandler(t, s) {this.notificationHandlers.has(t) || this.notificationHandlers.set(t, /* @__PURE__ */new Set()), this.notificationHandlers.get(t).add(s);} /**
108
+ * Send a JSON-RPC request to the peer.
109
+ *
110
+ * @param method - The JSON-RPC method name
111
+ * @param params - The method parameters
112
+ * @returns Promise that resolves with the result or rejects with error
113
+ *
114
+ * @example
115
+ * const result = await this.request("ui/message", {
116
+ * role: "user",
117
+ * content: { type: "text", text: "Hello" }
118
+ * });
119
+ */request(t, s) {const n = this.nextRequestId++,r = { jsonrpc: "2.0", id: n, method: t, params: s };return this.applyOutboundMeta(r, t), new Promise((f, h) => {this.pending.set(n, { resolve: f, reject: h }), this.transport.post(r);});}
120
+ /**
121
+ * Send a JSON-RPC notification to the peer.
122
+ *
123
+ * Notifications are one-way messages that do not expect a response.
124
+ * Use notifications for:
125
+ * - Informing the host of state changes
126
+ * - Fire-and-forget operations
127
+ * - Events that don't require confirmation
128
+ *
129
+ * Use request() instead when you need:
130
+ * - A response from the host
131
+ * - Confirmation of success/failure
132
+ * - Return values from the operation
133
+ *
134
+ * @param method - The JSON-RPC method name
135
+ * @param params - Optional method parameters
136
+ *
137
+ * @example
138
+ * this.sendNotification("ui/notifications/size-changed", {
139
+ * width: 800,
140
+ * height: 600
141
+ * });
142
+ */
143
+ sendNotification(t, s) {
144
+ const n = {
145
+ jsonrpc: "2.0",
146
+ method: t,
147
+ params: s
148
+ };
149
+ this.applyOutboundMeta(n, t), this.transport.post(n);
150
+ }
151
+ /**
152
+ * Outbound `_meta` hook. Override to attach protocol-meta (e.g. a
153
+ * per-message `traceId`) to every outgoing request and notification.
154
+ *
155
+ * Default returns `undefined` so the envelope ships without `_meta`,
156
+ * matching JSON-RPC 2.0 baseline behavior.
157
+ */
158
+ getOutboundMeta(t) {
159
+ }
160
+ /**
161
+ * Inbound `_meta` hook. Invoked once per validated inbound frame
162
+ * (response or notification) before the value is dispatched to the
163
+ * pending-request resolver or notification handlers.
164
+ *
165
+ * Default is a no-op. Override to feed log correlation, tracing, etc.
166
+ */
167
+ onInboundMeta(t, s) {
168
+ }
169
+ applyOutboundMeta(t, s) {
170
+ const n = this.getOutboundMeta(s);
171
+ n !== void 0 && (t._meta = n);
172
+ }
173
+ }
174
+ const a = {
175
+ METHOD_NOT_FOUND: -32601,
176
+ INTERNAL_ERROR: -32603,
177
+ /** `default` / `long` timeout-class request expired. */
178
+ REQUEST_TIMEOUT: -32018,
179
+ /** In-flight cap reached. */
180
+ BACKPRESSURE: -32019 },l = /* @__PURE__ */new Set([
181
+ a.REQUEST_TIMEOUT,
182
+ a.BACKPRESSURE]
183
+ );
184
+ function E(e) {
185
+ return !!l.has(e);
186
+ }
187
+ function I(e, t = {}) {
188
+ const n = { retryable: t.retryable ?? E(e) };
189
+ t.details !== void 0 && (n.details = t.details);
190
+ const r = { code: e };
191
+ return t.message !== void 0 && (r.message = t.message), r.data = n, r;
192
+ }
193
+
194
+ /**
195
+ * JSON-RPC plumbing shared by both peers of the sf-embedding protocol.
196
+ *
197
+ * Two layers live here:
198
+ *
199
+ * - `BridgeClient` — the OUTBOUND half plus inbound responses/notifications.
200
+ * Extends the library `JsonRpcClient`, so it already correlates outbound
201
+ * `send()` requests with their inbound responses, dispatches inbound
202
+ * notifications to `onNotification` handlers, and stamps every outbound
203
+ * frame with a `_meta.traceId`. It owns the single `Transport`.
204
+ *
205
+ * - `JsonRpcRouter` — the INBOUND-REQUEST half. It HOLDS a `BridgeClient`
206
+ * and adds the one thing the client deliberately lacks: routing inbound
207
+ * JSON-RPC *requests* to registered handlers and replying success/error
208
+ * on the same transport (echoing `_meta` for tracing). Notifications,
209
+ * responses, and outbound traffic are delegated straight to the client —
210
+ * no duplicate handler tables.
211
+ *
212
+ * Request vs response/notification dispatch does not collide on the shared
213
+ * transport: `JsonRpcClient` ignores frames carrying both an `id` and a
214
+ * `method` (requests), so the router is free to claim them.
215
+ *
216
+ * Each peer subclasses `JsonRpcRouter` (see `HostBridge` /
217
+ * `EmbeddingBridge`): the subclass registers its inbound handlers in the
218
+ * constructor and exposes named methods for its outbound requests.
219
+ */
220
+ // makeJsonRpcError is the upstream factory; sf-embedding's NON_RETRYABLE_CODES wrapper
221
+ // (in sf-embedding-bridge/src/errors.ts) is bypassed here because `utils` cannot depend
222
+ // on the bridge package. A ratchet test in sf-embedding-contract guards the invariant
223
+ // that NON_RETRYABLE_CODES never overlaps the upstream RETRYABLE set.
224
+ function isRequestHandlerError(err) {
225
+ return err instanceof Error && typeof err.code === "number";
226
+ }
227
+ /**
228
+ * Outbound + response/notification half of a JSON-RPC peer, bound to one
229
+ * transport. Promotes the library client's `protected` send/notify/register
230
+ * methods to a `public` surface the router (and its subclasses) can call, and
231
+ * exposes `post`/`subscribe` so the router can reply to and listen for inbound
232
+ * requests over the same transport.
233
+ *
234
+ * Stamps `_meta.traceId` on every outbound frame; both peers want tracing.
235
+ */
236
+ class BridgeClient extends b {
237
+
238
+ constructor(transport) {
239
+ super(transport);_defineProperty(this, "sharedTransport", void 0);
240
+ this.sharedTransport = transport;
241
+ }
242
+ /** Send a request and await its correlated response. */
243
+ send(method, params) {
244
+ return this.request(method, params);
245
+ }
246
+ /** Send a fire-and-forget notification. */
247
+ notify(method, params) {
248
+ this.sendNotification(method, params);
249
+ }
250
+ /** Register an inbound-notification handler. */
251
+ onNotification(method, handler) {
252
+ this.registerNotificationHandler(method, handler);
253
+ }
254
+ /** @internal — used by JsonRpcRouter to reply to inbound requests. */
255
+ post(frame) {
256
+ this.sharedTransport.post(frame);
257
+ }
258
+ /** @internal — used by JsonRpcRouter to claim inbound requests. */
259
+ subscribe(callback) {
260
+ return this.sharedTransport.onMessage(callback);
261
+ }
262
+ /** Tear down the underlying transport if it is disposable (e.g. MessageChannelTransport closes its port). */
263
+ dispose() {
264
+ const transport = this.sharedTransport;
265
+ if (typeof transport.dispose === "function") {
266
+ transport.dispose();
267
+ }
268
+ }
269
+ /** Mints `_meta.traceId` for every outbound request and notification. */
270
+ getOutboundMeta(_method) {
271
+ return { traceId: crypto.randomUUID() };
272
+ }
273
+ }
274
+ /**
275
+ * Inbound-request router. Holds a `BridgeClient` for everything else
276
+ * (outbound requests/notifications, inbound responses, inbound notifications)
277
+ * and adds inbound-request routing + replies on the shared transport.
278
+ *
279
+ * Subclass it per peer: register handlers in the constructor, add named
280
+ * outbound methods that call `send`/`notify`.
281
+ */
282
+ class JsonRpcRouter {
283
+
284
+
285
+
286
+
287
+ constructor(client, log = () => {}) {_defineProperty(this, "client", void 0);_defineProperty(this, "requestHandlers", new Map());_defineProperty(this, "log", void 0);_defineProperty(this, "unsubscribe", null);
288
+ this.client = client;
289
+ this.log = log;
290
+ // Claim inbound *requests*; the client already handles responses and
291
+ // notifications on the same transport and ignores request frames.
292
+ this.unsubscribe = this.client.subscribe((data) => this.handle(data));
293
+ }
294
+ /** Register a handler for an inbound request method. Returns a disposer; re-registering overwrites. */
295
+ onRequest(method, handler) {
296
+ this.requestHandlers.set(method, handler);
297
+ return () => {
298
+ if (this.requestHandlers.get(method) === handler) {
299
+ this.requestHandlers.delete(method);
300
+ }
301
+ };
302
+ }
303
+ /** Register an inbound-notification handler (delegates to the client). */
304
+ onNotification(method, handler) {
305
+ this.client.onNotification(method, handler);
306
+ }
307
+ /** Send an outbound request and await its response (delegates to the client). */
308
+ send(method, params) {
309
+ return this.client.send(method, params);
310
+ }
311
+ /** Send an outbound notification (delegates to the client). */
312
+ notify(method, params) {
313
+ this.client.notify(method, params);
314
+ }
315
+ /**
316
+ * Tear down: drop the inbound-request subscription, clear handlers, and
317
+ * dispose the client's transport (closes the port). Idempotent.
318
+ */
319
+ dispose() {
320
+ if (this.unsubscribe) {
321
+ this.unsubscribe();
322
+ this.unsubscribe = null;
323
+ }
324
+ this.requestHandlers.clear();
325
+ this.client.dispose();
326
+ }
327
+ /** Route one inbound frame. Only requests are handled here; the rest is the client's. */
328
+ handle(data) {
329
+ if (!m(data))
330
+ return;
331
+ this.handleRequest(data);
332
+ }
333
+ handleRequest(req) {
334
+ const handler = this.requestHandlers.get(req.method);
335
+ if (!handler) {
336
+ this.respondError(req.id, a.METHOD_NOT_FOUND, `Method not found: ${req.method}`, req._meta);
337
+ return;
338
+ }
339
+ Promise.resolve().
340
+ then(() => handler(req.params, req._meta)).
341
+ then((result) => this.respondSuccess(req.id, result, req._meta), (err) => {
342
+ const code = isRequestHandlerError(err) ? err.code : a.INTERNAL_ERROR;
343
+ const message = err instanceof Error ? err.message : String(err);
344
+ this.respondError(req.id, code, message, req._meta);
345
+ });
346
+ }
347
+ respondSuccess(id, result, meta) {
348
+ const frame = { jsonrpc: "2.0", id, result };
349
+ if (meta)
350
+ frame._meta = meta;
351
+ this.postSafely(frame);
352
+ }
353
+ respondError(id, code, message, meta) {
354
+ const frame = {
355
+ jsonrpc: "2.0",
356
+ id,
357
+ error: I(code, { message })
358
+ };
359
+ if (meta)
360
+ frame._meta = meta;
361
+ this.postSafely(frame);
362
+ }
363
+ postSafely(frame) {
364
+ try {
365
+ this.client.post(frame);
366
+ }
367
+ catch (err) {
368
+ // Transport.post should not throw on transient failure, but guard so a
369
+ // misbehaving transport can't take down request handling.
370
+ this.log("response post threw —", err);
371
+ }
372
+ }
373
+ }
374
+
375
+ export { BridgeClient, JsonRpcRouter };
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Copyright 2026 Salesforce, Inc. All rights reserved.
3
+ * For full license text, see the LICENSE.txt file in this package.
4
+ */
5
+
6
+ import { DEFAULT_SANDBOX_TOKENS } from "./constants";
7
+
8
+ export function computeSandboxTokens(addList, removeList) {
9
+ const tokens = new Set(DEFAULT_SANDBOX_TOKENS);
10
+
11
+ if (addList) {
12
+ for (const t of addList.split(/\s+/).filter(Boolean)) tokens.add(t);
13
+ }
14
+ if (removeList) {
15
+ for (const t of removeList.split(/\s+/).filter(Boolean)) {
16
+ if (tokens.has(t)) {
17
+ tokens.delete(t);
18
+ } else {
19
+ window.console.warn(
20
+ `[lightning-ui-embedding] removeSandboxTokens: '${t}' was not in the resolved sandbox; ignored.`,
21
+ );
22
+ }
23
+ }
24
+ }
25
+
26
+ return Array.from(tokens).join(" ");
27
+ }
@@ -0,0 +1,66 @@
1
+ function _defineProperty(e, r, t) {return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e;}function _toPropertyKey(t) {var i = _toPrimitive(t, "string");return "symbol" == typeof i ? i : i + "";}function _toPrimitive(t, r) {if ("object" != typeof t || !t) return t;var e = t[Symbol.toPrimitive];if (void 0 !== e) {var i = e.call(t, r || "default");if ("object" != typeof i) return i;throw new TypeError("@@toPrimitive must return a primitive value.");}return ("string" === r ? String : Number)(t);} // Bootstrap envelope vocabulary. Spec: EMBEDDING-PROTOCOL.md §3.1, §3.1.1,
2
+ // MC-7/MC-8/MC-10 in §2.2.
3
+ /** Wire identifier for this protocol. Carried verbatim on every bootstrap envelope. */
4
+ const PROTOCOL_NAME = "sf-embedding";
5
+ /** Discriminator for the host → embedding bootstrap envelope. */
6
+ const BOOTSTRAP_ENVELOPE_TYPE = "sf-embedding.bootstrap";
7
+ /** Discriminator for the embedding → host content-free heartbeat. */
8
+ const HEARTBEAT_TYPE = "sf-embedding/ready";
9
+ /**
10
+ * Discriminator for the embedding → host fail-closed shutdown signal
11
+ * (e.g., duplicate-transfer detection). Posted via window-level postMessage,
12
+ * not over the JSON-RPC port.
13
+ */
14
+ const SHUTDOWN_TYPE = "sf-embedding/shutdown";
15
+
16
+ // Bidirectional custom-event channel.
17
+ const EVENTS_DISPATCH_METHOD = "ui/events/dispatch";
18
+ const EVENTS_SUBSCRIBE_METHOD = "ui/events/subscribe";
19
+ const EVENTS_UNSUBSCRIBE_METHOD = "ui/events/unsubscribe";
20
+
21
+ // Host LWC reserved DOM event names and detail shapes. Spec §12.3.
22
+ //
23
+ // These are dispatched by the host LWC on its own element so application
24
+ // code on the page can react. The embedding never observes them.
25
+ /** Event names the host LWC dispatches on its own element. Reserved by the protocol. */
26
+ const HostLwcEvent = {
27
+ /** Synchronous with `ui/discover-capabilities` response; session reaches READY. */
28
+ READY: "sf-embedding.component.ready",
29
+ /** Misconfiguration, bootstrap failure, embedding-reported fatal, or protocol violation. */
30
+ ERROR: "sf-embedding.component.error"
31
+ };
32
+
33
+ // Host-supplied iframe URL metadata (per ADR 0029). Spec §3.1, MC-8/MC-10.
34
+ /** URL query-parameter name carrying the JSON-encoded `HostMetaData`. */
35
+ const HOST_META_DATA_PARAM = "hostMetaData";
36
+
37
+ // Shared error class for inbound-request handlers on either side of the wire.
38
+ // Routers translate it into a JSON-RPC error response with the carried `code`;
39
+ // any other thrown value falls back to INTERNAL_ERROR (-32603).
40
+ /** Throw from a request handler to surface a specific JSON-RPC error code. */
41
+ class JsonRpcHandlerError extends Error {
42
+
43
+ constructor(code, message) {
44
+ super(message);_defineProperty(this, "code", void 0);
45
+ this.code = code;
46
+ this.name = "JsonRpcHandlerError";
47
+ }
48
+ }
49
+
50
+ // JSON-RPC method names on the wire today.
51
+ /** Host announces session identity to the embedding over the port. */
52
+ const HOST_INITIALIZED_METHOD = "ui/notifications/host-initialized";
53
+ /** Embedding acknowledges receipt of `host-initialized`. Fire-and-forget. */
54
+ const EMBEDDING_INITIALIZED_METHOD = "ui/notifications/embedding-initialized";
55
+ /** Iframe-side error notification. Fire-and-forget, non-PII observability signal. */
56
+ const ERROR_METHOD = "ui/notifications/error";
57
+
58
+ // Resize hint channel: embedding → host, fire-and-forget. CSS pixels.
59
+ const RESIZE_METHOD = "ui/notifications/resize";
60
+
61
+ // UI-state subscription axis. Snapshot in subscribe response; full-replacement change pushes.
62
+ const UI_STATE_SUBSCRIBE_METHOD = "ui/subscribe/ui-state";
63
+ const UI_STATE_UNSUBSCRIBE_METHOD = "ui/unsubscribe/ui-state";
64
+ const UI_STATE_CHANGED_METHOD = "ui/notifications/ui-state-changed";
65
+
66
+ export { BOOTSTRAP_ENVELOPE_TYPE, EMBEDDING_INITIALIZED_METHOD, ERROR_METHOD, EVENTS_DISPATCH_METHOD, EVENTS_SUBSCRIBE_METHOD, EVENTS_UNSUBSCRIBE_METHOD, HEARTBEAT_TYPE, HOST_INITIALIZED_METHOD, HOST_META_DATA_PARAM, HostLwcEvent, JsonRpcHandlerError, PROTOCOL_NAME, RESIZE_METHOD, SHUTDOWN_TYPE, UI_STATE_CHANGED_METHOD, UI_STATE_SUBSCRIBE_METHOD, UI_STATE_UNSUBSCRIBE_METHOD };
@@ -0,0 +1,76 @@
1
+ /*
2
+ * Copyright 2026 Salesforce, Inc. All rights reserved.
3
+ * For full license text, see the LICENSE.txt file in this package.
4
+ */
5
+
6
+ // UiState snapshot composition. Reads from @api props, data-*, mirrored attrs, inline style (--*).
7
+
8
+ /** Mirrored attributes read off the host LWC element. */
9
+ export const MIRRORED_ATTRIBUTES = [
10
+ "autocapitalize",
11
+ "autocorrect",
12
+ "dir",
13
+ "enterkeyhint",
14
+ "inputmode",
15
+ "lang",
16
+ "spellcheck",
17
+ "title",
18
+ "translate",
19
+ ];
20
+
21
+ /** Convert kebab-case to camelCase: `record-id` → `recordId`. */
22
+ function kebabToCamel(name) {
23
+ return name.replace(/-([a-z])/g, (_match, letter) => letter.toUpperCase());
24
+ }
25
+
26
+ /** Read `data-*` attributes; strip prefix; convert kebab to camel. Tolerates non-Element host. */
27
+ export function readDataAttributes(element) {
28
+ const out = {};
29
+ if (!element || !element.attributes) return out;
30
+ for (const attr of element.attributes) {
31
+ if (attr.name.startsWith("data-")) {
32
+ const key = kebabToCamel(attr.name.slice("data-".length));
33
+ out[key] = attr.value;
34
+ }
35
+ }
36
+ return out;
37
+ }
38
+
39
+ /** Read CSS custom-property values off the element's inline style. */
40
+ export function readCssVariables(element) {
41
+ const out = {};
42
+ if (!element || !element.style) return out;
43
+ const style = element.style;
44
+ for (let i = 0; i < style.length; i++) {
45
+ const name = style.item(i);
46
+ if (name.startsWith("--")) {
47
+ out[name] = style.getPropertyValue(name).trim();
48
+ }
49
+ }
50
+ return out;
51
+ }
52
+
53
+ /** Read the mirrored attribute set off the element. Skips absent attributes. */
54
+ export function readMirroredAttributes(element) {
55
+ const out = {};
56
+ if (!element || typeof element.getAttribute !== "function") return out;
57
+ for (const name of MIRRORED_ATTRIBUTES) {
58
+ const value = element.getAttribute(name);
59
+ if (value !== null) out[name] = value;
60
+ }
61
+ return out;
62
+ }
63
+
64
+ /** `@api props` wins over `data-*` on collision (typed beats string). */
65
+ export function composeUiState(input) {
66
+ const dataProps = readDataAttributes(input.hostElement);
67
+ const attributes = readMirroredAttributes(input.hostElement);
68
+ const variables = readCssVariables(input.hostElement);
69
+ const props = { ...dataProps, ...input.apiProps };
70
+
71
+ const styles = {};
72
+ if (Object.keys(variables).length > 0) styles.variables = variables;
73
+ if (Object.keys(attributes).length > 0) styles.attributes = attributes;
74
+
75
+ return { props, styles };
76
+ }
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright 2026 Salesforce, Inc. All rights reserved.
3
+ * For full license text, see the LICENSE.txt file in this package.
4
+ */
5
+
6
+ import { HOST_META_DATA_PARAM } from "./sf-embedding-contract";
7
+
8
+ export function parseOrigin(src) {
9
+ try {
10
+ return new URL(src).origin;
11
+ } catch {
12
+ return null;
13
+ }
14
+ }
15
+
16
+ export function appendHostMetaData(src, instanceId, hostAppOrigin) {
17
+ const url = new URL(src);
18
+ const meta = { instanceId, hostAppOrigin };
19
+ url.searchParams.set(HOST_META_DATA_PARAM, JSON.stringify(meta));
20
+ return url.href;
21
+ }
File without changes
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@salesforce-ui-embedding/internal-lightning-ui-embedding",
3
+ "version": "2.2.7-rc.2",
4
+ "private": false,
5
+ "description": "Lightning Base Component (LWC) host for sf-embedding-protocol iframes",
6
+ "license": "SEE LICENSE IN LICENSE.txt",
7
+ "author": "Salesforce ECS Team",
8
+ "type": "module",
9
+ "files": [
10
+ "dist/",
11
+ "!dist/__tests__/",
12
+ "!dist/__mocks__/",
13
+ "!dist/*.test.js",
14
+ "!dist/*.map",
15
+ "LICENSE.txt"
16
+ ],
17
+ "scripts": {
18
+ "build": "node scripts/build.mjs",
19
+ "typecheck": "tsc --noEmit",
20
+ "test": "jest --passWithNoTests",
21
+ "clean": "rimraf dist"
22
+ },
23
+ "devDependencies": {
24
+ "@salesforce/jsonrpc": "^10.12.3",
25
+ "@salesforce/sf-embedding-contract": "2.2.7-rc.2",
26
+ "utils": "2.2.7-rc.2"
27
+ },
28
+ "sideEffects": false,
29
+ "publishConfig": {
30
+ "access": "public"
31
+ }
32
+ }