@corti/embedded-web 0.1.1 → 0.3.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.
- package/README.md +92 -50
- package/dist/CortiEmbedded.d.ts +34 -7
- package/dist/CortiEmbedded.js +274 -106
- package/dist/CortiEmbedded.js.map +1 -1
- package/dist/bundle.js +1699 -20
- package/dist/corti-embedded.d.ts +17 -1
- package/dist/corti-embedded.js +4 -3
- package/dist/corti-embedded.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/public-types.d.ts +185 -0
- package/dist/public-types.js +2 -0
- package/dist/public-types.js.map +1 -0
- package/dist/react/CortiEmbeddedReact.d.ts +32 -23
- package/dist/react/CortiEmbeddedReact.js +69 -21
- package/dist/react/CortiEmbeddedReact.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/styles/base.js +1 -1
- package/dist/styles/base.js.map +1 -1
- package/dist/styles/container-styles.js +2 -2
- package/dist/styles/container-styles.js.map +1 -1
- package/dist/styles/theme.js +2 -2
- package/dist/styles/theme.js.map +1 -1
- package/dist/types/api.d.ts +36 -22
- package/dist/types/api.js.map +1 -1
- package/dist/types/config.d.ts +16 -2
- package/dist/types/config.js.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/payloads.d.ts +36 -4
- package/dist/types/payloads.js.map +1 -1
- package/dist/types/protocol.d.ts +9 -4
- package/dist/types/protocol.js.map +1 -1
- package/dist/types/responses.d.ts +10 -2
- package/dist/types/responses.js.map +1 -1
- package/dist/utils/PostMessageHandler.d.ts +19 -70
- package/dist/utils/PostMessageHandler.js +98 -201
- package/dist/utils/PostMessageHandler.js.map +1 -1
- package/dist/utils/baseUrl.js +8 -8
- package/dist/utils/baseUrl.js.map +1 -1
- package/dist/utils/embedUrl.js +3 -3
- package/dist/utils/embedUrl.js.map +1 -1
- package/dist/utils/errorFormatter.js +44 -20
- package/dist/utils/errorFormatter.js.map +1 -1
- package/dist/web-bundle.js +1555 -13
- package/dist/web-index.d.ts +3 -3
- package/dist/web-index.js +4 -4
- package/dist/web-index.js.map +1 -1
- package/package.json +20 -20
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/CortiEmbedded.js
CHANGED
|
@@ -4,27 +4,70 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { html, LitElement } from
|
|
8
|
-
import { property } from
|
|
9
|
-
import { baseStyles } from
|
|
10
|
-
import { containerStyles } from
|
|
11
|
-
import { validateAndNormalizeBaseURL } from
|
|
12
|
-
import { buildEmbeddedUrl, isRealEmbeddedLoad } from
|
|
13
|
-
import { formatError } from
|
|
14
|
-
import { PostMessageHandler, } from
|
|
7
|
+
import { html, LitElement } from "lit";
|
|
8
|
+
import { property } from "lit/decorators.js";
|
|
9
|
+
import { baseStyles } from "./styles/base.js";
|
|
10
|
+
import { containerStyles } from "./styles/container-styles.js";
|
|
11
|
+
import { validateAndNormalizeBaseURL } from "./utils/baseUrl.js";
|
|
12
|
+
import { buildEmbeddedUrl, isRealEmbeddedLoad } from "./utils/embedUrl.js";
|
|
13
|
+
import { formatError } from "./utils/errorFormatter.js";
|
|
14
|
+
import { PostMessageHandler, } from "./utils/PostMessageHandler.js";
|
|
15
|
+
const IFRAME_SANDBOX_POLICY = "allow-forms allow-modals allow-scripts allow-same-origin";
|
|
16
|
+
const DEPRECATION_TIMELINE_URL = "https://docs.corti.ai/assistant/deprecation-timeline";
|
|
17
|
+
const CONFIGURATION_MIGRATION_URL = "https://docs.corti.ai/assistant/configuration-migration";
|
|
18
|
+
const DEPRECATED_EVENT_SUBSCRIPTIONS = new Set([
|
|
19
|
+
"ready",
|
|
20
|
+
"loaded",
|
|
21
|
+
"recordingStarted",
|
|
22
|
+
"recordingStopped",
|
|
23
|
+
"documentGenerated",
|
|
24
|
+
"documentUpdated",
|
|
25
|
+
"documentSynced",
|
|
26
|
+
"authChanged",
|
|
27
|
+
"interactionCreated",
|
|
28
|
+
"navigationChanged",
|
|
29
|
+
"usage",
|
|
30
|
+
"embedded-event",
|
|
31
|
+
]);
|
|
15
32
|
export class CortiEmbedded extends LitElement {
|
|
16
33
|
constructor() {
|
|
17
34
|
super(...arguments);
|
|
18
|
-
this.visibility =
|
|
35
|
+
this.visibility = "hidden";
|
|
19
36
|
this.postMessageHandler = null;
|
|
20
37
|
this.normalizedBaseURL = null;
|
|
38
|
+
this.warnedDeprecatedEventSubscriptions = new Set();
|
|
39
|
+
}
|
|
40
|
+
addEventListener(type, callback, options) {
|
|
41
|
+
this.warnDeprecatedEventSubscription(type);
|
|
42
|
+
super.addEventListener(type, callback, options);
|
|
43
|
+
}
|
|
44
|
+
warnDeprecatedEventSubscription(eventName) {
|
|
45
|
+
if (!DEPRECATED_EVENT_SUBSCRIPTIONS.has(eventName) ||
|
|
46
|
+
this.warnedDeprecatedEventSubscriptions.has(eventName)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
this.warnedDeprecatedEventSubscriptions.add(eventName);
|
|
50
|
+
console.warn(`[Corti Embedded] The '${eventName}' event subscription is deprecated and will be removed in a future release. Subscribe to the canonical 'event' stream instead. See ${DEPRECATION_TIMELINE_URL}.`);
|
|
51
|
+
}
|
|
52
|
+
// eslint-disable-next-line class-methods-use-this
|
|
53
|
+
getIframeAllowPolicy(normalizedBaseURL) {
|
|
54
|
+
const permissionTarget = normalizedBaseURL
|
|
55
|
+
? new URL(normalizedBaseURL).origin
|
|
56
|
+
: "*";
|
|
57
|
+
return [
|
|
58
|
+
`microphone ${permissionTarget}`,
|
|
59
|
+
`camera ${permissionTarget}`,
|
|
60
|
+
`device-capture ${permissionTarget}`,
|
|
61
|
+
`display-capture ${permissionTarget}`,
|
|
62
|
+
`clipboard-write ${permissionTarget}`,
|
|
63
|
+
].join("; ");
|
|
21
64
|
}
|
|
22
65
|
connectedCallback() {
|
|
23
66
|
super.connectedCallback();
|
|
24
67
|
// Ensure baseURL is provided
|
|
25
68
|
if (!this.baseURL) {
|
|
26
69
|
this.dispatchErrorEvent({
|
|
27
|
-
message:
|
|
70
|
+
message: "baseURL is required",
|
|
28
71
|
});
|
|
29
72
|
return;
|
|
30
73
|
}
|
|
@@ -34,9 +77,10 @@ export class CortiEmbedded extends LitElement {
|
|
|
34
77
|
}
|
|
35
78
|
catch (error) {
|
|
36
79
|
this.dispatchErrorEvent({
|
|
37
|
-
message: error.message ||
|
|
80
|
+
message: error.message || "Invalid baseURL",
|
|
38
81
|
});
|
|
39
|
-
|
|
82
|
+
// Dispatch the error event rather than throwing so consumers can handle it
|
|
83
|
+
// via the 'error' event listener without wrapping connectedCallback in try/catch.
|
|
40
84
|
}
|
|
41
85
|
}
|
|
42
86
|
disconnectedCallback() {
|
|
@@ -65,7 +109,7 @@ export class CortiEmbedded extends LitElement {
|
|
|
65
109
|
}
|
|
66
110
|
else {
|
|
67
111
|
this.dispatchErrorEvent({
|
|
68
|
-
message:
|
|
112
|
+
message: "No iframe or contentWindow available",
|
|
69
113
|
});
|
|
70
114
|
}
|
|
71
115
|
}
|
|
@@ -73,18 +117,32 @@ export class CortiEmbedded extends LitElement {
|
|
|
73
117
|
this.dispatchEvent(new CustomEvent(event, { detail: data }));
|
|
74
118
|
}
|
|
75
119
|
dispatchEmbeddedEvent(rawEventName, payload) {
|
|
76
|
-
|
|
120
|
+
if (rawEventName === "ready" || rawEventName === "loaded")
|
|
121
|
+
return;
|
|
122
|
+
// Pass all other events through as raw DOM events for direct listeners.
|
|
77
123
|
this.dispatchPublicEvent(rawEventName, payload);
|
|
78
|
-
|
|
124
|
+
// Forward supported embedded events through the generic 'event' stream so
|
|
125
|
+
// consumers can observe them without subscribing to each raw event name.
|
|
126
|
+
this.dispatchPublicEvent("event", {
|
|
127
|
+
name: rawEventName,
|
|
128
|
+
payload,
|
|
129
|
+
});
|
|
130
|
+
// Also emit the legacy 'embedded-event' stream for backward compatibility.
|
|
131
|
+
// This allows existing integrations listening for 'embedded-event' to continue
|
|
132
|
+
// working while newer consumers can use the 'event' stream.
|
|
133
|
+
this.dispatchPublicEvent("embedded-event", {
|
|
79
134
|
name: rawEventName,
|
|
80
135
|
payload,
|
|
81
136
|
});
|
|
82
137
|
}
|
|
83
138
|
dispatchErrorEvent(error) {
|
|
84
|
-
this.dispatchPublicEvent(
|
|
139
|
+
this.dispatchPublicEvent("error", error);
|
|
140
|
+
}
|
|
141
|
+
static warnDeprecatedAPI(methodName, replacement) {
|
|
142
|
+
console.warn(`[Corti Embedded] ${methodName} is deprecated and will be removed in a future release. Use ${replacement} instead. See ${CONFIGURATION_MIGRATION_URL} and ${DEPRECATION_TIMELINE_URL}.`);
|
|
85
143
|
}
|
|
86
144
|
isRealIframeLoad(iframe) {
|
|
87
|
-
const src = iframe.getAttribute(
|
|
145
|
+
const src = iframe.getAttribute("src") || "";
|
|
88
146
|
if (!this.normalizedBaseURL)
|
|
89
147
|
return false;
|
|
90
148
|
return isRealEmbeddedLoad(src, this.normalizedBaseURL);
|
|
@@ -108,43 +166,38 @@ export class CortiEmbedded extends LitElement {
|
|
|
108
166
|
}
|
|
109
167
|
}
|
|
110
168
|
getIframe() {
|
|
111
|
-
return this.shadowRoot?.querySelector(
|
|
169
|
+
return this.shadowRoot?.querySelector("iframe") || null;
|
|
112
170
|
}
|
|
113
171
|
updated(changedProps) {
|
|
114
172
|
super.updated(changedProps);
|
|
115
|
-
if (changedProps.has(
|
|
116
|
-
//
|
|
173
|
+
if (changedProps.has("baseURL")) {
|
|
174
|
+
// Tear down the existing handler; the new one is created in handleIframeLoad
|
|
175
|
+
if (this.postMessageHandler) {
|
|
176
|
+
this.postMessageHandler.destroy();
|
|
177
|
+
this.postMessageHandler = null;
|
|
178
|
+
}
|
|
179
|
+
// Validate the new URL
|
|
117
180
|
try {
|
|
118
181
|
this.normalizedBaseURL = validateAndNormalizeBaseURL(this.baseURL);
|
|
119
182
|
}
|
|
120
183
|
catch (error) {
|
|
121
|
-
|
|
122
|
-
if (this.postMessageHandler) {
|
|
123
|
-
this.postMessageHandler.destroy();
|
|
124
|
-
this.postMessageHandler = null;
|
|
125
|
-
}
|
|
184
|
+
this.normalizedBaseURL = null;
|
|
126
185
|
const iframe = this.getIframe();
|
|
127
186
|
if (iframe) {
|
|
128
|
-
iframe.setAttribute(
|
|
187
|
+
iframe.setAttribute("src", "about:blank");
|
|
129
188
|
}
|
|
130
189
|
this.dispatchErrorEvent({
|
|
131
|
-
message: error.message ||
|
|
190
|
+
message: error.message || "Invalid baseURL",
|
|
132
191
|
});
|
|
133
192
|
return;
|
|
134
193
|
}
|
|
135
|
-
//
|
|
136
|
-
if (this.postMessageHandler) {
|
|
137
|
-
this.postMessageHandler.destroy();
|
|
138
|
-
this.postMessageHandler = null;
|
|
139
|
-
}
|
|
194
|
+
// Update the iframe to the new URL
|
|
140
195
|
const iframe = this.getIframe();
|
|
141
196
|
if (iframe) {
|
|
142
|
-
const expected = this.normalizedBaseURL
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
iframe.setAttribute('src', expected);
|
|
147
|
-
iframe.setAttribute('allow', `microphone ${expected}; camera ${expected}; device-capture ${expected}; display-capture ${expected}`);
|
|
197
|
+
const expected = buildEmbeddedUrl(this.normalizedBaseURL);
|
|
198
|
+
iframe.setAttribute("allow", this.getIframeAllowPolicy(expected));
|
|
199
|
+
if (iframe.getAttribute("src") !== expected) {
|
|
200
|
+
iframe.setAttribute("src", expected);
|
|
148
201
|
}
|
|
149
202
|
}
|
|
150
203
|
}
|
|
@@ -157,7 +210,7 @@ export class CortiEmbedded extends LitElement {
|
|
|
157
210
|
*/
|
|
158
211
|
async auth(credentials) {
|
|
159
212
|
if (!this.postMessageHandler) {
|
|
160
|
-
throw new Error(
|
|
213
|
+
throw new Error("Component not ready");
|
|
161
214
|
}
|
|
162
215
|
try {
|
|
163
216
|
const payload = {
|
|
@@ -168,18 +221,24 @@ export class CortiEmbedded extends LitElement {
|
|
|
168
221
|
refresh_expires_in: credentials.refresh_expires_in,
|
|
169
222
|
refresh_token: credentials.refresh_token,
|
|
170
223
|
id_token: credentials.id_token,
|
|
171
|
-
|
|
224
|
+
"not-before-policy": credentials["not-before-policy"],
|
|
172
225
|
session_state: credentials.session_state,
|
|
173
226
|
scope: credentials.scope,
|
|
174
227
|
profile: credentials.profile,
|
|
175
|
-
mode: credentials.mode,
|
|
176
228
|
};
|
|
177
|
-
const
|
|
178
|
-
|
|
229
|
+
const response = await this.postMessageHandler.postMessage({
|
|
230
|
+
type: "CORTI_EMBEDDED",
|
|
231
|
+
version: "v1",
|
|
232
|
+
action: "auth",
|
|
233
|
+
payload,
|
|
234
|
+
});
|
|
235
|
+
if (response.success && response.payload) {
|
|
236
|
+
return response.payload.user;
|
|
237
|
+
}
|
|
238
|
+
throw new Error(response.error);
|
|
179
239
|
}
|
|
180
240
|
catch (error) {
|
|
181
|
-
const formattedError = formatError(error,
|
|
182
|
-
this.dispatchErrorEvent(formattedError);
|
|
241
|
+
const formattedError = formatError(error, "Authentication failed");
|
|
183
242
|
throw new Error(JSON.stringify(formattedError));
|
|
184
243
|
}
|
|
185
244
|
}
|
|
@@ -190,18 +249,26 @@ export class CortiEmbedded extends LitElement {
|
|
|
190
249
|
*/
|
|
191
250
|
async createInteraction(encounter) {
|
|
192
251
|
if (!this.postMessageHandler) {
|
|
193
|
-
throw new Error(
|
|
252
|
+
throw new Error("Component not ready");
|
|
194
253
|
}
|
|
195
254
|
try {
|
|
196
|
-
const response = await this.postMessageHandler.
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
255
|
+
const response = await this.postMessageHandler.postMessage({
|
|
256
|
+
type: "CORTI_EMBEDDED",
|
|
257
|
+
version: "v1",
|
|
258
|
+
action: "createInteraction",
|
|
259
|
+
payload: encounter,
|
|
260
|
+
});
|
|
261
|
+
if (response.success && response.payload) {
|
|
262
|
+
const result = response.payload;
|
|
263
|
+
return {
|
|
264
|
+
id: result.id,
|
|
265
|
+
createdAt: result.createdAt,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
throw new Error(response.error);
|
|
201
269
|
}
|
|
202
270
|
catch (error) {
|
|
203
|
-
const formattedError = formatError(error,
|
|
204
|
-
this.dispatchErrorEvent(formattedError);
|
|
271
|
+
const formattedError = formatError(error, "Failed to create interaction");
|
|
205
272
|
throw new Error(JSON.stringify(formattedError));
|
|
206
273
|
}
|
|
207
274
|
}
|
|
@@ -212,20 +279,25 @@ export class CortiEmbedded extends LitElement {
|
|
|
212
279
|
*/
|
|
213
280
|
async configureSession(config) {
|
|
214
281
|
if (!this.postMessageHandler) {
|
|
215
|
-
throw new Error(
|
|
282
|
+
throw new Error("Component not ready");
|
|
216
283
|
}
|
|
217
284
|
try {
|
|
285
|
+
CortiEmbedded.warnDeprecatedAPI("configureSession()", "setInteractionOptions()");
|
|
218
286
|
const payload = {
|
|
219
287
|
defaultLanguage: config.defaultLanguage,
|
|
220
288
|
defaultOutputLanguage: config.defaultOutputLanguage,
|
|
221
289
|
defaultTemplateKey: config.defaultTemplateKey,
|
|
222
290
|
defaultMode: config.defaultMode,
|
|
223
291
|
};
|
|
224
|
-
await this.postMessageHandler.
|
|
292
|
+
await this.postMessageHandler.postMessage({
|
|
293
|
+
type: "CORTI_EMBEDDED",
|
|
294
|
+
version: "v1",
|
|
295
|
+
action: "configureSession",
|
|
296
|
+
payload,
|
|
297
|
+
});
|
|
225
298
|
}
|
|
226
299
|
catch (error) {
|
|
227
|
-
const formattedError = formatError(error,
|
|
228
|
-
this.dispatchErrorEvent(formattedError);
|
|
300
|
+
const formattedError = formatError(error, "Failed to configure session");
|
|
229
301
|
throw new Error(JSON.stringify(formattedError));
|
|
230
302
|
}
|
|
231
303
|
}
|
|
@@ -236,34 +308,42 @@ export class CortiEmbedded extends LitElement {
|
|
|
236
308
|
*/
|
|
237
309
|
async addFacts(facts) {
|
|
238
310
|
if (!this.postMessageHandler) {
|
|
239
|
-
throw new Error(
|
|
311
|
+
throw new Error("Component not ready");
|
|
240
312
|
}
|
|
241
313
|
try {
|
|
242
314
|
const payload = { facts };
|
|
243
|
-
await this.postMessageHandler.
|
|
315
|
+
await this.postMessageHandler.postMessage({
|
|
316
|
+
type: "CORTI_EMBEDDED",
|
|
317
|
+
version: "v1",
|
|
318
|
+
action: "addFacts",
|
|
319
|
+
payload,
|
|
320
|
+
});
|
|
244
321
|
}
|
|
245
322
|
catch (error) {
|
|
246
|
-
const formattedError = formatError(error,
|
|
247
|
-
this.dispatchErrorEvent(formattedError);
|
|
323
|
+
const formattedError = formatError(error, "Failed to add facts");
|
|
248
324
|
throw new Error(JSON.stringify(formattedError));
|
|
249
325
|
}
|
|
250
326
|
}
|
|
251
327
|
/**
|
|
252
328
|
* Navigate to a specific path within the embedded UI
|
|
253
|
-
* @param
|
|
329
|
+
* @param payload Navigation request payload or legacy path string
|
|
254
330
|
* @returns Promise that resolves when navigation is complete
|
|
255
331
|
*/
|
|
256
|
-
async navigate(
|
|
332
|
+
async navigate(payload) {
|
|
257
333
|
if (!this.postMessageHandler) {
|
|
258
|
-
throw new Error(
|
|
334
|
+
throw new Error("Component not ready");
|
|
259
335
|
}
|
|
260
336
|
try {
|
|
261
|
-
const
|
|
262
|
-
await this.postMessageHandler.
|
|
337
|
+
const normalizedPayload = typeof payload === "string" ? { path: payload } : payload;
|
|
338
|
+
await this.postMessageHandler.postMessage({
|
|
339
|
+
type: "CORTI_EMBEDDED",
|
|
340
|
+
version: "v1",
|
|
341
|
+
action: "navigate",
|
|
342
|
+
payload: normalizedPayload,
|
|
343
|
+
});
|
|
263
344
|
}
|
|
264
345
|
catch (error) {
|
|
265
|
-
const formattedError = formatError(error,
|
|
266
|
-
this.dispatchErrorEvent(formattedError);
|
|
346
|
+
const formattedError = formatError(error, "Failed to navigate");
|
|
267
347
|
throw new Error(JSON.stringify(formattedError));
|
|
268
348
|
}
|
|
269
349
|
}
|
|
@@ -273,14 +353,18 @@ export class CortiEmbedded extends LitElement {
|
|
|
273
353
|
*/
|
|
274
354
|
async startRecording() {
|
|
275
355
|
if (!this.postMessageHandler) {
|
|
276
|
-
throw new Error(
|
|
356
|
+
throw new Error("Component not ready");
|
|
277
357
|
}
|
|
278
358
|
try {
|
|
279
|
-
await this.postMessageHandler.
|
|
359
|
+
await this.postMessageHandler.postMessage({
|
|
360
|
+
type: "CORTI_EMBEDDED",
|
|
361
|
+
version: "v1",
|
|
362
|
+
action: "startRecording",
|
|
363
|
+
payload: {},
|
|
364
|
+
});
|
|
280
365
|
}
|
|
281
366
|
catch (error) {
|
|
282
|
-
const formattedError = formatError(error,
|
|
283
|
-
this.dispatchErrorEvent(formattedError);
|
|
367
|
+
const formattedError = formatError(error, "Failed to start recording");
|
|
284
368
|
throw new Error(JSON.stringify(formattedError));
|
|
285
369
|
}
|
|
286
370
|
}
|
|
@@ -290,14 +374,18 @@ export class CortiEmbedded extends LitElement {
|
|
|
290
374
|
*/
|
|
291
375
|
async stopRecording() {
|
|
292
376
|
if (!this.postMessageHandler) {
|
|
293
|
-
throw new Error(
|
|
377
|
+
throw new Error("Component not ready");
|
|
294
378
|
}
|
|
295
379
|
try {
|
|
296
|
-
await this.postMessageHandler.
|
|
380
|
+
await this.postMessageHandler.postMessage({
|
|
381
|
+
type: "CORTI_EMBEDDED",
|
|
382
|
+
version: "v1",
|
|
383
|
+
action: "stopRecording",
|
|
384
|
+
payload: {},
|
|
385
|
+
});
|
|
297
386
|
}
|
|
298
387
|
catch (error) {
|
|
299
|
-
const formattedError = formatError(error,
|
|
300
|
-
this.dispatchErrorEvent(formattedError);
|
|
388
|
+
const formattedError = formatError(error, "Failed to stop recording");
|
|
301
389
|
throw new Error(JSON.stringify(formattedError));
|
|
302
390
|
}
|
|
303
391
|
}
|
|
@@ -312,16 +400,50 @@ export class CortiEmbedded extends LitElement {
|
|
|
312
400
|
isAuthenticated: false,
|
|
313
401
|
user: undefined,
|
|
314
402
|
},
|
|
315
|
-
currentUrl:
|
|
403
|
+
currentUrl: "",
|
|
316
404
|
interaction: null,
|
|
317
405
|
};
|
|
318
406
|
}
|
|
319
407
|
try {
|
|
320
|
-
|
|
408
|
+
const response = await this.postMessageHandler.postMessage({
|
|
409
|
+
type: "CORTI_EMBEDDED",
|
|
410
|
+
version: "v1",
|
|
411
|
+
action: "getStatus",
|
|
412
|
+
payload: {},
|
|
413
|
+
});
|
|
414
|
+
if (response.success && response.payload) {
|
|
415
|
+
return response.payload;
|
|
416
|
+
}
|
|
417
|
+
throw new Error(response.error);
|
|
321
418
|
}
|
|
322
419
|
catch (error) {
|
|
323
|
-
const formattedError = formatError(error,
|
|
324
|
-
|
|
420
|
+
const formattedError = formatError(error, "Failed to get status");
|
|
421
|
+
throw new Error(JSON.stringify(formattedError));
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Configure the component
|
|
426
|
+
* @param config Component configuration
|
|
427
|
+
* @returns Promise that resolves when configuration is applied
|
|
428
|
+
*/
|
|
429
|
+
async configureApp(config) {
|
|
430
|
+
if (!this.postMessageHandler) {
|
|
431
|
+
throw new Error("Component not ready");
|
|
432
|
+
}
|
|
433
|
+
try {
|
|
434
|
+
const response = await this.postMessageHandler.postMessage({
|
|
435
|
+
type: "CORTI_EMBEDDED",
|
|
436
|
+
version: "v1",
|
|
437
|
+
action: "configureApp",
|
|
438
|
+
payload: config,
|
|
439
|
+
});
|
|
440
|
+
if (response.success && response.payload) {
|
|
441
|
+
return response.payload;
|
|
442
|
+
}
|
|
443
|
+
throw new Error(response.error);
|
|
444
|
+
}
|
|
445
|
+
catch (error) {
|
|
446
|
+
const formattedError = formatError(error, "Failed to configure app");
|
|
325
447
|
throw new Error(JSON.stringify(formattedError));
|
|
326
448
|
}
|
|
327
449
|
}
|
|
@@ -332,14 +454,48 @@ export class CortiEmbedded extends LitElement {
|
|
|
332
454
|
*/
|
|
333
455
|
async configure(config) {
|
|
334
456
|
if (!this.postMessageHandler) {
|
|
335
|
-
throw new Error(
|
|
457
|
+
throw new Error("Component not ready");
|
|
458
|
+
}
|
|
459
|
+
try {
|
|
460
|
+
CortiEmbedded.warnDeprecatedAPI("configure()", "configureApp()");
|
|
461
|
+
const response = await this.postMessageHandler.postMessage({
|
|
462
|
+
type: "CORTI_EMBEDDED",
|
|
463
|
+
version: "v1",
|
|
464
|
+
action: "configure",
|
|
465
|
+
payload: config,
|
|
466
|
+
});
|
|
467
|
+
if (response.success && response.payload) {
|
|
468
|
+
return response.payload;
|
|
469
|
+
}
|
|
470
|
+
throw new Error(response.error);
|
|
471
|
+
}
|
|
472
|
+
catch (error) {
|
|
473
|
+
const formattedError = formatError(error, "Failed to configure component");
|
|
474
|
+
throw new Error(JSON.stringify(formattedError));
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Set one-shot interaction options for the embedded instance.
|
|
479
|
+
* @param config Interaction/session-level options
|
|
480
|
+
* @returns Promise that resolves when options are applied
|
|
481
|
+
*/
|
|
482
|
+
async setInteractionOptions(config) {
|
|
483
|
+
if (!this.postMessageHandler) {
|
|
484
|
+
throw new Error("Component not ready");
|
|
336
485
|
}
|
|
337
486
|
try {
|
|
338
|
-
|
|
487
|
+
const response = await this.postMessageHandler.postMessage({
|
|
488
|
+
type: "CORTI_EMBEDDED",
|
|
489
|
+
version: "v1",
|
|
490
|
+
action: "setInteractionOptions",
|
|
491
|
+
payload: config,
|
|
492
|
+
});
|
|
493
|
+
if (response.success === false || response.error) {
|
|
494
|
+
throw new Error(response.error);
|
|
495
|
+
}
|
|
339
496
|
}
|
|
340
497
|
catch (error) {
|
|
341
|
-
const formattedError = formatError(error,
|
|
342
|
-
this.dispatchErrorEvent(formattedError);
|
|
498
|
+
const formattedError = formatError(error, "Failed to set interaction options");
|
|
343
499
|
throw new Error(JSON.stringify(formattedError));
|
|
344
500
|
}
|
|
345
501
|
}
|
|
@@ -350,17 +506,21 @@ export class CortiEmbedded extends LitElement {
|
|
|
350
506
|
*/
|
|
351
507
|
async setCredentials(credentials) {
|
|
352
508
|
if (!this.postMessageHandler) {
|
|
353
|
-
throw new Error(
|
|
509
|
+
throw new Error("Component not ready");
|
|
354
510
|
}
|
|
355
511
|
try {
|
|
356
512
|
if (!credentials.password) {
|
|
357
|
-
throw new Error(
|
|
513
|
+
throw new Error("Password is required");
|
|
358
514
|
}
|
|
359
|
-
await this.postMessageHandler.
|
|
515
|
+
await this.postMessageHandler.postMessage({
|
|
516
|
+
type: "CORTI_EMBEDDED",
|
|
517
|
+
version: "v1",
|
|
518
|
+
action: "setCredentials",
|
|
519
|
+
payload: credentials,
|
|
520
|
+
});
|
|
360
521
|
}
|
|
361
522
|
catch (error) {
|
|
362
|
-
const formattedError = formatError(error,
|
|
363
|
-
this.dispatchErrorEvent(formattedError);
|
|
523
|
+
const formattedError = formatError(error, "Failed to set credentials");
|
|
364
524
|
throw new Error(JSON.stringify(formattedError));
|
|
365
525
|
}
|
|
366
526
|
}
|
|
@@ -368,28 +528,34 @@ export class CortiEmbedded extends LitElement {
|
|
|
368
528
|
* Show the embedded UI
|
|
369
529
|
*/
|
|
370
530
|
show() {
|
|
371
|
-
this.visibility =
|
|
531
|
+
this.visibility = "visible";
|
|
372
532
|
}
|
|
373
533
|
/**
|
|
374
534
|
* Hide the embedded UI
|
|
375
535
|
*/
|
|
376
536
|
hide() {
|
|
377
|
-
this.visibility =
|
|
537
|
+
this.visibility = "hidden";
|
|
378
538
|
}
|
|
379
539
|
/**
|
|
380
540
|
* Get templates
|
|
381
541
|
*/
|
|
382
542
|
async getTemplates() {
|
|
383
543
|
if (!this.postMessageHandler) {
|
|
384
|
-
throw new Error(
|
|
544
|
+
throw new Error("Component not ready");
|
|
385
545
|
}
|
|
386
546
|
try {
|
|
387
|
-
const response = await this.postMessageHandler.
|
|
388
|
-
|
|
547
|
+
const response = await this.postMessageHandler.postMessage({
|
|
548
|
+
type: "CORTI_EMBEDDED",
|
|
549
|
+
version: "v1",
|
|
550
|
+
action: "getTemplates",
|
|
551
|
+
});
|
|
552
|
+
if (response.success && response.payload) {
|
|
553
|
+
return response.payload;
|
|
554
|
+
}
|
|
555
|
+
throw new Error(response.error);
|
|
389
556
|
}
|
|
390
557
|
catch (error) {
|
|
391
|
-
const formattedError = formatError(error,
|
|
392
|
-
this.dispatchErrorEvent(formattedError);
|
|
558
|
+
const formattedError = formatError(error, "Failed to get templates");
|
|
393
559
|
throw new Error(JSON.stringify(formattedError));
|
|
394
560
|
}
|
|
395
561
|
}
|
|
@@ -401,7 +567,7 @@ export class CortiEmbedded extends LitElement {
|
|
|
401
567
|
getDebugStatus() {
|
|
402
568
|
const iframe = this.getIframe();
|
|
403
569
|
return {
|
|
404
|
-
ready: iframe?.contentDocument?.readyState ===
|
|
570
|
+
ready: iframe?.contentDocument?.readyState === "complete",
|
|
405
571
|
iframeExists: !!iframe,
|
|
406
572
|
iframeSrc: iframe?.src,
|
|
407
573
|
iframeContentWindow: !!iframe?.contentWindow,
|
|
@@ -413,21 +579,23 @@ export class CortiEmbedded extends LitElement {
|
|
|
413
579
|
};
|
|
414
580
|
}
|
|
415
581
|
render() {
|
|
416
|
-
//
|
|
417
|
-
|
|
418
|
-
|
|
582
|
+
// Use the pre-validated normalizedBaseURL so render() never throws.
|
|
583
|
+
// normalizedBaseURL is set in connectedCallback (before first render) and
|
|
584
|
+
// kept up to date by updated() on each baseURL change.
|
|
585
|
+
if (!this.normalizedBaseURL) {
|
|
586
|
+
return html ``;
|
|
419
587
|
}
|
|
420
588
|
return html `
|
|
421
589
|
<iframe
|
|
422
|
-
src=${buildEmbeddedUrl(
|
|
590
|
+
src=${buildEmbeddedUrl(this.normalizedBaseURL)}
|
|
423
591
|
title="Corti Embedded UI"
|
|
424
|
-
sandbox=${
|
|
425
|
-
allow
|
|
592
|
+
sandbox=${IFRAME_SANDBOX_POLICY}
|
|
593
|
+
allow=${this.getIframeAllowPolicy(this.normalizedBaseURL)}
|
|
426
594
|
@load=${(event) => this.handleIframeLoad(event)}
|
|
427
595
|
@unload=${() => this.postMessageHandler?.destroy()}
|
|
428
|
-
style=${this.visibility ===
|
|
429
|
-
?
|
|
430
|
-
:
|
|
596
|
+
style=${this.visibility === "hidden"
|
|
597
|
+
? "display: none;"
|
|
598
|
+
: "display: block;"}
|
|
431
599
|
></iframe>
|
|
432
600
|
`;
|
|
433
601
|
}
|