cap-copilot-widget 0.1.0 → 0.1.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.
@@ -6,8 +6,8 @@ const f = class f {
6
6
  const n = f._fromCookie();
7
7
  if (n) return n;
8
8
  try {
9
- const i = localStorage.getItem("access_token");
10
- if (i) return i;
9
+ const r = localStorage.getItem("access_token");
10
+ if (r) return r;
11
11
  } catch {
12
12
  }
13
13
  return null;
@@ -19,9 +19,9 @@ const f = class f {
19
19
  try {
20
20
  const t = document.cookie.split(";");
21
21
  for (const e of t) {
22
- const [n, ...i] = e.trim().split("=");
22
+ const [n, ...r] = e.trim().split("=");
23
23
  if (f.XSUAA_COOKIE_NAMES.includes(n.trim()))
24
- return decodeURIComponent(i.join("=").trim());
24
+ return decodeURIComponent(r.join("=").trim());
25
25
  }
26
26
  } catch {
27
27
  }
@@ -37,18 +37,18 @@ f.XSUAA_COOKIE_NAMES = [
37
37
  let d = f;
38
38
  class m {
39
39
  static getHash() {
40
- var t, e, n, i;
40
+ var t, e, n, r;
41
41
  try {
42
- const r = (n = (e = (t = sap == null ? void 0 : sap.ushell) == null ? void 0 : t.Container) == null ? void 0 : e.getService) == null ? void 0 : n.call(
42
+ const o = (n = (e = (t = sap == null ? void 0 : sap.ushell) == null ? void 0 : t.Container) == null ? void 0 : e.getService) == null ? void 0 : n.call(
43
43
  e,
44
44
  "CrossApplicationNavigation"
45
45
  );
46
- if (r) {
47
- const s = (i = r.hrefForExternal) == null ? void 0 : i.call(r);
48
- if (s) return s;
46
+ if (o) {
47
+ const i = (r = o.hrefForExternal) == null ? void 0 : r.call(o);
48
+ if (i) return i;
49
49
  }
50
- } catch (r) {
51
- console.log(r);
50
+ } catch (o) {
51
+ console.log(o);
52
52
  }
53
53
  return window.location.hash || "";
54
54
  }
@@ -61,9 +61,9 @@ class m {
61
61
  }
62
62
  }
63
63
  static getUserLocale() {
64
- var t, e, n, i, r, s;
64
+ var t, e, n, r, o, i;
65
65
  try {
66
- return ((s = (r = (i = (n = (e = (t = sap == null ? void 0 : sap.ui) == null ? void 0 : t.getCore) == null ? void 0 : e.call(t)) == null ? void 0 : n.getConfiguration) == null ? void 0 : i.call(n)) == null ? void 0 : r.getLanguageTag) == null ? void 0 : s.call(r)) ?? navigator.language ?? "en";
66
+ return ((i = (o = (r = (n = (e = (t = sap == null ? void 0 : sap.ui) == null ? void 0 : t.getCore) == null ? void 0 : e.call(t)) == null ? void 0 : n.getConfiguration) == null ? void 0 : r.call(n)) == null ? void 0 : o.getLanguageTag) == null ? void 0 : i.call(o)) ?? navigator.language ?? "en";
67
67
  } catch {
68
68
  return navigator.language ?? "en";
69
69
  }
@@ -71,24 +71,24 @@ class m {
71
71
  }
72
72
  class u {
73
73
  static getCurrentEntity() {
74
- var t, e, n, i;
74
+ var t, e, n, r;
75
75
  try {
76
- const r = (e = (t = sap == null ? void 0 : sap.ui) == null ? void 0 : t.getCore) == null ? void 0 : e.call(t);
77
- if (!r) return null;
78
- let s = document.activeElement;
79
- for (; s; ) {
80
- const a = s.getAttribute("id") || s.getAttribute("data-sap-ui");
76
+ const o = (e = (t = sap == null ? void 0 : sap.ui) == null ? void 0 : t.getCore) == null ? void 0 : e.call(t);
77
+ if (!o) return null;
78
+ let i = document.activeElement;
79
+ for (; i; ) {
80
+ const a = i.getAttribute("id") || i.getAttribute("data-sap-ui");
81
81
  if (a) {
82
- const o = r.byId(a), l = (n = o == null ? void 0 : o.getBindingContext) == null ? void 0 : n.call(o);
82
+ const s = o.byId(a), l = (n = s == null ? void 0 : s.getBindingContext) == null ? void 0 : n.call(s);
83
83
  if (l) {
84
- const p = (i = l.getObject) == null ? void 0 : i.call(l);
84
+ const p = (r = l.getObject) == null ? void 0 : r.call(l);
85
85
  if (p && typeof p == "object")
86
86
  return u._sanitize(p);
87
87
  }
88
88
  }
89
- s = s.parentElement;
89
+ i = i.parentElement;
90
90
  }
91
- return u._scanAllControls(r);
91
+ return u._scanAllControls(o);
92
92
  } catch {
93
93
  return null;
94
94
  }
@@ -96,13 +96,13 @@ class u {
96
96
  static _scanAllControls(t) {
97
97
  var e, n;
98
98
  try {
99
- const i = t.mElements ?? {};
100
- for (const r of Object.keys(i)) {
101
- const s = i[r], a = (e = s == null ? void 0 : s.getBindingContext) == null ? void 0 : e.call(s);
99
+ const r = t.mElements ?? {};
100
+ for (const o of Object.keys(r)) {
101
+ const i = r[o], a = (e = i == null ? void 0 : i.getBindingContext) == null ? void 0 : e.call(i);
102
102
  if (a) {
103
- const o = (n = a.getObject) == null ? void 0 : n.call(a);
104
- if (o && typeof o == "object" && Object.keys(o).length > 0)
105
- return u._sanitize(o);
103
+ const s = (n = a.getObject) == null ? void 0 : n.call(a);
104
+ if (s && typeof s == "object" && Object.keys(s).length > 0)
105
+ return u._sanitize(s);
106
106
  }
107
107
  }
108
108
  } catch {
@@ -114,15 +114,15 @@ class u {
114
114
  try {
115
115
  const n = (e = (t = sap == null ? void 0 : sap.ui) == null ? void 0 : t.getCore) == null ? void 0 : e.call(t);
116
116
  if (!n) return null;
117
- const i = n.mElements ?? {};
118
- for (const r of Object.keys(i)) {
119
- const s = i[r];
120
- if (!(s != null && s.getModel)) continue;
121
- const a = s.getModel();
117
+ const r = n.mElements ?? {};
118
+ for (const o of Object.keys(r)) {
119
+ const i = r[o];
120
+ if (!(i != null && i.getModel)) continue;
121
+ const a = i.getModel();
122
122
  if (!a) continue;
123
- const o = a.sServiceUrl ?? a._sServiceUrl;
124
- if (typeof o == "string" && o.length > 4)
125
- return o.replace(/\/$/, "");
123
+ const s = a.sServiceUrl ?? a._sServiceUrl;
124
+ if (typeof s == "string" && s.length > 4)
125
+ return s.replace(/\/$/, "");
126
126
  }
127
127
  } catch {
128
128
  }
@@ -130,8 +130,8 @@ class u {
130
130
  }
131
131
  static _sanitize(t) {
132
132
  const e = {};
133
- for (const [n, i] of Object.entries(t))
134
- n.startsWith("__") || (i === null || typeof i != "object" ? e[n] = i : i.__deferred || (e[n] = i));
133
+ for (const [n, r] of Object.entries(t))
134
+ n.startsWith("__") || (r === null || typeof r != "object" ? e[n] = r : r.__deferred || (e[n] = r));
135
135
  return e;
136
136
  }
137
137
  }
@@ -140,19 +140,19 @@ const c = class c {
140
140
  const n = `btp-copilot-meta-${t}`;
141
141
  if (c._cache.has(n))
142
142
  return c._cache.get(n);
143
- const i = sessionStorage.getItem(n);
144
- if (i)
143
+ const r = sessionStorage.getItem(n);
144
+ if (r)
145
145
  try {
146
- const r = JSON.parse(i);
147
- return c._cache.set(n, r), r;
146
+ const o = JSON.parse(r);
147
+ return c._cache.set(n, o), o;
148
148
  } catch {
149
149
  }
150
150
  try {
151
- const r = `${t}/$metadata`, s = { Accept: "application/xml" };
152
- e && (s.Authorization = `Bearer ${e}`);
153
- const a = await fetch(r, { headers: s });
151
+ const o = `${t}/$metadata`, i = { Accept: "application/xml" };
152
+ e && (i.Authorization = `Bearer ${e}`);
153
+ const a = await fetch(o, { headers: i });
154
154
  if (!a.ok) return [];
155
- const o = await a.text(), l = c._parseEDMX(o), p = c._schemasToDocuments(l, t);
155
+ const s = await a.text(), l = c._parseEDMX(s), p = c._schemasToDocuments(l, t);
156
156
  return c._cache.set(n, p), sessionStorage.setItem(n, JSON.stringify(p)), p;
157
157
  } catch {
158
158
  return [];
@@ -160,26 +160,26 @@ const c = class c {
160
160
  }
161
161
  static _parseEDMX(t) {
162
162
  try {
163
- const i = new DOMParser().parseFromString(t, "text/xml").querySelectorAll("EntityType");
164
- return Array.from(i).map((r) => {
165
- const s = r.getAttribute("Name") ?? "", a = r.querySelectorAll("Key > PropertyRef"), o = new Set(
163
+ const r = new DOMParser().parseFromString(t, "text/xml").querySelectorAll("EntityType");
164
+ return Array.from(r).map((o) => {
165
+ const i = o.getAttribute("Name") ?? "", a = o.querySelectorAll("Key > PropertyRef"), s = new Set(
166
166
  Array.from(a).map((h) => h.getAttribute("Name") ?? "")
167
167
  ), l = Array.from(
168
- r.querySelectorAll("Property")
168
+ o.querySelectorAll("Property")
169
169
  ).map((h) => ({
170
170
  name: h.getAttribute("Name") ?? "",
171
171
  type: c._shortType(h.getAttribute("Type") ?? ""),
172
- isKey: o.has(h.getAttribute("Name") ?? ""),
172
+ isKey: s.has(h.getAttribute("Name") ?? ""),
173
173
  nullable: h.getAttribute("Nullable") !== "false"
174
174
  })), p = Array.from(
175
- r.querySelectorAll("NavigationProperty")
175
+ o.querySelectorAll("NavigationProperty")
176
176
  ).map((h) => ({
177
177
  name: h.getAttribute("Name") ?? "",
178
178
  type: c._shortType(
179
179
  h.getAttribute("Type") ?? h.getAttribute("ToRole") ?? ""
180
180
  )
181
181
  }));
182
- return { name: s, properties: l, navProperties: p };
182
+ return { name: i, properties: l, navProperties: p };
183
183
  });
184
184
  } catch {
185
185
  return [];
@@ -190,24 +190,24 @@ const c = class c {
190
190
  }
191
191
  static _schemasToDocuments(t, e) {
192
192
  const n = [];
193
- for (const i of t) {
194
- if (!i.name) continue;
195
- const r = i.properties.filter((o) => o.isKey), s = i.properties.filter((o) => !o.isKey), a = [
196
- `Entity: ${i.name}`,
193
+ for (const r of t) {
194
+ if (!r.name) continue;
195
+ const o = r.properties.filter((s) => s.isKey), i = r.properties.filter((s) => !s.isKey), a = [
196
+ `Entity: ${r.name}`,
197
197
  `OData service: ${e}`,
198
- `Entity set path: ${e}/${i.name}`,
199
- `Count path: ${e}/${i.name}/$count`
198
+ `Entity set path: ${e}/${r.name}`,
199
+ `Count path: ${e}/${r.name}/$count`
200
200
  ];
201
- r.length && a.push(
202
- `Key fields: ${r.map((o) => `${o.name} (${o.type})`).join(", ")}`
203
- ), s.length && a.push(
204
- `Fields: ${s.map(
205
- (o) => `${o.name} (${o.type}${o.nullable ? "" : ", required"})`
201
+ o.length && a.push(
202
+ `Key fields: ${o.map((s) => `${s.name} (${s.type})`).join(", ")}`
203
+ ), i.length && a.push(
204
+ `Fields: ${i.map(
205
+ (s) => `${s.name} (${s.type}${s.nullable ? "" : ", required"})`
206
206
  ).join(", ")}`
207
- ), i.navProperties.length && a.push(
208
- `Navigation: ${i.navProperties.map((o) => `${o.name} → ${o.type}`).join(", ")}`
207
+ ), r.navProperties.length && a.push(
208
+ `Navigation: ${r.navProperties.map((s) => `${s.name} → ${s.type}`).join(", ")}`
209
209
  ), n.push({
210
- title: `${i.name} entity schema`,
210
+ title: `${r.name} entity schema`,
211
211
  content: a.join(`
212
212
  `)
213
213
  });
@@ -216,7 +216,7 @@ const c = class c {
216
216
  title: "Available OData entity sets",
217
217
  content: [
218
218
  `OData service: ${e}`,
219
- `Entities: ${t.map((i) => i.name).join(", ")}`,
219
+ `Entities: ${t.map((r) => r.name).join(", ")}`,
220
220
  "GET {entity}/$count | ?$filter=field eq 'value' | ?$top=10&$skip=0 | ?$orderby=field desc"
221
221
  ].join(`
222
222
  `)
@@ -231,15 +231,16 @@ c._cache = /* @__PURE__ */ new Map();
231
231
  let b = c;
232
232
  class g {
233
233
  static capture(t) {
234
+ var n, r, o;
234
235
  const e = { ...t };
235
236
  try {
236
- const n = m.getHash();
237
- n && (e.current_view = n);
237
+ const i = m.getHash();
238
+ i && (e.current_view = i);
238
239
  } catch {
239
240
  }
240
241
  try {
241
- const n = u.getCurrentEntity();
242
- n && Object.keys(n).length > 0 && (e.entity_data = n);
242
+ const i = u.getCurrentEntity();
243
+ i && Object.keys(i).length > 0 && (e.entity_data = i);
243
244
  } catch {
244
245
  }
245
246
  try {
@@ -247,8 +248,25 @@ class g {
247
248
  } catch {
248
249
  }
249
250
  try {
250
- const n = window.__APP_CONTEXT__;
251
- n && (n.entity_data && (e.entity_data = { ...n.entity_data, ...e.entity_data }), n.current_view && !e.current_view && (e.current_view = n.current_view), n.extra && (e.extra = { ...n.extra, ...e.extra ?? {} }), n.service_url && !e.service_url && (e.service_url = n.service_url));
251
+ const i = window.location.pathname + window.location.search + window.location.hash;
252
+ (!e.current_view || e.current_view === "") && (e.current_view = i);
253
+ } catch {
254
+ }
255
+ try {
256
+ e.user_locale || (e.user_locale = navigator.language || ((n = navigator.languages) == null ? void 0 : n[0]) || "en");
257
+ } catch {
258
+ }
259
+ try {
260
+ e.extra = {
261
+ ...e.extra ?? {},
262
+ page_title: ((r = e.extra) == null ? void 0 : r.page_title) ?? document.title ?? "",
263
+ page_url: ((o = e.extra) == null ? void 0 : o.page_url) ?? window.location.href ?? ""
264
+ };
265
+ } catch {
266
+ }
267
+ try {
268
+ const i = window.__APP_CONTEXT__;
269
+ i && (i.entity_data && (e.entity_data = { ...i.entity_data, ...e.entity_data }), i.current_view && !e.current_view && (e.current_view = i.current_view), i.extra && (e.extra = { ...i.extra, ...e.extra ?? {} }), i.service_url && !e.service_url && (e.service_url = i.service_url));
252
270
  } catch {
253
271
  }
254
272
  return e;
@@ -258,16 +276,16 @@ class g {
258
276
  const e = g.capture(t);
259
277
  if (e.service_url || (e.service_url = g._discoverServiceUrl() ?? void 0), e.service_url)
260
278
  try {
261
- const i = ((n = e.extra) == null ? void 0 : n.auth_token) ?? null, r = await b.fetchSchemaDocuments(
279
+ const r = ((n = e.extra) == null ? void 0 : n.auth_token) ?? null, o = await b.fetchSchemaDocuments(
262
280
  e.service_url,
263
- i
281
+ r
264
282
  );
265
- if (r.length > 0) {
266
- const s = r.map((a) => `## ${a.title}
283
+ if (o.length > 0) {
284
+ const i = o.map((a) => `## ${a.title}
267
285
  ${a.content}`).join(`
268
286
 
269
287
  `);
270
- e.extra = { ...e.extra ?? {}, schema_hint: s };
288
+ e.extra = { ...e.extra ?? {}, schema_hint: i };
271
289
  }
272
290
  } catch {
273
291
  }
@@ -303,11 +321,11 @@ ${a.content}`).join(`
303
321
  try {
304
322
  const e = await fetch("/manifest.json");
305
323
  if (!e.ok) return null;
306
- const n = await e.json(), i = ((t = n == null ? void 0 : n["sap.app"]) == null ? void 0 : t.dataSources) ?? {};
307
- for (const r of Object.keys(i)) {
308
- const s = i[r];
309
- if ((s == null ? void 0 : s.type) === "ODataAnnotation") continue;
310
- const a = s == null ? void 0 : s.uri;
324
+ const n = await e.json(), r = ((t = n == null ? void 0 : n["sap.app"]) == null ? void 0 : t.dataSources) ?? {};
325
+ for (const o of Object.keys(r)) {
326
+ const i = r[o];
327
+ if ((i == null ? void 0 : i.type) === "ODataAnnotation") continue;
328
+ const a = i == null ? void 0 : i.uri;
311
329
  if (typeof a == "string" && a.length > 0)
312
330
  return new URL(a, window.location.href).toString().replace(/\/$/, "");
313
331
  }
@@ -315,13 +333,13 @@ ${a.content}`).join(`
315
333
  }
316
334
  return null;
317
335
  }
318
- static listenForUpdates(t, e, n, i) {
319
- const r = (s) => {
320
- if (!s.data || typeof s.data != "object") return;
321
- const { type: a, payload: o, text: l } = s.data;
336
+ static listenForUpdates(t, e, n, r) {
337
+ const o = (i) => {
338
+ if (!i.data || typeof i.data != "object") return;
339
+ const { type: a, payload: s, text: l } = i.data;
322
340
  switch (a) {
323
341
  case "btp-copilot:set-context":
324
- o && t(o);
342
+ s && t(s);
325
343
  break;
326
344
  case "btp-copilot:send-message":
327
345
  l && e(l);
@@ -330,11 +348,11 @@ ${a.content}`).join(`
330
348
  n();
331
349
  break;
332
350
  case "btp-copilot:close":
333
- i();
351
+ r();
334
352
  break;
335
353
  }
336
354
  };
337
- return window.addEventListener("message", r), () => window.removeEventListener("message", r);
355
+ return window.addEventListener("message", o), () => window.removeEventListener("message", o);
338
356
  }
339
357
  }
340
358
  const v = `/* ── Host element ─────────────────────────────────────────────────────────── */
@@ -474,7 +492,7 @@ const v = `/* ── Host element ───────────────
474
492
  "theme",
475
493
  "token",
476
494
  "context-interval"
477
- ], _ = class _ extends HTMLElement {
495
+ ], y = class y extends HTMLElement {
478
496
  constructor() {
479
497
  super(...arguments), this._open = !1, this._isFullscreen = !1, this._iframeEl = null, this._contextTimer = null;
480
498
  }
@@ -499,9 +517,11 @@ const v = `/* ── Host element ───────────────
499
517
  this._open = !0, this.shadowRoot.querySelector(".panel").classList.remove("closed"), this.shadowRoot.querySelector(".toggle-btn").setAttribute("aria-expanded", "true"), this._clearBadge(), this._pushContextToIframe();
500
518
  }
501
519
  close() {
502
- this._open = !1;
520
+ this._open = !1, this._isFullscreen = !1;
503
521
  const t = this.shadowRoot.querySelector(".panel");
504
- t.classList.add("closed"), t.classList.remove("fullscreen"), this._isFullscreen = !1, this.shadowRoot.querySelector(".toggle-btn").setAttribute("aria-expanded", "false");
522
+ t.classList.add("closed"), t.classList.remove("fullscreen");
523
+ const e = this.shadowRoot.querySelector(".toggle-btn");
524
+ e.style.display = "", e.setAttribute("aria-expanded", "false");
505
525
  }
506
526
  _toggleFullscreen() {
507
527
  this._isFullscreen = !this._isFullscreen;
@@ -519,14 +539,14 @@ const v = `/* ── Host element ───────────────
519
539
  }
520
540
  // ── Shadow DOM ─────────────────────────────────────────────────────────────
521
541
  _buildShadow() {
522
- var i;
542
+ var r;
523
543
  const t = this.attachShadow({ mode: "open" }), e = document.createElement("style");
524
544
  e.textContent = v, t.appendChild(e);
525
545
  const n = document.createElement("div");
526
546
  for (n.innerHTML = this._template(); n.firstChild; ) t.appendChild(n.firstChild);
527
547
  t.querySelector(".toggle-btn").addEventListener("click", () => {
528
548
  this._open ? this.close() : this.open();
529
- }), this._iframeEl = t.querySelector(".chat-iframe"), (i = this._iframeEl) == null || i.addEventListener("load", () => {
549
+ }), this._iframeEl = t.querySelector(".chat-iframe"), (r = this._iframeEl) == null || r.addEventListener("load", () => {
530
550
  this._pushAuthToIframe(), this._pushContextToIframe();
531
551
  });
532
552
  }
@@ -571,8 +591,8 @@ const v = `/* ── Host element ───────────────
571
591
  const t = ((e = this._config) == null ? void 0 : e.iframeUrl) ?? "";
572
592
  if (!t) return "";
573
593
  try {
574
- const n = new URL(t), { appId: i, appName: r, serviceUrl: s } = this._config;
575
- i && n.searchParams.set("appId", i), r && n.searchParams.set("appName", r), s && n.searchParams.set("serviceUrl", s);
594
+ const n = new URL(t), { appId: r, appName: o, serviceUrl: i } = this._config;
595
+ r && n.searchParams.set("appId", r), o && n.searchParams.set("appName", o), i && n.searchParams.set("serviceUrl", i);
576
596
  const a = d.resolve(this._config.token);
577
597
  return a && n.searchParams.set("token", a), n.toString();
578
598
  } catch {
@@ -593,14 +613,14 @@ const v = `/* ── Host element ───────────────
593
613
  if (!((e = this._iframeEl) != null && e.contentWindow)) return;
594
614
  const t = this._iframeOrigin();
595
615
  this._config.autoContext ? g.captureAsync(this._buildBaseContext()).then((n) => {
596
- var i, r;
597
- (r = (i = this._iframeEl) == null ? void 0 : i.contentWindow) == null || r.postMessage(
616
+ var r, o;
617
+ (o = (r = this._iframeEl) == null ? void 0 : r.contentWindow) == null || o.postMessage(
598
618
  { type: "btp-copilot:set-context", payload: n },
599
619
  t
600
620
  ), n.service_url && !this._config.serviceUrl && (this._config = { ...this._config, serviceUrl: n.service_url });
601
621
  }).catch(() => {
602
- var n, i;
603
- (i = (n = this._iframeEl) == null ? void 0 : n.contentWindow) == null || i.postMessage(
622
+ var n, r;
623
+ (r = (n = this._iframeEl) == null ? void 0 : n.contentWindow) == null || r.postMessage(
604
624
  { type: "btp-copilot:set-context", payload: this._buildBaseContext() },
605
625
  t
606
626
  );
@@ -655,11 +675,11 @@ const v = `/* ── Host element ───────────────
655
675
  return t.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
656
676
  }
657
677
  };
658
- _.observedAttributes = [...x];
659
- let y = _;
660
- customElements.get("btp-copilot") || customElements.define("btp-copilot", y);
678
+ y.observedAttributes = [...x];
679
+ let _ = y;
680
+ customElements.get("btp-copilot") || customElements.define("btp-copilot", _);
661
681
  export {
662
- y as BtpCopilotElement,
682
+ _ as BtpCopilotElement,
663
683
  g as ContextBridge
664
684
  };
665
685
  //# sourceMappingURL=btp-copilot.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"btp-copilot.esm.js","sources":["../src/api/TokenManager.ts","../src/context/ShellProbe.ts","../src/context/UI5Probe.ts","../src/context/ODataProbe.ts","../src/context/ContextBridge.ts","../src/styles/widget.css?raw","../src/BtpCopilotElement.ts","../src/index.ts"],"sourcesContent":["export class TokenManager {\n private static readonly XSUAA_COOKIE_NAMES = [\n \"x-uaa-token\",\n \"xsuaa_token\",\n \"access_token\",\n \"X-Authorization\",\n ];\n\n static resolve(explicitToken?: string | null): string | null {\n if (explicitToken) return explicitToken.replace(/^Bearer\\s+/i, \"\");\n\n const windowToken = (window as any).__BTP_COPILOT_TOKEN__ as\n | string\n | undefined;\n if (windowToken) return windowToken.replace(/^Bearer\\s+/i, \"\");\n\n const cookieToken = TokenManager._fromCookie();\n if (cookieToken) return cookieToken;\n\n try {\n const lsToken = localStorage.getItem(\"access_token\");\n if (lsToken) return lsToken;\n } catch {}\n\n return null;\n }\n\n static getAuthHeader(token: string | null): Record<string, string> {\n return token ? { Authorization: `Bearer ${token}` } : {};\n }\n\n private static _fromCookie(): string | null {\n try {\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, ...rest] = cookie.trim().split(\"=\");\n if (TokenManager.XSUAA_COOKIE_NAMES.includes(name.trim())) {\n return decodeURIComponent(rest.join(\"=\").trim());\n }\n }\n } catch {}\n return null;\n }\n}\n","declare const sap: any;\n\nexport class ShellProbe {\n static getHash(): string {\n try {\n const nav = sap?.ushell?.Container?.getService?.(\n \"CrossApplicationNavigation\",\n );\n if (nav) {\n const href = nav.hrefForExternal?.() as string | undefined;\n if (href) return href;\n }\n } catch (err) {\n console.log(err);\n }\n return window.location.hash || \"\";\n }\n\n static getCurrentAppId(): string | null {\n try {\n const hash = ShellProbe.getHash();\n const match = hash.match(/^#([^&?/]+)/);\n return match ? match[1] : null;\n } catch {\n return null;\n }\n }\n\n static getUserLocale(): string {\n try {\n return (\n sap?.ui?.getCore?.()?.getConfiguration?.()?.getLanguageTag?.() ??\n navigator.language ??\n \"en\"\n );\n } catch {\n return navigator.language ?? \"en\";\n }\n }\n}\n","declare const sap: any;\n\nexport class UI5Probe {\n static getCurrentEntity(): Record<string, unknown> | null {\n try {\n const core = sap?.ui?.getCore?.();\n if (!core) return null;\n\n let el: Element | null = document.activeElement;\n while (el) {\n const id = el.getAttribute(\"id\") || el.getAttribute(\"data-sap-ui\");\n if (id) {\n const control = core.byId(id);\n const ctx = control?.getBindingContext?.();\n if (ctx) {\n const obj = ctx.getObject?.();\n if (obj && typeof obj === \"object\") {\n return UI5Probe._sanitize(obj as Record<string, unknown>);\n }\n }\n }\n el = el.parentElement;\n }\n return UI5Probe._scanAllControls(core);\n } catch {\n return null;\n }\n }\n\n private static _scanAllControls(core: any): Record<string, unknown> | null {\n try {\n const elements = core.mElements ?? {};\n for (const id of Object.keys(elements)) {\n const control = elements[id];\n const ctx = control?.getBindingContext?.();\n if (ctx) {\n const obj = ctx.getObject?.();\n if (obj && typeof obj === \"object\" && Object.keys(obj).length > 0) {\n return UI5Probe._sanitize(obj as Record<string, unknown>);\n }\n }\n }\n } catch {}\n return null;\n }\n\n static getServiceUrl(): string | null {\n try {\n const core = sap?.ui?.getCore?.();\n if (!core) return null;\n const elements = core.mElements ?? {};\n for (const id of Object.keys(elements)) {\n const control = elements[id];\n if (!control?.getModel) continue;\n const model = control.getModel();\n if (!model) continue;\n const url: unknown = model.sServiceUrl ?? (model as any)._sServiceUrl;\n if (typeof url === \"string\" && url.length > 4) {\n return url.replace(/\\/$/, \"\");\n }\n }\n } catch {}\n return null;\n }\n\n private static _sanitize(\n obj: Record<string, unknown>,\n ): Record<string, unknown> {\n const clean: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (k.startsWith(\"__\")) continue;\n if (v === null || typeof v !== \"object\") {\n clean[k] = v;\n } else if ((v as any).__deferred) {\n // navigation property stub — skip\n } else {\n clean[k] = v;\n }\n }\n return clean;\n }\n}\n","import type {\n EntitySchema,\n EntityProperty,\n NavProperty,\n AppDocument,\n} from \"../types\";\n\nexport class ODataProbe {\n private static _cache = new Map<string, AppDocument[]>();\n\n static async fetchSchemaDocuments(\n serviceUrl: string,\n token?: string | null,\n ): Promise<AppDocument[]> {\n const cacheKey = `btp-copilot-meta-${serviceUrl}`;\n\n if (ODataProbe._cache.has(cacheKey)) {\n return ODataProbe._cache.get(cacheKey)!;\n }\n\n const stored = sessionStorage.getItem(cacheKey);\n if (stored) {\n try {\n const docs = JSON.parse(stored) as AppDocument[];\n ODataProbe._cache.set(cacheKey, docs);\n return docs;\n } catch {}\n }\n\n try {\n const metaUrl = `${serviceUrl}/$metadata`;\n const headers: Record<string, string> = { Accept: \"application/xml\" };\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\n const resp = await fetch(metaUrl, { headers });\n if (!resp.ok) return [];\n\n const xml = await resp.text();\n const schemas = ODataProbe._parseEDMX(xml);\n const docs = ODataProbe._schemasToDocuments(schemas, serviceUrl);\n\n ODataProbe._cache.set(cacheKey, docs);\n sessionStorage.setItem(cacheKey, JSON.stringify(docs));\n return docs;\n } catch {\n return [];\n }\n }\n\n private static _parseEDMX(xml: string): EntitySchema[] {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, \"text/xml\");\n const entityTypes = doc.querySelectorAll(\"EntityType\");\n return Array.from(entityTypes).map((et) => {\n const name = et.getAttribute(\"Name\") ?? \"\";\n const keyRefs = et.querySelectorAll(\"Key > PropertyRef\");\n const keyNames = new Set(\n Array.from(keyRefs).map((k) => k.getAttribute(\"Name\") ?? \"\"),\n );\n const properties: EntityProperty[] = Array.from(\n et.querySelectorAll(\"Property\"),\n ).map((p) => ({\n name: p.getAttribute(\"Name\") ?? \"\",\n type: ODataProbe._shortType(p.getAttribute(\"Type\") ?? \"\"),\n isKey: keyNames.has(p.getAttribute(\"Name\") ?? \"\"),\n nullable: p.getAttribute(\"Nullable\") !== \"false\",\n }));\n const navProperties: NavProperty[] = Array.from(\n et.querySelectorAll(\"NavigationProperty\"),\n ).map((n) => ({\n name: n.getAttribute(\"Name\") ?? \"\",\n type: ODataProbe._shortType(\n n.getAttribute(\"Type\") ?? n.getAttribute(\"ToRole\") ?? \"\",\n ),\n }));\n return { name, properties, navProperties };\n });\n } catch {\n return [];\n }\n }\n\n private static _shortType(full: string): string {\n if (full.startsWith(\"Collection(\")) {\n const inner = full.slice(11, -1);\n return `${inner.split(\".\").pop()}[]`;\n }\n return full.split(\".\").pop() ?? full;\n }\n\n private static _schemasToDocuments(\n schemas: EntitySchema[],\n serviceUrl: string,\n ): AppDocument[] {\n const docs: AppDocument[] = [];\n\n for (const schema of schemas) {\n if (!schema.name) continue;\n const keyProps = schema.properties.filter((p) => p.isKey);\n const otherProps = schema.properties.filter((p) => !p.isKey);\n const lines = [\n `Entity: ${schema.name}`,\n `OData service: ${serviceUrl}`,\n `Entity set path: ${serviceUrl}/${schema.name}`,\n `Count path: ${serviceUrl}/${schema.name}/$count`,\n ];\n if (keyProps.length) {\n lines.push(\n `Key fields: ${keyProps.map((p) => `${p.name} (${p.type})`).join(\", \")}`,\n );\n }\n if (otherProps.length) {\n lines.push(\n `Fields: ${otherProps\n .map(\n (p) => `${p.name} (${p.type}${p.nullable ? \"\" : \", required\"})`,\n )\n .join(\", \")}`,\n );\n }\n if (schema.navProperties.length) {\n lines.push(\n `Navigation: ${schema.navProperties.map((n) => `${n.name} → ${n.type}`).join(\", \")}`,\n );\n }\n docs.push({\n title: `${schema.name} entity schema`,\n content: lines.join(\"\\n\"),\n });\n }\n\n if (schemas.length > 0) {\n docs.push({\n title: \"Available OData entity sets\",\n content: [\n `OData service: ${serviceUrl}`,\n `Entities: ${schemas.map((s) => s.name).join(\", \")}`,\n \"GET {entity}/$count | ?$filter=field eq 'value' | ?$top=10&$skip=0 | ?$orderby=field desc\",\n ].join(\"\\n\"),\n });\n }\n\n return docs;\n }\n\n static invalidate(serviceUrl: string) {\n const key = `btp-copilot-meta-${serviceUrl}`;\n ODataProbe._cache.delete(key);\n sessionStorage.removeItem(key);\n }\n}\n","import type { HostAppContext } from \"../types\";\nimport { ShellProbe } from \"./ShellProbe\";\nimport { UI5Probe } from \"./UI5Probe\";\nimport { ODataProbe } from \"./ODataProbe\";\n\nexport class ContextBridge {\n static capture(baseContext: HostAppContext): HostAppContext {\n const ctx: HostAppContext = { ...baseContext };\n\n try {\n const hash = ShellProbe.getHash();\n if (hash) ctx.current_view = hash;\n } catch {}\n\n try {\n const entity = UI5Probe.getCurrentEntity();\n if (entity && Object.keys(entity).length > 0) ctx.entity_data = entity;\n } catch {}\n\n try {\n if (!ctx.user_locale) ctx.user_locale = ShellProbe.getUserLocale();\n } catch {}\n\n // Merge any context injected by the host app\n try {\n const injected = (window as any).__APP_CONTEXT__ as\n | Partial<HostAppContext>\n | undefined;\n if (injected) {\n if (injected.entity_data)\n ctx.entity_data = { ...injected.entity_data, ...ctx.entity_data };\n if (injected.current_view && !ctx.current_view)\n ctx.current_view = injected.current_view;\n if (injected.extra)\n ctx.extra = { ...injected.extra, ...(ctx.extra ?? {}) };\n if (injected.service_url && !ctx.service_url)\n ctx.service_url = injected.service_url;\n }\n } catch {}\n\n return ctx;\n }\n\n static async captureAsync(\n baseContext: HostAppContext,\n ): Promise<HostAppContext> {\n const ctx = ContextBridge.capture(baseContext);\n\n if (!ctx.service_url) {\n ctx.service_url = ContextBridge._discoverServiceUrl() ?? undefined;\n }\n\n if (ctx.service_url) {\n try {\n const token = (ctx.extra as any)?.auth_token ?? null;\n const docs = await ODataProbe.fetchSchemaDocuments(\n ctx.service_url,\n token,\n );\n if (docs.length > 0) {\n const schemaHint = docs\n .map((d) => `## ${d.title}\\n${d.content}`)\n .join(\"\\n\\n\");\n ctx.extra = { ...(ctx.extra ?? {}), schema_hint: schemaHint };\n }\n } catch {}\n }\n\n return ctx;\n }\n\n private static _discoverServiceUrl(): string | null {\n try {\n const url = UI5Probe.getServiceUrl();\n if (url) return url;\n } catch {}\n\n try {\n const entries = performance.getEntriesByType(\n \"resource\",\n ) as PerformanceResourceTiming[];\n for (const e of entries) {\n const m = e.name.match(/^(https?:\\/\\/[^?#]+)\\/\\$metadata/);\n if (m) return m[1];\n }\n } catch {}\n\n try {\n const m = window.location.href.match(\n /(https?:\\/\\/[^/]+(?:\\/odata\\/v[24]\\/[^/?#]+|\\/sap\\/opu\\/odata\\/[^/?#]+))/,\n );\n if (m) return m[1];\n } catch {}\n\n return null;\n }\n\n static async discoverFromManifest(): Promise<string | null> {\n try {\n const resp = await fetch(\"/manifest.json\");\n if (!resp.ok) return null;\n const manifest = await resp.json();\n const sources: Record<string, any> =\n manifest?.[\"sap.app\"]?.dataSources ?? {};\n for (const key of Object.keys(sources)) {\n const src = sources[key];\n if (src?.type === \"ODataAnnotation\") continue;\n const uri: unknown = src?.uri;\n if (typeof uri === \"string\" && uri.length > 0) {\n return new URL(uri, window.location.href)\n .toString()\n .replace(/\\/$/, \"\");\n }\n }\n } catch {}\n return null;\n }\n\n static listenForUpdates(\n onContextUpdate: (ctx: Partial<HostAppContext>) => void,\n onMessage: (text: string) => void,\n onOpen: () => void,\n onClose: () => void,\n ): () => void {\n const handler = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== \"object\") return;\n const { type, payload, text } = event.data as {\n type?: string;\n payload?: Partial<HostAppContext>;\n text?: string;\n };\n switch (type) {\n case \"btp-copilot:set-context\":\n if (payload) onContextUpdate(payload);\n break;\n case \"btp-copilot:send-message\":\n if (text) onMessage(text);\n break;\n case \"btp-copilot:open\":\n onOpen();\n break;\n case \"btp-copilot:close\":\n onClose();\n break;\n }\n };\n window.addEventListener(\"message\", handler);\n return () => window.removeEventListener(\"message\", handler);\n }\n}\n","export default \"/* ── Host element ─────────────────────────────────────────────────────────── */\\n:host {\\n position: fixed;\\n z-index: 2147483647;\\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\\n}\\n\\n*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\\n\\n/* ── Toggle (FAB) button ─────────────────────────────────────────────────── */\\n.toggle-btn {\\n position: fixed;\\n bottom: 1.25rem;\\n width: 3.25rem;\\n height: 3.25rem;\\n border-radius: 50%;\\n border: none;\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\\n color: #fff;\\n box-shadow: 0 4px 14px rgba(102, 126, 234, 0.45);\\n z-index: 2147483647;\\n transition: transform 0.2s ease, box-shadow 0.2s ease;\\n outline: none;\\n}\\n\\n.toggle-btn.bottom-right { right: 1.25rem; }\\n.toggle-btn.bottom-left { left: 1.25rem; }\\n\\n.toggle-btn:hover {\\n transform: scale(1.08);\\n box-shadow: 0 6px 20px rgba(102, 126, 234, 0.55);\\n}\\n.toggle-btn:active { transform: scale(0.95); }\\n.toggle-btn:focus-visible { outline: 3px solid #60a5fa; outline-offset: 2px; }\\n\\n.toggle-btn[aria-expanded=\\\"false\\\"] .icon-close { display: none; }\\n.toggle-btn[aria-expanded=\\\"true\\\"] .icon-chat { display: none; }\\n.toggle-btn svg { width: 1.375rem; height: 1.375rem; pointer-events: none; }\\n\\n/* Unread-message badge */\\n.badge {\\n position: absolute;\\n top: 0.125rem;\\n right: 0.125rem;\\n width: 0.625rem;\\n height: 0.625rem;\\n border-radius: 50%;\\n background: #ef4444;\\n border: 2px solid #fff;\\n opacity: 0;\\n transform: scale(0);\\n transition: opacity 0.2s ease, transform 0.2s ease;\\n}\\n.badge.visible { opacity: 1; transform: scale(1); }\\n\\n/* ── Chat panel ──────────────────────────────────────────────────────────── */\\n.panel {\\n position: fixed;\\n bottom: 5.5rem;\\n width: 26rem;\\n height: 70vh;\\n min-height: 25rem;\\n max-height: 47.5rem;\\n background: transparent;\\n border-radius: 1rem;\\n box-shadow: 0 8px 40px rgba(0, 0, 0, 0.22), 0 0 0 1px rgba(0, 0, 0, 0.06);\\n z-index: 2147483646;\\n overflow: hidden;\\n display: flex;\\n flex-direction: column;\\n transform-origin: bottom center;\\n transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.34, 1.3, 0.64, 1),\\n width 0.3s cubic-bezier(0.4, 0, 0.2, 1), height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\\n bottom 0.3s cubic-bezier(0.4, 0, 0.2, 1), border-radius 0.3s ease;\\n}\\n\\n.panel.bottom-right { right: 1.25rem; }\\n.panel.bottom-left { left: 1.25rem; }\\n\\n.panel.closed {\\n opacity: 0;\\n pointer-events: none;\\n transform: translateY(0.5rem) scale(0.97);\\n}\\n\\n/* Fullscreen mode */\\n.panel.fullscreen {\\n width: 100vw !important;\\n height: 100vh !important;\\n height: 100dvh !important;\\n bottom: 0 !important;\\n right: 0 !important;\\n left: 0 !important;\\n border-radius: 0 !important;\\n max-height: none !important;\\n}\\n\\n.panel.fullscreen .chat-iframe {\\n border-radius: 0 !important;\\n}\\n\\n/* Iframe fills the entire panel */\\n.chat-iframe {\\n width: 100%;\\n height: 100%;\\n border: none;\\n border-radius: 1rem;\\n display: block;\\n background: #fff;\\n}\\n\\n/* ── Mobile: full-screen ─────────────────────────────────────────────────── */\\n@media (max-width: 30rem) {\\n .panel {\\n width: 100vw;\\n height: 85dvh;\\n bottom: 0;\\n right: 0 !important;\\n left: 0 !important;\\n border-radius: 1rem 1rem 0 0;\\n }\\n .chat-iframe { border-radius: 1rem 1rem 0 0; }\\n}\\n\"","/**\n * BtpCopilotElement — <btp-copilot> Custom Element.\n *\n * Renders a fixed floating FAB button. When opened, shows your deployed\n * BTP Copilot React chatbot in an iframe. Context from the host UI5/Fiori\n * app is auto-captured and forwarded into the iframe via postMessage so the\n * chatbot is always aware of what the user is looking at.\n *\n * Attributes:\n * iframe-url Full URL of the deployed React chatbot frontend (required)\n * app-id Stable identifier of the host application (required)\n * app-name Human-readable app name\n * service-url OData service URL for context auto-capture\n * auto-context \"true\"|\"false\" — auto-capture UI5/OData context (default: true)\n * position \"bottom-right\"|\"bottom-left\" (default: bottom-right)\n * theme \"auto\"|\"light\"|\"dark\" (default: auto)\n * token Bearer token forwarded to the chatbot iframe\n * context-interval Context re-capture interval in ms (default: 3000)\n *\n * postMessage protocol (outgoing → iframe):\n * { type: 'btp-copilot:set-context', payload: HostAppContext }\n * { type: 'btp-copilot:auth', token: string }\n *\n * postMessage protocol (incoming ← iframe or host page):\n * { type: 'btp-copilot:close' }\n * { type: 'btp-copilot:open' }\n */\n\nimport type { HostAppContext, WidgetConfig } from \"./types\";\nimport { TokenManager } from \"./api/TokenManager\";\nimport { ContextBridge } from \"./context/ContextBridge\";\nimport widgetCss from \"./styles/widget.css?raw\";\n\nconst OBSERVED = [\n \"iframe-url\",\n \"app-id\",\n \"app-name\",\n \"service-url\",\n \"auto-context\",\n \"position\",\n \"theme\",\n \"token\",\n \"context-interval\",\n] as const;\n\nexport class BtpCopilotElement extends HTMLElement {\n static observedAttributes = [...OBSERVED];\n\n private _config!: WidgetConfig;\n private _open = false;\n private _isFullscreen = false;\n private _iframeEl: HTMLIFrameElement | null = null;\n private _contextTimer: ReturnType<typeof setInterval> | null = null;\n private _removeMessageListener?: () => void;\n\n connectedCallback() {\n this._config = this._readConfig();\n this._buildShadow();\n this._startContextPolling();\n\n const msgHandler = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== \"object\") return;\n const { type } = event.data as { type?: string };\n if (type === \"btp-copilot:close\") this.close();\n if (type === \"btp-copilot:open\") this.open();\n if (type === \"btp-copilot:fullscreen\") this._toggleFullscreen();\n if (type === \"btp-copilot:minimize\") this.close();\n };\n window.addEventListener(\"message\", msgHandler);\n this._removeMessageListener = () =>\n window.removeEventListener(\"message\", msgHandler);\n }\n\n disconnectedCallback() {\n this._removeMessageListener?.();\n this._stopContextPolling();\n }\n\n attributeChangedCallback(\n _name: string,\n old: string | null,\n next: string | null\n ) {\n if (old === next || !this.isConnected) return;\n this._config = this._readConfig();\n this._updateAfterAttributeChange();\n }\n\n // ── Public API ─────────────────────────────────────────────────────────────\n open() {\n this._open = true;\n this.shadowRoot!.querySelector(\".panel\")!.classList.remove(\"closed\");\n this.shadowRoot!\n .querySelector(\".toggle-btn\")!\n .setAttribute(\"aria-expanded\", \"true\");\n this._clearBadge();\n this._pushContextToIframe();\n }\n\n close() {\n this._open = false;\n const panel = this.shadowRoot!.querySelector(\".panel\")!;\n panel.classList.add(\"closed\");\n panel.classList.remove(\"fullscreen\");\n this._isFullscreen = false;\n this.shadowRoot!\n .querySelector(\".toggle-btn\")!\n .setAttribute(\"aria-expanded\", \"false\");\n }\n\n private _toggleFullscreen() {\n this._isFullscreen = !this._isFullscreen;\n const panel = this.shadowRoot!.querySelector(\".panel\")!;\n const fab = this.shadowRoot!.querySelector(\".toggle-btn\") as HTMLElement;\n if (this._isFullscreen) {\n panel.classList.add(\"fullscreen\");\n fab.style.display = \"none\";\n } else {\n panel.classList.remove(\"fullscreen\");\n fab.style.display = \"\";\n }\n }\n\n sendMessage(text: string) {\n if (!this._open) this.open();\n setTimeout(() => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:send-message\", text },\n \"*\"\n );\n }, 100);\n }\n\n // ── Shadow DOM ─────────────────────────────────────────────────────────────\n private _buildShadow() {\n const shadow = this.attachShadow({ mode: \"open\" });\n\n const styleEl = document.createElement(\"style\");\n styleEl.textContent = widgetCss;\n shadow.appendChild(styleEl);\n\n const wrapper = document.createElement(\"div\");\n wrapper.innerHTML = this._template();\n while (wrapper.firstChild) shadow.appendChild(wrapper.firstChild);\n\n shadow.querySelector(\".toggle-btn\")!.addEventListener(\"click\", () => {\n this._open ? this.close() : this.open();\n });\n\n this._iframeEl = shadow.querySelector(\".chat-iframe\");\n\n this._iframeEl?.addEventListener(\"load\", () => {\n this._pushAuthToIframe();\n this._pushContextToIframe();\n });\n }\n\n private _template(): string {\n const pos = this._config?.position ?? \"bottom-right\";\n const src = this._esc(this._buildIframeUrl());\n return `\n<button class=\"toggle-btn ${pos}\" aria-label=\"Open AI assistant\" aria-expanded=\"false\" aria-haspopup=\"dialog\">\n <svg class=\"icon-chat\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>\n </svg>\n <svg class=\"icon-close\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n <span class=\"badge\" aria-hidden=\"true\"></span>\n</button>\n\n<div class=\"panel closed ${pos}\" role=\"dialog\" aria-label=\"AI Assistant\" aria-modal=\"true\">\n <iframe\n class=\"chat-iframe\"\n src=\"${src}\"\n title=\"AI Assistant\"\n allow=\"clipboard-read; clipboard-write\"\n loading=\"lazy\">\n </iframe>\n</div>`;\n }\n\n // ── Context + Auth ─────────────────────────────────────────────────────────\n private _buildBaseContext(): HostAppContext {\n const token = TokenManager.resolve(this._config.token);\n return {\n app_id: this._config.appId,\n app_name: this._config.appName,\n service_url: this._config.serviceUrl,\n // Include the resolved auth token in extra so the backend can\n // proxy OData calls on behalf of the user to fetch real data\n ...(token ? { extra: { auth_token: token } } : {}),\n };\n }\n\n private _buildIframeUrl(): string {\n const base = this._config?.iframeUrl ?? \"\";\n if (!base) return \"\";\n try {\n const url = new URL(base);\n const { appId, appName, serviceUrl } = this._config;\n if (appId) url.searchParams.set(\"appId\", appId);\n if (appName) url.searchParams.set(\"appName\", appName);\n if (serviceUrl) url.searchParams.set(\"serviceUrl\", serviceUrl);\n // Pass token as URL param so the chatbot can auto-authenticate in iframe mode\n const token = TokenManager.resolve(this._config.token);\n if (token) url.searchParams.set(\"token\", token);\n return url.toString();\n } catch {\n return base;\n }\n }\n\n /** Derive the allowed postMessage target origin from the configured iframe URL.\n * Falls back to \"*\" only when the URL cannot be parsed (e.g. empty string). */\n private _iframeOrigin(): string {\n try {\n return new URL(this._config.iframeUrl).origin;\n } catch {\n return \"*\";\n }\n }\n\n private _pushContextToIframe() {\n if (!this._iframeEl?.contentWindow) return;\n const origin = this._iframeOrigin();\n\n if (this._config.autoContext) {\n ContextBridge.captureAsync(this._buildBaseContext())\n .then((ctx) => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:set-context\", payload: ctx },\n origin\n );\n if (ctx.service_url && !this._config.serviceUrl) {\n this._config = { ...this._config, serviceUrl: ctx.service_url };\n }\n })\n .catch(() => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:set-context\", payload: this._buildBaseContext() },\n origin\n );\n });\n } else {\n this._iframeEl.contentWindow.postMessage(\n { type: \"btp-copilot:set-context\", payload: this._buildBaseContext() },\n origin\n );\n }\n }\n\n private _pushAuthToIframe() {\n const token = TokenManager.resolve(this._config.token);\n if (!token || !this._iframeEl?.contentWindow) return;\n this._iframeEl.contentWindow.postMessage(\n { type: \"btp-copilot:auth\", token },\n this._iframeOrigin()\n );\n }\n\n private _startContextPolling() {\n if (!this._config.autoContext) return;\n this._contextTimer = setInterval(() => {\n if (this._open) this._pushContextToIframe();\n }, this._config.contextInterval);\n }\n\n private _stopContextPolling() {\n if (this._contextTimer !== null) {\n clearInterval(this._contextTimer);\n this._contextTimer = null;\n }\n }\n\n // ── Config ─────────────────────────────────────────────────────────────────\n private _readConfig(): WidgetConfig {\n const get = (attr: string) => this.getAttribute(attr);\n return {\n iframeUrl: get(\"iframe-url\") ?? \"\",\n appId: get(\"app-id\") ?? \"default\",\n appName: get(\"app-name\") ?? undefined,\n serviceUrl: get(\"service-url\") ?? undefined,\n autoContext: get(\"auto-context\") !== \"false\",\n position: (get(\"position\") ?? \"bottom-right\") as WidgetConfig[\"position\"],\n theme: (get(\"theme\") ?? \"auto\") as WidgetConfig[\"theme\"],\n token: get(\"token\") ?? undefined,\n contextInterval: Math.max(500, Number(get(\"context-interval\")) || 3000),\n };\n }\n\n private _updateAfterAttributeChange() {\n const style = this.shadowRoot?.querySelector(\"style\");\n if (style) style.textContent = widgetCss;\n\n const newSrc = this._buildIframeUrl();\n if (this._iframeEl && this._iframeEl.src !== newSrc && newSrc) {\n this._iframeEl.src = newSrc;\n }\n\n this._stopContextPolling();\n this._startContextPolling();\n }\n\n private _clearBadge() {\n this.shadowRoot?.querySelector(\".badge\")?.classList.remove(\"visible\");\n }\n\n private _esc(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n }\n}\n","import { BtpCopilotElement } from \"./BtpCopilotElement\";\n\nif (!customElements.get(\"btp-copilot\")) {\n customElements.define(\"btp-copilot\", BtpCopilotElement);\n}\n\nexport { BtpCopilotElement };\nexport type { HostAppContext, WidgetConfig, AppDocument } from \"./types\";\nexport { ContextBridge } from \"./context/ContextBridge\";\n"],"names":["_TokenManager","explicitToken","windowToken","cookieToken","lsToken","token","cookies","cookie","name","rest","TokenManager","ShellProbe","_a","_b","_c","_d","nav","href","err","match","_e","_f","UI5Probe","core","el","id","control","ctx","obj","elements","model","url","clean","k","v","_ODataProbe","serviceUrl","cacheKey","stored","docs","metaUrl","headers","resp","xml","schemas","entityTypes","et","keyRefs","keyNames","properties","p","navProperties","n","full","schema","keyProps","otherProps","lines","s","key","ODataProbe","ContextBridge","baseContext","hash","entity","injected","schemaHint","d","entries","m","manifest","sources","src","uri","onContextUpdate","onMessage","onOpen","onClose","handler","event","type","payload","text","widgetCss","OBSERVED","_BtpCopilotElement","msgHandler","_name","old","next","panel","fab","shadow","styleEl","wrapper","pos","base","appId","appName","origin","get","attr","style","newSrc","BtpCopilotElement"],"mappings":"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"}
1
+ {"version":3,"file":"btp-copilot.esm.js","sources":["../src/api/TokenManager.ts","../src/context/ShellProbe.ts","../src/context/UI5Probe.ts","../src/context/ODataProbe.ts","../src/context/ContextBridge.ts","../src/styles/widget.css?raw","../src/BtpCopilotElement.ts","../src/index.ts"],"sourcesContent":["export class TokenManager {\n private static readonly XSUAA_COOKIE_NAMES = [\n \"x-uaa-token\",\n \"xsuaa_token\",\n \"access_token\",\n \"X-Authorization\",\n ];\n\n static resolve(explicitToken?: string | null): string | null {\n if (explicitToken) return explicitToken.replace(/^Bearer\\s+/i, \"\");\n\n const windowToken = (window as any).__BTP_COPILOT_TOKEN__ as\n | string\n | undefined;\n if (windowToken) return windowToken.replace(/^Bearer\\s+/i, \"\");\n\n const cookieToken = TokenManager._fromCookie();\n if (cookieToken) return cookieToken;\n\n try {\n const lsToken = localStorage.getItem(\"access_token\");\n if (lsToken) return lsToken;\n } catch {}\n\n return null;\n }\n\n static getAuthHeader(token: string | null): Record<string, string> {\n return token ? { Authorization: `Bearer ${token}` } : {};\n }\n\n private static _fromCookie(): string | null {\n try {\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, ...rest] = cookie.trim().split(\"=\");\n if (TokenManager.XSUAA_COOKIE_NAMES.includes(name.trim())) {\n return decodeURIComponent(rest.join(\"=\").trim());\n }\n }\n } catch {}\n return null;\n }\n}\n","declare const sap: any;\n\nexport class ShellProbe {\n static getHash(): string {\n try {\n const nav = sap?.ushell?.Container?.getService?.(\n \"CrossApplicationNavigation\",\n );\n if (nav) {\n const href = nav.hrefForExternal?.() as string | undefined;\n if (href) return href;\n }\n } catch (err) {\n console.log(err);\n }\n return window.location.hash || \"\";\n }\n\n static getCurrentAppId(): string | null {\n try {\n const hash = ShellProbe.getHash();\n const match = hash.match(/^#([^&?/]+)/);\n return match ? match[1] : null;\n } catch {\n return null;\n }\n }\n\n static getUserLocale(): string {\n try {\n return (\n sap?.ui?.getCore?.()?.getConfiguration?.()?.getLanguageTag?.() ??\n navigator.language ??\n \"en\"\n );\n } catch {\n return navigator.language ?? \"en\";\n }\n }\n}\n","declare const sap: any;\n\nexport class UI5Probe {\n static getCurrentEntity(): Record<string, unknown> | null {\n try {\n const core = sap?.ui?.getCore?.();\n if (!core) return null;\n\n let el: Element | null = document.activeElement;\n while (el) {\n const id = el.getAttribute(\"id\") || el.getAttribute(\"data-sap-ui\");\n if (id) {\n const control = core.byId(id);\n const ctx = control?.getBindingContext?.();\n if (ctx) {\n const obj = ctx.getObject?.();\n if (obj && typeof obj === \"object\") {\n return UI5Probe._sanitize(obj as Record<string, unknown>);\n }\n }\n }\n el = el.parentElement;\n }\n return UI5Probe._scanAllControls(core);\n } catch {\n return null;\n }\n }\n\n private static _scanAllControls(core: any): Record<string, unknown> | null {\n try {\n const elements = core.mElements ?? {};\n for (const id of Object.keys(elements)) {\n const control = elements[id];\n const ctx = control?.getBindingContext?.();\n if (ctx) {\n const obj = ctx.getObject?.();\n if (obj && typeof obj === \"object\" && Object.keys(obj).length > 0) {\n return UI5Probe._sanitize(obj as Record<string, unknown>);\n }\n }\n }\n } catch {}\n return null;\n }\n\n static getServiceUrl(): string | null {\n try {\n const core = sap?.ui?.getCore?.();\n if (!core) return null;\n const elements = core.mElements ?? {};\n for (const id of Object.keys(elements)) {\n const control = elements[id];\n if (!control?.getModel) continue;\n const model = control.getModel();\n if (!model) continue;\n const url: unknown = model.sServiceUrl ?? (model as any)._sServiceUrl;\n if (typeof url === \"string\" && url.length > 4) {\n return url.replace(/\\/$/, \"\");\n }\n }\n } catch {}\n return null;\n }\n\n private static _sanitize(\n obj: Record<string, unknown>,\n ): Record<string, unknown> {\n const clean: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (k.startsWith(\"__\")) continue;\n if (v === null || typeof v !== \"object\") {\n clean[k] = v;\n } else if ((v as any).__deferred) {\n // navigation property stub — skip\n } else {\n clean[k] = v;\n }\n }\n return clean;\n }\n}\n","import type {\n EntitySchema,\n EntityProperty,\n NavProperty,\n AppDocument,\n} from \"../types\";\n\nexport class ODataProbe {\n private static _cache = new Map<string, AppDocument[]>();\n\n static async fetchSchemaDocuments(\n serviceUrl: string,\n token?: string | null,\n ): Promise<AppDocument[]> {\n const cacheKey = `btp-copilot-meta-${serviceUrl}`;\n\n if (ODataProbe._cache.has(cacheKey)) {\n return ODataProbe._cache.get(cacheKey)!;\n }\n\n const stored = sessionStorage.getItem(cacheKey);\n if (stored) {\n try {\n const docs = JSON.parse(stored) as AppDocument[];\n ODataProbe._cache.set(cacheKey, docs);\n return docs;\n } catch {}\n }\n\n try {\n const metaUrl = `${serviceUrl}/$metadata`;\n const headers: Record<string, string> = { Accept: \"application/xml\" };\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\n const resp = await fetch(metaUrl, { headers });\n if (!resp.ok) return [];\n\n const xml = await resp.text();\n const schemas = ODataProbe._parseEDMX(xml);\n const docs = ODataProbe._schemasToDocuments(schemas, serviceUrl);\n\n ODataProbe._cache.set(cacheKey, docs);\n sessionStorage.setItem(cacheKey, JSON.stringify(docs));\n return docs;\n } catch {\n return [];\n }\n }\n\n private static _parseEDMX(xml: string): EntitySchema[] {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, \"text/xml\");\n const entityTypes = doc.querySelectorAll(\"EntityType\");\n return Array.from(entityTypes).map((et) => {\n const name = et.getAttribute(\"Name\") ?? \"\";\n const keyRefs = et.querySelectorAll(\"Key > PropertyRef\");\n const keyNames = new Set(\n Array.from(keyRefs).map((k) => k.getAttribute(\"Name\") ?? \"\"),\n );\n const properties: EntityProperty[] = Array.from(\n et.querySelectorAll(\"Property\"),\n ).map((p) => ({\n name: p.getAttribute(\"Name\") ?? \"\",\n type: ODataProbe._shortType(p.getAttribute(\"Type\") ?? \"\"),\n isKey: keyNames.has(p.getAttribute(\"Name\") ?? \"\"),\n nullable: p.getAttribute(\"Nullable\") !== \"false\",\n }));\n const navProperties: NavProperty[] = Array.from(\n et.querySelectorAll(\"NavigationProperty\"),\n ).map((n) => ({\n name: n.getAttribute(\"Name\") ?? \"\",\n type: ODataProbe._shortType(\n n.getAttribute(\"Type\") ?? n.getAttribute(\"ToRole\") ?? \"\",\n ),\n }));\n return { name, properties, navProperties };\n });\n } catch {\n return [];\n }\n }\n\n private static _shortType(full: string): string {\n if (full.startsWith(\"Collection(\")) {\n const inner = full.slice(11, -1);\n return `${inner.split(\".\").pop()}[]`;\n }\n return full.split(\".\").pop() ?? full;\n }\n\n private static _schemasToDocuments(\n schemas: EntitySchema[],\n serviceUrl: string,\n ): AppDocument[] {\n const docs: AppDocument[] = [];\n\n for (const schema of schemas) {\n if (!schema.name) continue;\n const keyProps = schema.properties.filter((p) => p.isKey);\n const otherProps = schema.properties.filter((p) => !p.isKey);\n const lines = [\n `Entity: ${schema.name}`,\n `OData service: ${serviceUrl}`,\n `Entity set path: ${serviceUrl}/${schema.name}`,\n `Count path: ${serviceUrl}/${schema.name}/$count`,\n ];\n if (keyProps.length) {\n lines.push(\n `Key fields: ${keyProps.map((p) => `${p.name} (${p.type})`).join(\", \")}`,\n );\n }\n if (otherProps.length) {\n lines.push(\n `Fields: ${otherProps\n .map(\n (p) => `${p.name} (${p.type}${p.nullable ? \"\" : \", required\"})`,\n )\n .join(\", \")}`,\n );\n }\n if (schema.navProperties.length) {\n lines.push(\n `Navigation: ${schema.navProperties.map((n) => `${n.name} → ${n.type}`).join(\", \")}`,\n );\n }\n docs.push({\n title: `${schema.name} entity schema`,\n content: lines.join(\"\\n\"),\n });\n }\n\n if (schemas.length > 0) {\n docs.push({\n title: \"Available OData entity sets\",\n content: [\n `OData service: ${serviceUrl}`,\n `Entities: ${schemas.map((s) => s.name).join(\", \")}`,\n \"GET {entity}/$count | ?$filter=field eq 'value' | ?$top=10&$skip=0 | ?$orderby=field desc\",\n ].join(\"\\n\"),\n });\n }\n\n return docs;\n }\n\n static invalidate(serviceUrl: string) {\n const key = `btp-copilot-meta-${serviceUrl}`;\n ODataProbe._cache.delete(key);\n sessionStorage.removeItem(key);\n }\n}\n","import type { HostAppContext } from \"../types\";\nimport { ShellProbe } from \"./ShellProbe\";\nimport { UI5Probe } from \"./UI5Probe\";\nimport { ODataProbe } from \"./ODataProbe\";\n\nexport class ContextBridge {\n static capture(baseContext: HostAppContext): HostAppContext {\n const ctx: HostAppContext = { ...baseContext };\n\n // ── SAP-specific probes (no-ops on non-SAP apps) ──────────────────────────\n try {\n const hash = ShellProbe.getHash();\n if (hash) ctx.current_view = hash;\n } catch {}\n\n try {\n const entity = UI5Probe.getCurrentEntity();\n if (entity && Object.keys(entity).length > 0) ctx.entity_data = entity;\n } catch {}\n\n try {\n if (!ctx.user_locale) ctx.user_locale = ShellProbe.getUserLocale();\n } catch {}\n\n // ── Generic web context (works for any app) ───────────────────────────────\n // current_view: full path + search + hash (more useful than hash alone)\n try {\n const fullPath =\n window.location.pathname +\n window.location.search +\n window.location.hash;\n if (!ctx.current_view || ctx.current_view === \"\") {\n ctx.current_view = fullPath;\n }\n } catch {}\n\n // locale fallback\n try {\n if (!ctx.user_locale) {\n ctx.user_locale =\n navigator.language || (navigator as any).languages?.[0] || \"en\";\n }\n } catch {}\n\n // page_title and page_url give the LLM meaningful screen context\n try {\n ctx.extra = {\n ...(ctx.extra ?? {}),\n page_title:\n (ctx.extra as any)?.page_title ?? document.title ?? \"\",\n page_url:\n (ctx.extra as any)?.page_url ?? window.location.href ?? \"\",\n };\n } catch {}\n\n // ── Host-app injected context (highest priority) ──────────────────────────\n try {\n const injected = (window as any).__APP_CONTEXT__ as\n | Partial<HostAppContext>\n | undefined;\n if (injected) {\n if (injected.entity_data)\n ctx.entity_data = { ...injected.entity_data, ...ctx.entity_data };\n if (injected.current_view && !ctx.current_view)\n ctx.current_view = injected.current_view;\n if (injected.extra)\n ctx.extra = { ...injected.extra, ...(ctx.extra ?? {}) };\n if (injected.service_url && !ctx.service_url)\n ctx.service_url = injected.service_url;\n }\n } catch {}\n\n return ctx;\n }\n\n static async captureAsync(\n baseContext: HostAppContext,\n ): Promise<HostAppContext> {\n const ctx = ContextBridge.capture(baseContext);\n\n if (!ctx.service_url) {\n ctx.service_url = ContextBridge._discoverServiceUrl() ?? undefined;\n }\n\n if (ctx.service_url) {\n try {\n const token = (ctx.extra as any)?.auth_token ?? null;\n const docs = await ODataProbe.fetchSchemaDocuments(\n ctx.service_url,\n token,\n );\n if (docs.length > 0) {\n const schemaHint = docs\n .map((d) => `## ${d.title}\\n${d.content}`)\n .join(\"\\n\\n\");\n ctx.extra = { ...(ctx.extra ?? {}), schema_hint: schemaHint };\n }\n } catch {}\n }\n\n return ctx;\n }\n\n private static _discoverServiceUrl(): string | null {\n try {\n const url = UI5Probe.getServiceUrl();\n if (url) return url;\n } catch {}\n\n try {\n const entries = performance.getEntriesByType(\n \"resource\",\n ) as PerformanceResourceTiming[];\n for (const e of entries) {\n const m = e.name.match(/^(https?:\\/\\/[^?#]+)\\/\\$metadata/);\n if (m) return m[1];\n }\n } catch {}\n\n try {\n const m = window.location.href.match(\n /(https?:\\/\\/[^/]+(?:\\/odata\\/v[24]\\/[^/?#]+|\\/sap\\/opu\\/odata\\/[^/?#]+))/,\n );\n if (m) return m[1];\n } catch {}\n\n return null;\n }\n\n static async discoverFromManifest(): Promise<string | null> {\n try {\n const resp = await fetch(\"/manifest.json\");\n if (!resp.ok) return null;\n const manifest = await resp.json();\n const sources: Record<string, any> =\n manifest?.[\"sap.app\"]?.dataSources ?? {};\n for (const key of Object.keys(sources)) {\n const src = sources[key];\n if (src?.type === \"ODataAnnotation\") continue;\n const uri: unknown = src?.uri;\n if (typeof uri === \"string\" && uri.length > 0) {\n return new URL(uri, window.location.href)\n .toString()\n .replace(/\\/$/, \"\");\n }\n }\n } catch {}\n return null;\n }\n\n static listenForUpdates(\n onContextUpdate: (ctx: Partial<HostAppContext>) => void,\n onMessage: (text: string) => void,\n onOpen: () => void,\n onClose: () => void,\n ): () => void {\n const handler = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== \"object\") return;\n const { type, payload, text } = event.data as {\n type?: string;\n payload?: Partial<HostAppContext>;\n text?: string;\n };\n switch (type) {\n case \"btp-copilot:set-context\":\n if (payload) onContextUpdate(payload);\n break;\n case \"btp-copilot:send-message\":\n if (text) onMessage(text);\n break;\n case \"btp-copilot:open\":\n onOpen();\n break;\n case \"btp-copilot:close\":\n onClose();\n break;\n }\n };\n window.addEventListener(\"message\", handler);\n return () => window.removeEventListener(\"message\", handler);\n }\n}\n","export default \"/* ── Host element ─────────────────────────────────────────────────────────── */\\n:host {\\n position: fixed;\\n z-index: 2147483647;\\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\\n}\\n\\n*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\\n\\n/* ── Toggle (FAB) button ─────────────────────────────────────────────────── */\\n.toggle-btn {\\n position: fixed;\\n bottom: 1.25rem;\\n width: 3.25rem;\\n height: 3.25rem;\\n border-radius: 50%;\\n border: none;\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\\n color: #fff;\\n box-shadow: 0 4px 14px rgba(102, 126, 234, 0.45);\\n z-index: 2147483647;\\n transition: transform 0.2s ease, box-shadow 0.2s ease;\\n outline: none;\\n}\\n\\n.toggle-btn.bottom-right { right: 1.25rem; }\\n.toggle-btn.bottom-left { left: 1.25rem; }\\n\\n.toggle-btn:hover {\\n transform: scale(1.08);\\n box-shadow: 0 6px 20px rgba(102, 126, 234, 0.55);\\n}\\n.toggle-btn:active { transform: scale(0.95); }\\n.toggle-btn:focus-visible { outline: 3px solid #60a5fa; outline-offset: 2px; }\\n\\n.toggle-btn[aria-expanded=\\\"false\\\"] .icon-close { display: none; }\\n.toggle-btn[aria-expanded=\\\"true\\\"] .icon-chat { display: none; }\\n.toggle-btn svg { width: 1.375rem; height: 1.375rem; pointer-events: none; }\\n\\n/* Unread-message badge */\\n.badge {\\n position: absolute;\\n top: 0.125rem;\\n right: 0.125rem;\\n width: 0.625rem;\\n height: 0.625rem;\\n border-radius: 50%;\\n background: #ef4444;\\n border: 2px solid #fff;\\n opacity: 0;\\n transform: scale(0);\\n transition: opacity 0.2s ease, transform 0.2s ease;\\n}\\n.badge.visible { opacity: 1; transform: scale(1); }\\n\\n/* ── Chat panel ──────────────────────────────────────────────────────────── */\\n.panel {\\n position: fixed;\\n bottom: 5.5rem;\\n width: 26rem;\\n height: 70vh;\\n min-height: 25rem;\\n max-height: 47.5rem;\\n background: transparent;\\n border-radius: 1rem;\\n box-shadow: 0 8px 40px rgba(0, 0, 0, 0.22), 0 0 0 1px rgba(0, 0, 0, 0.06);\\n z-index: 2147483646;\\n overflow: hidden;\\n display: flex;\\n flex-direction: column;\\n transform-origin: bottom center;\\n transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.34, 1.3, 0.64, 1),\\n width 0.3s cubic-bezier(0.4, 0, 0.2, 1), height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\\n bottom 0.3s cubic-bezier(0.4, 0, 0.2, 1), border-radius 0.3s ease;\\n}\\n\\n.panel.bottom-right { right: 1.25rem; }\\n.panel.bottom-left { left: 1.25rem; }\\n\\n.panel.closed {\\n opacity: 0;\\n pointer-events: none;\\n transform: translateY(0.5rem) scale(0.97);\\n}\\n\\n/* Fullscreen mode */\\n.panel.fullscreen {\\n width: 100vw !important;\\n height: 100vh !important;\\n height: 100dvh !important;\\n bottom: 0 !important;\\n right: 0 !important;\\n left: 0 !important;\\n border-radius: 0 !important;\\n max-height: none !important;\\n}\\n\\n.panel.fullscreen .chat-iframe {\\n border-radius: 0 !important;\\n}\\n\\n/* Iframe fills the entire panel */\\n.chat-iframe {\\n width: 100%;\\n height: 100%;\\n border: none;\\n border-radius: 1rem;\\n display: block;\\n background: #fff;\\n}\\n\\n/* ── Mobile: full-screen ─────────────────────────────────────────────────── */\\n@media (max-width: 30rem) {\\n .panel {\\n width: 100vw;\\n height: 85dvh;\\n bottom: 0;\\n right: 0 !important;\\n left: 0 !important;\\n border-radius: 1rem 1rem 0 0;\\n }\\n .chat-iframe { border-radius: 1rem 1rem 0 0; }\\n}\\n\"","/**\n * BtpCopilotElement — <btp-copilot> Custom Element.\n *\n * Renders a fixed floating FAB button. When opened, shows your deployed\n * BTP Copilot React chatbot in an iframe. Context from the host UI5/Fiori\n * app is auto-captured and forwarded into the iframe via postMessage so the\n * chatbot is always aware of what the user is looking at.\n *\n * Attributes:\n * iframe-url Full URL of the deployed React chatbot frontend (required)\n * app-id Stable identifier of the host application (required)\n * app-name Human-readable app name\n * service-url OData service URL for context auto-capture\n * auto-context \"true\"|\"false\" — auto-capture UI5/OData context (default: true)\n * position \"bottom-right\"|\"bottom-left\" (default: bottom-right)\n * theme \"auto\"|\"light\"|\"dark\" (default: auto)\n * token Bearer token forwarded to the chatbot iframe\n * context-interval Context re-capture interval in ms (default: 3000)\n *\n * postMessage protocol (outgoing → iframe):\n * { type: 'btp-copilot:set-context', payload: HostAppContext }\n * { type: 'btp-copilot:auth', token: string }\n *\n * postMessage protocol (incoming ← iframe or host page):\n * { type: 'btp-copilot:close' }\n * { type: 'btp-copilot:open' }\n */\n\nimport type { HostAppContext, WidgetConfig } from \"./types\";\nimport { TokenManager } from \"./api/TokenManager\";\nimport { ContextBridge } from \"./context/ContextBridge\";\nimport widgetCss from \"./styles/widget.css?raw\";\n\nconst OBSERVED = [\n \"iframe-url\",\n \"app-id\",\n \"app-name\",\n \"service-url\",\n \"auto-context\",\n \"position\",\n \"theme\",\n \"token\",\n \"context-interval\",\n] as const;\n\nexport class BtpCopilotElement extends HTMLElement {\n static observedAttributes = [...OBSERVED];\n\n private _config!: WidgetConfig;\n private _open = false;\n private _isFullscreen = false;\n private _iframeEl: HTMLIFrameElement | null = null;\n private _contextTimer: ReturnType<typeof setInterval> | null = null;\n private _removeMessageListener?: () => void;\n\n connectedCallback() {\n this._config = this._readConfig();\n this._buildShadow();\n this._startContextPolling();\n\n const msgHandler = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== \"object\") return;\n const { type } = event.data as { type?: string };\n if (type === \"btp-copilot:close\") this.close();\n if (type === \"btp-copilot:open\") this.open();\n if (type === \"btp-copilot:fullscreen\") this._toggleFullscreen();\n if (type === \"btp-copilot:minimize\") this.close();\n };\n window.addEventListener(\"message\", msgHandler);\n this._removeMessageListener = () =>\n window.removeEventListener(\"message\", msgHandler);\n }\n\n disconnectedCallback() {\n this._removeMessageListener?.();\n this._stopContextPolling();\n }\n\n attributeChangedCallback(\n _name: string,\n old: string | null,\n next: string | null\n ) {\n if (old === next || !this.isConnected) return;\n this._config = this._readConfig();\n this._updateAfterAttributeChange();\n }\n\n // ── Public API ─────────────────────────────────────────────────────────────\n open() {\n this._open = true;\n this.shadowRoot!.querySelector(\".panel\")!.classList.remove(\"closed\");\n this.shadowRoot!\n .querySelector(\".toggle-btn\")!\n .setAttribute(\"aria-expanded\", \"true\");\n this._clearBadge();\n this._pushContextToIframe();\n }\n\n close() {\n this._open = false;\n this._isFullscreen = false;\n const panel = this.shadowRoot!.querySelector(\".panel\")!;\n panel.classList.add(\"closed\");\n panel.classList.remove(\"fullscreen\");\n const fab = this.shadowRoot!.querySelector(\".toggle-btn\") as HTMLElement;\n fab.style.display = \"\"; // always restore FAB — covers minimize-from-fullscreen\n fab.setAttribute(\"aria-expanded\", \"false\");\n }\n\n private _toggleFullscreen() {\n this._isFullscreen = !this._isFullscreen;\n const panel = this.shadowRoot!.querySelector(\".panel\")!;\n const fab = this.shadowRoot!.querySelector(\".toggle-btn\") as HTMLElement;\n if (this._isFullscreen) {\n panel.classList.add(\"fullscreen\");\n fab.style.display = \"none\";\n } else {\n panel.classList.remove(\"fullscreen\");\n fab.style.display = \"\";\n }\n }\n\n sendMessage(text: string) {\n if (!this._open) this.open();\n setTimeout(() => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:send-message\", text },\n \"*\"\n );\n }, 100);\n }\n\n // ── Shadow DOM ─────────────────────────────────────────────────────────────\n private _buildShadow() {\n const shadow = this.attachShadow({ mode: \"open\" });\n\n const styleEl = document.createElement(\"style\");\n styleEl.textContent = widgetCss;\n shadow.appendChild(styleEl);\n\n const wrapper = document.createElement(\"div\");\n wrapper.innerHTML = this._template();\n while (wrapper.firstChild) shadow.appendChild(wrapper.firstChild);\n\n shadow.querySelector(\".toggle-btn\")!.addEventListener(\"click\", () => {\n this._open ? this.close() : this.open();\n });\n\n this._iframeEl = shadow.querySelector(\".chat-iframe\");\n\n this._iframeEl?.addEventListener(\"load\", () => {\n this._pushAuthToIframe();\n this._pushContextToIframe();\n });\n }\n\n private _template(): string {\n const pos = this._config?.position ?? \"bottom-right\";\n const src = this._esc(this._buildIframeUrl());\n return `\n<button class=\"toggle-btn ${pos}\" aria-label=\"Open AI assistant\" aria-expanded=\"false\" aria-haspopup=\"dialog\">\n <svg class=\"icon-chat\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>\n </svg>\n <svg class=\"icon-close\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n <span class=\"badge\" aria-hidden=\"true\"></span>\n</button>\n\n<div class=\"panel closed ${pos}\" role=\"dialog\" aria-label=\"AI Assistant\" aria-modal=\"true\">\n <iframe\n class=\"chat-iframe\"\n src=\"${src}\"\n title=\"AI Assistant\"\n allow=\"clipboard-read; clipboard-write\"\n loading=\"lazy\">\n </iframe>\n</div>`;\n }\n\n // ── Context + Auth ─────────────────────────────────────────────────────────\n private _buildBaseContext(): HostAppContext {\n const token = TokenManager.resolve(this._config.token);\n return {\n app_id: this._config.appId,\n app_name: this._config.appName,\n service_url: this._config.serviceUrl,\n // Include the resolved auth token in extra so the backend can\n // proxy OData calls on behalf of the user to fetch real data\n ...(token ? { extra: { auth_token: token } } : {}),\n };\n }\n\n private _buildIframeUrl(): string {\n const base = this._config?.iframeUrl ?? \"\";\n if (!base) return \"\";\n try {\n const url = new URL(base);\n const { appId, appName, serviceUrl } = this._config;\n if (appId) url.searchParams.set(\"appId\", appId);\n if (appName) url.searchParams.set(\"appName\", appName);\n if (serviceUrl) url.searchParams.set(\"serviceUrl\", serviceUrl);\n // Pass token as URL param so the chatbot can auto-authenticate in iframe mode\n const token = TokenManager.resolve(this._config.token);\n if (token) url.searchParams.set(\"token\", token);\n return url.toString();\n } catch {\n return base;\n }\n }\n\n /** Derive the allowed postMessage target origin from the configured iframe URL.\n * Falls back to \"*\" only when the URL cannot be parsed (e.g. empty string). */\n private _iframeOrigin(): string {\n try {\n return new URL(this._config.iframeUrl).origin;\n } catch {\n return \"*\";\n }\n }\n\n private _pushContextToIframe() {\n if (!this._iframeEl?.contentWindow) return;\n const origin = this._iframeOrigin();\n\n if (this._config.autoContext) {\n ContextBridge.captureAsync(this._buildBaseContext())\n .then((ctx) => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:set-context\", payload: ctx },\n origin\n );\n if (ctx.service_url && !this._config.serviceUrl) {\n this._config = { ...this._config, serviceUrl: ctx.service_url };\n }\n })\n .catch(() => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:set-context\", payload: this._buildBaseContext() },\n origin\n );\n });\n } else {\n this._iframeEl.contentWindow.postMessage(\n { type: \"btp-copilot:set-context\", payload: this._buildBaseContext() },\n origin\n );\n }\n }\n\n private _pushAuthToIframe() {\n const token = TokenManager.resolve(this._config.token);\n if (!token || !this._iframeEl?.contentWindow) return;\n this._iframeEl.contentWindow.postMessage(\n { type: \"btp-copilot:auth\", token },\n this._iframeOrigin()\n );\n }\n\n private _startContextPolling() {\n if (!this._config.autoContext) return;\n this._contextTimer = setInterval(() => {\n if (this._open) this._pushContextToIframe();\n }, this._config.contextInterval);\n }\n\n private _stopContextPolling() {\n if (this._contextTimer !== null) {\n clearInterval(this._contextTimer);\n this._contextTimer = null;\n }\n }\n\n // ── Config ─────────────────────────────────────────────────────────────────\n private _readConfig(): WidgetConfig {\n const get = (attr: string) => this.getAttribute(attr);\n return {\n iframeUrl: get(\"iframe-url\") ?? \"\",\n appId: get(\"app-id\") ?? \"default\",\n appName: get(\"app-name\") ?? undefined,\n serviceUrl: get(\"service-url\") ?? undefined,\n autoContext: get(\"auto-context\") !== \"false\",\n position: (get(\"position\") ?? \"bottom-right\") as WidgetConfig[\"position\"],\n theme: (get(\"theme\") ?? \"auto\") as WidgetConfig[\"theme\"],\n token: get(\"token\") ?? undefined,\n contextInterval: Math.max(500, Number(get(\"context-interval\")) || 3000),\n };\n }\n\n private _updateAfterAttributeChange() {\n const style = this.shadowRoot?.querySelector(\"style\");\n if (style) style.textContent = widgetCss;\n\n const newSrc = this._buildIframeUrl();\n if (this._iframeEl && this._iframeEl.src !== newSrc && newSrc) {\n this._iframeEl.src = newSrc;\n }\n\n this._stopContextPolling();\n this._startContextPolling();\n }\n\n private _clearBadge() {\n this.shadowRoot?.querySelector(\".badge\")?.classList.remove(\"visible\");\n }\n\n private _esc(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n }\n}\n","import { BtpCopilotElement } from \"./BtpCopilotElement\";\n\nif (!customElements.get(\"btp-copilot\")) {\n customElements.define(\"btp-copilot\", BtpCopilotElement);\n}\n\nexport { BtpCopilotElement };\nexport type { HostAppContext, WidgetConfig, AppDocument } from \"./types\";\nexport { ContextBridge } from \"./context/ContextBridge\";\n"],"names":["_TokenManager","explicitToken","windowToken","cookieToken","lsToken","token","cookies","cookie","name","rest","TokenManager","ShellProbe","_a","_b","_c","_d","nav","href","err","match","_e","_f","UI5Probe","core","el","id","control","ctx","obj","elements","model","url","clean","k","v","_ODataProbe","serviceUrl","cacheKey","stored","docs","metaUrl","headers","resp","xml","schemas","entityTypes","et","keyRefs","keyNames","properties","p","navProperties","n","full","schema","keyProps","otherProps","lines","s","key","ODataProbe","ContextBridge","baseContext","hash","entity","fullPath","injected","schemaHint","d","entries","m","manifest","sources","src","uri","onContextUpdate","onMessage","onOpen","onClose","handler","event","type","payload","text","widgetCss","OBSERVED","_BtpCopilotElement","msgHandler","_name","old","next","panel","fab","shadow","styleEl","wrapper","pos","base","appId","appName","origin","get","attr","style","newSrc","BtpCopilotElement"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- var BtpCopilot=function(g){"use strict";const m=class m{static resolve(t){if(t)return t.replace(/^Bearer\s+/i,"");const e=window.__BTP_COPILOT_TOKEN__;if(e)return e.replace(/^Bearer\s+/i,"");const n=m._fromCookie();if(n)return n;try{const i=localStorage.getItem("access_token");if(i)return i}catch{}return null}static getAuthHeader(t){return t?{Authorization:`Bearer ${t}`}:{}}static _fromCookie(){try{const t=document.cookie.split(";");for(const e of t){const[n,...i]=e.trim().split("=");if(m.XSUAA_COOKIE_NAMES.includes(n.trim()))return decodeURIComponent(i.join("=").trim())}}catch{}return null}};m.XSUAA_COOKIE_NAMES=["x-uaa-token","xsuaa_token","access_token","X-Authorization"];let d=m;class b{static getHash(){var t,e,n,i;try{const r=(n=(e=(t=sap==null?void 0:sap.ushell)==null?void 0:t.Container)==null?void 0:e.getService)==null?void 0:n.call(e,"CrossApplicationNavigation");if(r){const o=(i=r.hrefForExternal)==null?void 0:i.call(r);if(o)return o}}catch(r){console.log(r)}return window.location.hash||""}static getCurrentAppId(){try{const e=b.getHash().match(/^#([^&?/]+)/);return e?e[1]:null}catch{return null}}static getUserLocale(){var t,e,n,i,r,o;try{return((o=(r=(i=(n=(e=(t=sap==null?void 0:sap.ui)==null?void 0:t.getCore)==null?void 0:e.call(t))==null?void 0:n.getConfiguration)==null?void 0:i.call(n))==null?void 0:r.getLanguageTag)==null?void 0:o.call(r))??navigator.language??"en"}catch{return navigator.language??"en"}}}class u{static getCurrentEntity(){var t,e,n,i;try{const r=(e=(t=sap==null?void 0:sap.ui)==null?void 0:t.getCore)==null?void 0:e.call(t);if(!r)return null;let o=document.activeElement;for(;o;){const a=o.getAttribute("id")||o.getAttribute("data-sap-ui");if(a){const s=r.byId(a),l=(n=s==null?void 0:s.getBindingContext)==null?void 0:n.call(s);if(l){const p=(i=l.getObject)==null?void 0:i.call(l);if(p&&typeof p=="object")return u._sanitize(p)}}o=o.parentElement}return u._scanAllControls(r)}catch{return null}}static _scanAllControls(t){var e,n;try{const i=t.mElements??{};for(const r of Object.keys(i)){const o=i[r],a=(e=o==null?void 0:o.getBindingContext)==null?void 0:e.call(o);if(a){const s=(n=a.getObject)==null?void 0:n.call(a);if(s&&typeof s=="object"&&Object.keys(s).length>0)return u._sanitize(s)}}}catch{}return null}static getServiceUrl(){var t,e;try{const n=(e=(t=sap==null?void 0:sap.ui)==null?void 0:t.getCore)==null?void 0:e.call(t);if(!n)return null;const i=n.mElements??{};for(const r of Object.keys(i)){const o=i[r];if(!(o!=null&&o.getModel))continue;const a=o.getModel();if(!a)continue;const s=a.sServiceUrl??a._sServiceUrl;if(typeof s=="string"&&s.length>4)return s.replace(/\/$/,"")}}catch{}return null}static _sanitize(t){const e={};for(const[n,i]of Object.entries(t))n.startsWith("__")||(i===null||typeof i!="object"?e[n]=i:i.__deferred||(e[n]=i));return e}}const c=class c{static async fetchSchemaDocuments(t,e){const n=`btp-copilot-meta-${t}`;if(c._cache.has(n))return c._cache.get(n);const i=sessionStorage.getItem(n);if(i)try{const r=JSON.parse(i);return c._cache.set(n,r),r}catch{}try{const r=`${t}/$metadata`,o={Accept:"application/xml"};e&&(o.Authorization=`Bearer ${e}`);const a=await fetch(r,{headers:o});if(!a.ok)return[];const s=await a.text(),l=c._parseEDMX(s),p=c._schemasToDocuments(l,t);return c._cache.set(n,p),sessionStorage.setItem(n,JSON.stringify(p)),p}catch{return[]}}static _parseEDMX(t){try{const i=new DOMParser().parseFromString(t,"text/xml").querySelectorAll("EntityType");return Array.from(i).map(r=>{const o=r.getAttribute("Name")??"",a=r.querySelectorAll("Key > PropertyRef"),s=new Set(Array.from(a).map(h=>h.getAttribute("Name")??"")),l=Array.from(r.querySelectorAll("Property")).map(h=>({name:h.getAttribute("Name")??"",type:c._shortType(h.getAttribute("Type")??""),isKey:s.has(h.getAttribute("Name")??""),nullable:h.getAttribute("Nullable")!=="false"})),p=Array.from(r.querySelectorAll("NavigationProperty")).map(h=>({name:h.getAttribute("Name")??"",type:c._shortType(h.getAttribute("Type")??h.getAttribute("ToRole")??"")}));return{name:o,properties:l,navProperties:p}})}catch{return[]}}static _shortType(t){return t.startsWith("Collection(")?`${t.slice(11,-1).split(".").pop()}[]`:t.split(".").pop()??t}static _schemasToDocuments(t,e){const n=[];for(const i of t){if(!i.name)continue;const r=i.properties.filter(s=>s.isKey),o=i.properties.filter(s=>!s.isKey),a=[`Entity: ${i.name}`,`OData service: ${e}`,`Entity set path: ${e}/${i.name}`,`Count path: ${e}/${i.name}/$count`];r.length&&a.push(`Key fields: ${r.map(s=>`${s.name} (${s.type})`).join(", ")}`),o.length&&a.push(`Fields: ${o.map(s=>`${s.name} (${s.type}${s.nullable?"":", required"})`).join(", ")}`),i.navProperties.length&&a.push(`Navigation: ${i.navProperties.map(s=>`${s.name} → ${s.type}`).join(", ")}`),n.push({title:`${i.name} entity schema`,content:a.join(`
2
- `)})}return t.length>0&&n.push({title:"Available OData entity sets",content:[`OData service: ${e}`,`Entities: ${t.map(i=>i.name).join(", ")}`,"GET {entity}/$count | ?$filter=field eq 'value' | ?$top=10&$skip=0 | ?$orderby=field desc"].join(`
3
- `)}),n}static invalidate(t){const e=`btp-copilot-meta-${t}`;c._cache.delete(e),sessionStorage.removeItem(e)}};c._cache=new Map;let _=c;class f{static capture(t){const e={...t};try{const n=b.getHash();n&&(e.current_view=n)}catch{}try{const n=u.getCurrentEntity();n&&Object.keys(n).length>0&&(e.entity_data=n)}catch{}try{e.user_locale||(e.user_locale=b.getUserLocale())}catch{}try{const n=window.__APP_CONTEXT__;n&&(n.entity_data&&(e.entity_data={...n.entity_data,...e.entity_data}),n.current_view&&!e.current_view&&(e.current_view=n.current_view),n.extra&&(e.extra={...n.extra,...e.extra??{}}),n.service_url&&!e.service_url&&(e.service_url=n.service_url))}catch{}return e}static async captureAsync(t){var n;const e=f.capture(t);if(e.service_url||(e.service_url=f._discoverServiceUrl()??void 0),e.service_url)try{const i=((n=e.extra)==null?void 0:n.auth_token)??null,r=await _.fetchSchemaDocuments(e.service_url,i);if(r.length>0){const o=r.map(a=>`## ${a.title}
1
+ var BtpCopilot=function(g){"use strict";const m=class m{static resolve(t){if(t)return t.replace(/^Bearer\s+/i,"");const e=window.__BTP_COPILOT_TOKEN__;if(e)return e.replace(/^Bearer\s+/i,"");const n=m._fromCookie();if(n)return n;try{const r=localStorage.getItem("access_token");if(r)return r}catch{}return null}static getAuthHeader(t){return t?{Authorization:`Bearer ${t}`}:{}}static _fromCookie(){try{const t=document.cookie.split(";");for(const e of t){const[n,...r]=e.trim().split("=");if(m.XSUAA_COOKIE_NAMES.includes(n.trim()))return decodeURIComponent(r.join("=").trim())}}catch{}return null}};m.XSUAA_COOKIE_NAMES=["x-uaa-token","xsuaa_token","access_token","X-Authorization"];let d=m;class b{static getHash(){var t,e,n,r;try{const o=(n=(e=(t=sap==null?void 0:sap.ushell)==null?void 0:t.Container)==null?void 0:e.getService)==null?void 0:n.call(e,"CrossApplicationNavigation");if(o){const i=(r=o.hrefForExternal)==null?void 0:r.call(o);if(i)return i}}catch(o){console.log(o)}return window.location.hash||""}static getCurrentAppId(){try{const e=b.getHash().match(/^#([^&?/]+)/);return e?e[1]:null}catch{return null}}static getUserLocale(){var t,e,n,r,o,i;try{return((i=(o=(r=(n=(e=(t=sap==null?void 0:sap.ui)==null?void 0:t.getCore)==null?void 0:e.call(t))==null?void 0:n.getConfiguration)==null?void 0:r.call(n))==null?void 0:o.getLanguageTag)==null?void 0:i.call(o))??navigator.language??"en"}catch{return navigator.language??"en"}}}class u{static getCurrentEntity(){var t,e,n,r;try{const o=(e=(t=sap==null?void 0:sap.ui)==null?void 0:t.getCore)==null?void 0:e.call(t);if(!o)return null;let i=document.activeElement;for(;i;){const a=i.getAttribute("id")||i.getAttribute("data-sap-ui");if(a){const s=o.byId(a),l=(n=s==null?void 0:s.getBindingContext)==null?void 0:n.call(s);if(l){const p=(r=l.getObject)==null?void 0:r.call(l);if(p&&typeof p=="object")return u._sanitize(p)}}i=i.parentElement}return u._scanAllControls(o)}catch{return null}}static _scanAllControls(t){var e,n;try{const r=t.mElements??{};for(const o of Object.keys(r)){const i=r[o],a=(e=i==null?void 0:i.getBindingContext)==null?void 0:e.call(i);if(a){const s=(n=a.getObject)==null?void 0:n.call(a);if(s&&typeof s=="object"&&Object.keys(s).length>0)return u._sanitize(s)}}}catch{}return null}static getServiceUrl(){var t,e;try{const n=(e=(t=sap==null?void 0:sap.ui)==null?void 0:t.getCore)==null?void 0:e.call(t);if(!n)return null;const r=n.mElements??{};for(const o of Object.keys(r)){const i=r[o];if(!(i!=null&&i.getModel))continue;const a=i.getModel();if(!a)continue;const s=a.sServiceUrl??a._sServiceUrl;if(typeof s=="string"&&s.length>4)return s.replace(/\/$/,"")}}catch{}return null}static _sanitize(t){const e={};for(const[n,r]of Object.entries(t))n.startsWith("__")||(r===null||typeof r!="object"?e[n]=r:r.__deferred||(e[n]=r));return e}}const c=class c{static async fetchSchemaDocuments(t,e){const n=`btp-copilot-meta-${t}`;if(c._cache.has(n))return c._cache.get(n);const r=sessionStorage.getItem(n);if(r)try{const o=JSON.parse(r);return c._cache.set(n,o),o}catch{}try{const o=`${t}/$metadata`,i={Accept:"application/xml"};e&&(i.Authorization=`Bearer ${e}`);const a=await fetch(o,{headers:i});if(!a.ok)return[];const s=await a.text(),l=c._parseEDMX(s),p=c._schemasToDocuments(l,t);return c._cache.set(n,p),sessionStorage.setItem(n,JSON.stringify(p)),p}catch{return[]}}static _parseEDMX(t){try{const r=new DOMParser().parseFromString(t,"text/xml").querySelectorAll("EntityType");return Array.from(r).map(o=>{const i=o.getAttribute("Name")??"",a=o.querySelectorAll("Key > PropertyRef"),s=new Set(Array.from(a).map(h=>h.getAttribute("Name")??"")),l=Array.from(o.querySelectorAll("Property")).map(h=>({name:h.getAttribute("Name")??"",type:c._shortType(h.getAttribute("Type")??""),isKey:s.has(h.getAttribute("Name")??""),nullable:h.getAttribute("Nullable")!=="false"})),p=Array.from(o.querySelectorAll("NavigationProperty")).map(h=>({name:h.getAttribute("Name")??"",type:c._shortType(h.getAttribute("Type")??h.getAttribute("ToRole")??"")}));return{name:i,properties:l,navProperties:p}})}catch{return[]}}static _shortType(t){return t.startsWith("Collection(")?`${t.slice(11,-1).split(".").pop()}[]`:t.split(".").pop()??t}static _schemasToDocuments(t,e){const n=[];for(const r of t){if(!r.name)continue;const o=r.properties.filter(s=>s.isKey),i=r.properties.filter(s=>!s.isKey),a=[`Entity: ${r.name}`,`OData service: ${e}`,`Entity set path: ${e}/${r.name}`,`Count path: ${e}/${r.name}/$count`];o.length&&a.push(`Key fields: ${o.map(s=>`${s.name} (${s.type})`).join(", ")}`),i.length&&a.push(`Fields: ${i.map(s=>`${s.name} (${s.type}${s.nullable?"":", required"})`).join(", ")}`),r.navProperties.length&&a.push(`Navigation: ${r.navProperties.map(s=>`${s.name} → ${s.type}`).join(", ")}`),n.push({title:`${r.name} entity schema`,content:a.join(`
2
+ `)})}return t.length>0&&n.push({title:"Available OData entity sets",content:[`OData service: ${e}`,`Entities: ${t.map(r=>r.name).join(", ")}`,"GET {entity}/$count | ?$filter=field eq 'value' | ?$top=10&$skip=0 | ?$orderby=field desc"].join(`
3
+ `)}),n}static invalidate(t){const e=`btp-copilot-meta-${t}`;c._cache.delete(e),sessionStorage.removeItem(e)}};c._cache=new Map;let _=c;class f{static capture(t){var n,r,o;const e={...t};try{const i=b.getHash();i&&(e.current_view=i)}catch{}try{const i=u.getCurrentEntity();i&&Object.keys(i).length>0&&(e.entity_data=i)}catch{}try{e.user_locale||(e.user_locale=b.getUserLocale())}catch{}try{const i=window.location.pathname+window.location.search+window.location.hash;(!e.current_view||e.current_view==="")&&(e.current_view=i)}catch{}try{e.user_locale||(e.user_locale=navigator.language||((n=navigator.languages)==null?void 0:n[0])||"en")}catch{}try{e.extra={...e.extra??{},page_title:((r=e.extra)==null?void 0:r.page_title)??document.title??"",page_url:((o=e.extra)==null?void 0:o.page_url)??window.location.href??""}}catch{}try{const i=window.__APP_CONTEXT__;i&&(i.entity_data&&(e.entity_data={...i.entity_data,...e.entity_data}),i.current_view&&!e.current_view&&(e.current_view=i.current_view),i.extra&&(e.extra={...i.extra,...e.extra??{}}),i.service_url&&!e.service_url&&(e.service_url=i.service_url))}catch{}return e}static async captureAsync(t){var n;const e=f.capture(t);if(e.service_url||(e.service_url=f._discoverServiceUrl()??void 0),e.service_url)try{const r=((n=e.extra)==null?void 0:n.auth_token)??null,o=await _.fetchSchemaDocuments(e.service_url,r);if(o.length>0){const i=o.map(a=>`## ${a.title}
4
4
  ${a.content}`).join(`
5
5
 
6
- `);e.extra={...e.extra??{},schema_hint:o}}}catch{}return e}static _discoverServiceUrl(){try{const t=u.getServiceUrl();if(t)return t}catch{}try{const t=performance.getEntriesByType("resource");for(const e of t){const n=e.name.match(/^(https?:\/\/[^?#]+)\/\$metadata/);if(n)return n[1]}}catch{}try{const t=window.location.href.match(/(https?:\/\/[^/]+(?:\/odata\/v[24]\/[^/?#]+|\/sap\/opu\/odata\/[^/?#]+))/);if(t)return t[1]}catch{}return null}static async discoverFromManifest(){var t;try{const e=await fetch("/manifest.json");if(!e.ok)return null;const n=await e.json(),i=((t=n==null?void 0:n["sap.app"])==null?void 0:t.dataSources)??{};for(const r of Object.keys(i)){const o=i[r];if((o==null?void 0:o.type)==="ODataAnnotation")continue;const a=o==null?void 0:o.uri;if(typeof a=="string"&&a.length>0)return new URL(a,window.location.href).toString().replace(/\/$/,"")}}catch{}return null}static listenForUpdates(t,e,n,i){const r=o=>{if(!o.data||typeof o.data!="object")return;const{type:a,payload:s,text:l}=o.data;switch(a){case"btp-copilot:set-context":s&&t(s);break;case"btp-copilot:send-message":l&&e(l);break;case"btp-copilot:open":n();break;case"btp-copilot:close":i();break}};return window.addEventListener("message",r),()=>window.removeEventListener("message",r)}}const x=`/* ── Host element ─────────────────────────────────────────────────────────── */
6
+ `);e.extra={...e.extra??{},schema_hint:i}}}catch{}return e}static _discoverServiceUrl(){try{const t=u.getServiceUrl();if(t)return t}catch{}try{const t=performance.getEntriesByType("resource");for(const e of t){const n=e.name.match(/^(https?:\/\/[^?#]+)\/\$metadata/);if(n)return n[1]}}catch{}try{const t=window.location.href.match(/(https?:\/\/[^/]+(?:\/odata\/v[24]\/[^/?#]+|\/sap\/opu\/odata\/[^/?#]+))/);if(t)return t[1]}catch{}return null}static async discoverFromManifest(){var t;try{const e=await fetch("/manifest.json");if(!e.ok)return null;const n=await e.json(),r=((t=n==null?void 0:n["sap.app"])==null?void 0:t.dataSources)??{};for(const o of Object.keys(r)){const i=r[o];if((i==null?void 0:i.type)==="ODataAnnotation")continue;const a=i==null?void 0:i.uri;if(typeof a=="string"&&a.length>0)return new URL(a,window.location.href).toString().replace(/\/$/,"")}}catch{}return null}static listenForUpdates(t,e,n,r){const o=i=>{if(!i.data||typeof i.data!="object")return;const{type:a,payload:s,text:l}=i.data;switch(a){case"btp-copilot:set-context":s&&t(s);break;case"btp-copilot:send-message":l&&e(l);break;case"btp-copilot:open":n();break;case"btp-copilot:close":r();break}};return window.addEventListener("message",o),()=>window.removeEventListener("message",o)}}const w=`/* ── Host element ─────────────────────────────────────────────────────────── */
7
7
  :host {
8
8
  position: fixed;
9
9
  z-index: 2147483647;
@@ -130,7 +130,7 @@ ${a.content}`).join(`
130
130
  }
131
131
  .chat-iframe { border-radius: 1rem 1rem 0 0; }
132
132
  }
133
- `,w=["iframe-url","app-id","app-name","service-url","auto-context","position","theme","token","context-interval"],v=class v extends HTMLElement{constructor(){super(...arguments),this._open=!1,this._isFullscreen=!1,this._iframeEl=null,this._contextTimer=null}connectedCallback(){this._config=this._readConfig(),this._buildShadow(),this._startContextPolling();const t=e=>{if(!e.data||typeof e.data!="object")return;const{type:n}=e.data;n==="btp-copilot:close"&&this.close(),n==="btp-copilot:open"&&this.open(),n==="btp-copilot:fullscreen"&&this._toggleFullscreen(),n==="btp-copilot:minimize"&&this.close()};window.addEventListener("message",t),this._removeMessageListener=()=>window.removeEventListener("message",t)}disconnectedCallback(){var t;(t=this._removeMessageListener)==null||t.call(this),this._stopContextPolling()}attributeChangedCallback(t,e,n){e===n||!this.isConnected||(this._config=this._readConfig(),this._updateAfterAttributeChange())}open(){this._open=!0,this.shadowRoot.querySelector(".panel").classList.remove("closed"),this.shadowRoot.querySelector(".toggle-btn").setAttribute("aria-expanded","true"),this._clearBadge(),this._pushContextToIframe()}close(){this._open=!1;const t=this.shadowRoot.querySelector(".panel");t.classList.add("closed"),t.classList.remove("fullscreen"),this._isFullscreen=!1,this.shadowRoot.querySelector(".toggle-btn").setAttribute("aria-expanded","false")}_toggleFullscreen(){this._isFullscreen=!this._isFullscreen;const t=this.shadowRoot.querySelector(".panel"),e=this.shadowRoot.querySelector(".toggle-btn");this._isFullscreen?(t.classList.add("fullscreen"),e.style.display="none"):(t.classList.remove("fullscreen"),e.style.display="")}sendMessage(t){this._open||this.open(),setTimeout(()=>{var e,n;(n=(e=this._iframeEl)==null?void 0:e.contentWindow)==null||n.postMessage({type:"btp-copilot:send-message",text:t},"*")},100)}_buildShadow(){var i;const t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=x,t.appendChild(e);const n=document.createElement("div");for(n.innerHTML=this._template();n.firstChild;)t.appendChild(n.firstChild);t.querySelector(".toggle-btn").addEventListener("click",()=>{this._open?this.close():this.open()}),this._iframeEl=t.querySelector(".chat-iframe"),(i=this._iframeEl)==null||i.addEventListener("load",()=>{this._pushAuthToIframe(),this._pushContextToIframe()})}_template(){var n;const t=((n=this._config)==null?void 0:n.position)??"bottom-right",e=this._esc(this._buildIframeUrl());return`
133
+ `,x=["iframe-url","app-id","app-name","service-url","auto-context","position","theme","token","context-interval"],v=class v extends HTMLElement{constructor(){super(...arguments),this._open=!1,this._isFullscreen=!1,this._iframeEl=null,this._contextTimer=null}connectedCallback(){this._config=this._readConfig(),this._buildShadow(),this._startContextPolling();const t=e=>{if(!e.data||typeof e.data!="object")return;const{type:n}=e.data;n==="btp-copilot:close"&&this.close(),n==="btp-copilot:open"&&this.open(),n==="btp-copilot:fullscreen"&&this._toggleFullscreen(),n==="btp-copilot:minimize"&&this.close()};window.addEventListener("message",t),this._removeMessageListener=()=>window.removeEventListener("message",t)}disconnectedCallback(){var t;(t=this._removeMessageListener)==null||t.call(this),this._stopContextPolling()}attributeChangedCallback(t,e,n){e===n||!this.isConnected||(this._config=this._readConfig(),this._updateAfterAttributeChange())}open(){this._open=!0,this.shadowRoot.querySelector(".panel").classList.remove("closed"),this.shadowRoot.querySelector(".toggle-btn").setAttribute("aria-expanded","true"),this._clearBadge(),this._pushContextToIframe()}close(){this._open=!1,this._isFullscreen=!1;const t=this.shadowRoot.querySelector(".panel");t.classList.add("closed"),t.classList.remove("fullscreen");const e=this.shadowRoot.querySelector(".toggle-btn");e.style.display="",e.setAttribute("aria-expanded","false")}_toggleFullscreen(){this._isFullscreen=!this._isFullscreen;const t=this.shadowRoot.querySelector(".panel"),e=this.shadowRoot.querySelector(".toggle-btn");this._isFullscreen?(t.classList.add("fullscreen"),e.style.display="none"):(t.classList.remove("fullscreen"),e.style.display="")}sendMessage(t){this._open||this.open(),setTimeout(()=>{var e,n;(n=(e=this._iframeEl)==null?void 0:e.contentWindow)==null||n.postMessage({type:"btp-copilot:send-message",text:t},"*")},100)}_buildShadow(){var r;const t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=w,t.appendChild(e);const n=document.createElement("div");for(n.innerHTML=this._template();n.firstChild;)t.appendChild(n.firstChild);t.querySelector(".toggle-btn").addEventListener("click",()=>{this._open?this.close():this.open()}),this._iframeEl=t.querySelector(".chat-iframe"),(r=this._iframeEl)==null||r.addEventListener("load",()=>{this._pushAuthToIframe(),this._pushContextToIframe()})}_template(){var n;const t=((n=this._config)==null?void 0:n.position)??"bottom-right",e=this._esc(this._buildIframeUrl());return`
134
134
  <button class="toggle-btn ${t}" aria-label="Open AI assistant" aria-expanded="false" aria-haspopup="dialog">
135
135
  <svg class="icon-chat" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
136
136
  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
@@ -149,5 +149,5 @@ ${a.content}`).join(`
149
149
  allow="clipboard-read; clipboard-write"
150
150
  loading="lazy">
151
151
  </iframe>
152
- </div>`}_buildBaseContext(){const t=d.resolve(this._config.token);return{app_id:this._config.appId,app_name:this._config.appName,service_url:this._config.serviceUrl,...t?{extra:{auth_token:t}}:{}}}_buildIframeUrl(){var e;const t=((e=this._config)==null?void 0:e.iframeUrl)??"";if(!t)return"";try{const n=new URL(t),{appId:i,appName:r,serviceUrl:o}=this._config;i&&n.searchParams.set("appId",i),r&&n.searchParams.set("appName",r),o&&n.searchParams.set("serviceUrl",o);const a=d.resolve(this._config.token);return a&&n.searchParams.set("token",a),n.toString()}catch{return t}}_iframeOrigin(){try{return new URL(this._config.iframeUrl).origin}catch{return"*"}}_pushContextToIframe(){var e;if(!((e=this._iframeEl)!=null&&e.contentWindow))return;const t=this._iframeOrigin();this._config.autoContext?f.captureAsync(this._buildBaseContext()).then(n=>{var i,r;(r=(i=this._iframeEl)==null?void 0:i.contentWindow)==null||r.postMessage({type:"btp-copilot:set-context",payload:n},t),n.service_url&&!this._config.serviceUrl&&(this._config={...this._config,serviceUrl:n.service_url})}).catch(()=>{var n,i;(i=(n=this._iframeEl)==null?void 0:n.contentWindow)==null||i.postMessage({type:"btp-copilot:set-context",payload:this._buildBaseContext()},t)}):this._iframeEl.contentWindow.postMessage({type:"btp-copilot:set-context",payload:this._buildBaseContext()},t)}_pushAuthToIframe(){var e;const t=d.resolve(this._config.token);!t||!((e=this._iframeEl)!=null&&e.contentWindow)||this._iframeEl.contentWindow.postMessage({type:"btp-copilot:auth",token:t},this._iframeOrigin())}_startContextPolling(){this._config.autoContext&&(this._contextTimer=setInterval(()=>{this._open&&this._pushContextToIframe()},this._config.contextInterval))}_stopContextPolling(){this._contextTimer!==null&&(clearInterval(this._contextTimer),this._contextTimer=null)}_readConfig(){const t=e=>this.getAttribute(e);return{iframeUrl:t("iframe-url")??"",appId:t("app-id")??"default",appName:t("app-name")??void 0,serviceUrl:t("service-url")??void 0,autoContext:t("auto-context")!=="false",position:t("position")??"bottom-right",theme:t("theme")??"auto",token:t("token")??void 0,contextInterval:Math.max(500,Number(t("context-interval"))||3e3)}}_updateAfterAttributeChange(){var n;const t=(n=this.shadowRoot)==null?void 0:n.querySelector("style");t&&(t.textContent=x);const e=this._buildIframeUrl();this._iframeEl&&this._iframeEl.src!==e&&e&&(this._iframeEl.src=e),this._stopContextPolling(),this._startContextPolling()}_clearBadge(){var t,e;(e=(t=this.shadowRoot)==null?void 0:t.querySelector(".badge"))==null||e.classList.remove("visible")}_esc(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}};v.observedAttributes=[...w];let y=v;return customElements.get("btp-copilot")||customElements.define("btp-copilot",y),g.BtpCopilotElement=y,g.ContextBridge=f,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"}),g}({});
152
+ </div>`}_buildBaseContext(){const t=d.resolve(this._config.token);return{app_id:this._config.appId,app_name:this._config.appName,service_url:this._config.serviceUrl,...t?{extra:{auth_token:t}}:{}}}_buildIframeUrl(){var e;const t=((e=this._config)==null?void 0:e.iframeUrl)??"";if(!t)return"";try{const n=new URL(t),{appId:r,appName:o,serviceUrl:i}=this._config;r&&n.searchParams.set("appId",r),o&&n.searchParams.set("appName",o),i&&n.searchParams.set("serviceUrl",i);const a=d.resolve(this._config.token);return a&&n.searchParams.set("token",a),n.toString()}catch{return t}}_iframeOrigin(){try{return new URL(this._config.iframeUrl).origin}catch{return"*"}}_pushContextToIframe(){var e;if(!((e=this._iframeEl)!=null&&e.contentWindow))return;const t=this._iframeOrigin();this._config.autoContext?f.captureAsync(this._buildBaseContext()).then(n=>{var r,o;(o=(r=this._iframeEl)==null?void 0:r.contentWindow)==null||o.postMessage({type:"btp-copilot:set-context",payload:n},t),n.service_url&&!this._config.serviceUrl&&(this._config={...this._config,serviceUrl:n.service_url})}).catch(()=>{var n,r;(r=(n=this._iframeEl)==null?void 0:n.contentWindow)==null||r.postMessage({type:"btp-copilot:set-context",payload:this._buildBaseContext()},t)}):this._iframeEl.contentWindow.postMessage({type:"btp-copilot:set-context",payload:this._buildBaseContext()},t)}_pushAuthToIframe(){var e;const t=d.resolve(this._config.token);!t||!((e=this._iframeEl)!=null&&e.contentWindow)||this._iframeEl.contentWindow.postMessage({type:"btp-copilot:auth",token:t},this._iframeOrigin())}_startContextPolling(){this._config.autoContext&&(this._contextTimer=setInterval(()=>{this._open&&this._pushContextToIframe()},this._config.contextInterval))}_stopContextPolling(){this._contextTimer!==null&&(clearInterval(this._contextTimer),this._contextTimer=null)}_readConfig(){const t=e=>this.getAttribute(e);return{iframeUrl:t("iframe-url")??"",appId:t("app-id")??"default",appName:t("app-name")??void 0,serviceUrl:t("service-url")??void 0,autoContext:t("auto-context")!=="false",position:t("position")??"bottom-right",theme:t("theme")??"auto",token:t("token")??void 0,contextInterval:Math.max(500,Number(t("context-interval"))||3e3)}}_updateAfterAttributeChange(){var n;const t=(n=this.shadowRoot)==null?void 0:n.querySelector("style");t&&(t.textContent=w);const e=this._buildIframeUrl();this._iframeEl&&this._iframeEl.src!==e&&e&&(this._iframeEl.src=e),this._stopContextPolling(),this._startContextPolling()}_clearBadge(){var t,e;(e=(t=this.shadowRoot)==null?void 0:t.querySelector(".badge"))==null||e.classList.remove("visible")}_esc(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}};v.observedAttributes=[...x];let y=v;return customElements.get("btp-copilot")||customElements.define("btp-copilot",y),g.BtpCopilotElement=y,g.ContextBridge=f,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"}),g}({});
153
153
  //# sourceMappingURL=btp-copilot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"btp-copilot.js","sources":["../src/api/TokenManager.ts","../src/context/ShellProbe.ts","../src/context/UI5Probe.ts","../src/context/ODataProbe.ts","../src/context/ContextBridge.ts","../src/styles/widget.css?raw","../src/BtpCopilotElement.ts","../src/index.ts"],"sourcesContent":["export class TokenManager {\n private static readonly XSUAA_COOKIE_NAMES = [\n \"x-uaa-token\",\n \"xsuaa_token\",\n \"access_token\",\n \"X-Authorization\",\n ];\n\n static resolve(explicitToken?: string | null): string | null {\n if (explicitToken) return explicitToken.replace(/^Bearer\\s+/i, \"\");\n\n const windowToken = (window as any).__BTP_COPILOT_TOKEN__ as\n | string\n | undefined;\n if (windowToken) return windowToken.replace(/^Bearer\\s+/i, \"\");\n\n const cookieToken = TokenManager._fromCookie();\n if (cookieToken) return cookieToken;\n\n try {\n const lsToken = localStorage.getItem(\"access_token\");\n if (lsToken) return lsToken;\n } catch {}\n\n return null;\n }\n\n static getAuthHeader(token: string | null): Record<string, string> {\n return token ? { Authorization: `Bearer ${token}` } : {};\n }\n\n private static _fromCookie(): string | null {\n try {\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, ...rest] = cookie.trim().split(\"=\");\n if (TokenManager.XSUAA_COOKIE_NAMES.includes(name.trim())) {\n return decodeURIComponent(rest.join(\"=\").trim());\n }\n }\n } catch {}\n return null;\n }\n}\n","declare const sap: any;\n\nexport class ShellProbe {\n static getHash(): string {\n try {\n const nav = sap?.ushell?.Container?.getService?.(\n \"CrossApplicationNavigation\",\n );\n if (nav) {\n const href = nav.hrefForExternal?.() as string | undefined;\n if (href) return href;\n }\n } catch (err) {\n console.log(err);\n }\n return window.location.hash || \"\";\n }\n\n static getCurrentAppId(): string | null {\n try {\n const hash = ShellProbe.getHash();\n const match = hash.match(/^#([^&?/]+)/);\n return match ? match[1] : null;\n } catch {\n return null;\n }\n }\n\n static getUserLocale(): string {\n try {\n return (\n sap?.ui?.getCore?.()?.getConfiguration?.()?.getLanguageTag?.() ??\n navigator.language ??\n \"en\"\n );\n } catch {\n return navigator.language ?? \"en\";\n }\n }\n}\n","declare const sap: any;\n\nexport class UI5Probe {\n static getCurrentEntity(): Record<string, unknown> | null {\n try {\n const core = sap?.ui?.getCore?.();\n if (!core) return null;\n\n let el: Element | null = document.activeElement;\n while (el) {\n const id = el.getAttribute(\"id\") || el.getAttribute(\"data-sap-ui\");\n if (id) {\n const control = core.byId(id);\n const ctx = control?.getBindingContext?.();\n if (ctx) {\n const obj = ctx.getObject?.();\n if (obj && typeof obj === \"object\") {\n return UI5Probe._sanitize(obj as Record<string, unknown>);\n }\n }\n }\n el = el.parentElement;\n }\n return UI5Probe._scanAllControls(core);\n } catch {\n return null;\n }\n }\n\n private static _scanAllControls(core: any): Record<string, unknown> | null {\n try {\n const elements = core.mElements ?? {};\n for (const id of Object.keys(elements)) {\n const control = elements[id];\n const ctx = control?.getBindingContext?.();\n if (ctx) {\n const obj = ctx.getObject?.();\n if (obj && typeof obj === \"object\" && Object.keys(obj).length > 0) {\n return UI5Probe._sanitize(obj as Record<string, unknown>);\n }\n }\n }\n } catch {}\n return null;\n }\n\n static getServiceUrl(): string | null {\n try {\n const core = sap?.ui?.getCore?.();\n if (!core) return null;\n const elements = core.mElements ?? {};\n for (const id of Object.keys(elements)) {\n const control = elements[id];\n if (!control?.getModel) continue;\n const model = control.getModel();\n if (!model) continue;\n const url: unknown = model.sServiceUrl ?? (model as any)._sServiceUrl;\n if (typeof url === \"string\" && url.length > 4) {\n return url.replace(/\\/$/, \"\");\n }\n }\n } catch {}\n return null;\n }\n\n private static _sanitize(\n obj: Record<string, unknown>,\n ): Record<string, unknown> {\n const clean: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (k.startsWith(\"__\")) continue;\n if (v === null || typeof v !== \"object\") {\n clean[k] = v;\n } else if ((v as any).__deferred) {\n // navigation property stub — skip\n } else {\n clean[k] = v;\n }\n }\n return clean;\n }\n}\n","import type {\n EntitySchema,\n EntityProperty,\n NavProperty,\n AppDocument,\n} from \"../types\";\n\nexport class ODataProbe {\n private static _cache = new Map<string, AppDocument[]>();\n\n static async fetchSchemaDocuments(\n serviceUrl: string,\n token?: string | null,\n ): Promise<AppDocument[]> {\n const cacheKey = `btp-copilot-meta-${serviceUrl}`;\n\n if (ODataProbe._cache.has(cacheKey)) {\n return ODataProbe._cache.get(cacheKey)!;\n }\n\n const stored = sessionStorage.getItem(cacheKey);\n if (stored) {\n try {\n const docs = JSON.parse(stored) as AppDocument[];\n ODataProbe._cache.set(cacheKey, docs);\n return docs;\n } catch {}\n }\n\n try {\n const metaUrl = `${serviceUrl}/$metadata`;\n const headers: Record<string, string> = { Accept: \"application/xml\" };\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\n const resp = await fetch(metaUrl, { headers });\n if (!resp.ok) return [];\n\n const xml = await resp.text();\n const schemas = ODataProbe._parseEDMX(xml);\n const docs = ODataProbe._schemasToDocuments(schemas, serviceUrl);\n\n ODataProbe._cache.set(cacheKey, docs);\n sessionStorage.setItem(cacheKey, JSON.stringify(docs));\n return docs;\n } catch {\n return [];\n }\n }\n\n private static _parseEDMX(xml: string): EntitySchema[] {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, \"text/xml\");\n const entityTypes = doc.querySelectorAll(\"EntityType\");\n return Array.from(entityTypes).map((et) => {\n const name = et.getAttribute(\"Name\") ?? \"\";\n const keyRefs = et.querySelectorAll(\"Key > PropertyRef\");\n const keyNames = new Set(\n Array.from(keyRefs).map((k) => k.getAttribute(\"Name\") ?? \"\"),\n );\n const properties: EntityProperty[] = Array.from(\n et.querySelectorAll(\"Property\"),\n ).map((p) => ({\n name: p.getAttribute(\"Name\") ?? \"\",\n type: ODataProbe._shortType(p.getAttribute(\"Type\") ?? \"\"),\n isKey: keyNames.has(p.getAttribute(\"Name\") ?? \"\"),\n nullable: p.getAttribute(\"Nullable\") !== \"false\",\n }));\n const navProperties: NavProperty[] = Array.from(\n et.querySelectorAll(\"NavigationProperty\"),\n ).map((n) => ({\n name: n.getAttribute(\"Name\") ?? \"\",\n type: ODataProbe._shortType(\n n.getAttribute(\"Type\") ?? n.getAttribute(\"ToRole\") ?? \"\",\n ),\n }));\n return { name, properties, navProperties };\n });\n } catch {\n return [];\n }\n }\n\n private static _shortType(full: string): string {\n if (full.startsWith(\"Collection(\")) {\n const inner = full.slice(11, -1);\n return `${inner.split(\".\").pop()}[]`;\n }\n return full.split(\".\").pop() ?? full;\n }\n\n private static _schemasToDocuments(\n schemas: EntitySchema[],\n serviceUrl: string,\n ): AppDocument[] {\n const docs: AppDocument[] = [];\n\n for (const schema of schemas) {\n if (!schema.name) continue;\n const keyProps = schema.properties.filter((p) => p.isKey);\n const otherProps = schema.properties.filter((p) => !p.isKey);\n const lines = [\n `Entity: ${schema.name}`,\n `OData service: ${serviceUrl}`,\n `Entity set path: ${serviceUrl}/${schema.name}`,\n `Count path: ${serviceUrl}/${schema.name}/$count`,\n ];\n if (keyProps.length) {\n lines.push(\n `Key fields: ${keyProps.map((p) => `${p.name} (${p.type})`).join(\", \")}`,\n );\n }\n if (otherProps.length) {\n lines.push(\n `Fields: ${otherProps\n .map(\n (p) => `${p.name} (${p.type}${p.nullable ? \"\" : \", required\"})`,\n )\n .join(\", \")}`,\n );\n }\n if (schema.navProperties.length) {\n lines.push(\n `Navigation: ${schema.navProperties.map((n) => `${n.name} → ${n.type}`).join(\", \")}`,\n );\n }\n docs.push({\n title: `${schema.name} entity schema`,\n content: lines.join(\"\\n\"),\n });\n }\n\n if (schemas.length > 0) {\n docs.push({\n title: \"Available OData entity sets\",\n content: [\n `OData service: ${serviceUrl}`,\n `Entities: ${schemas.map((s) => s.name).join(\", \")}`,\n \"GET {entity}/$count | ?$filter=field eq 'value' | ?$top=10&$skip=0 | ?$orderby=field desc\",\n ].join(\"\\n\"),\n });\n }\n\n return docs;\n }\n\n static invalidate(serviceUrl: string) {\n const key = `btp-copilot-meta-${serviceUrl}`;\n ODataProbe._cache.delete(key);\n sessionStorage.removeItem(key);\n }\n}\n","import type { HostAppContext } from \"../types\";\nimport { ShellProbe } from \"./ShellProbe\";\nimport { UI5Probe } from \"./UI5Probe\";\nimport { ODataProbe } from \"./ODataProbe\";\n\nexport class ContextBridge {\n static capture(baseContext: HostAppContext): HostAppContext {\n const ctx: HostAppContext = { ...baseContext };\n\n try {\n const hash = ShellProbe.getHash();\n if (hash) ctx.current_view = hash;\n } catch {}\n\n try {\n const entity = UI5Probe.getCurrentEntity();\n if (entity && Object.keys(entity).length > 0) ctx.entity_data = entity;\n } catch {}\n\n try {\n if (!ctx.user_locale) ctx.user_locale = ShellProbe.getUserLocale();\n } catch {}\n\n // Merge any context injected by the host app\n try {\n const injected = (window as any).__APP_CONTEXT__ as\n | Partial<HostAppContext>\n | undefined;\n if (injected) {\n if (injected.entity_data)\n ctx.entity_data = { ...injected.entity_data, ...ctx.entity_data };\n if (injected.current_view && !ctx.current_view)\n ctx.current_view = injected.current_view;\n if (injected.extra)\n ctx.extra = { ...injected.extra, ...(ctx.extra ?? {}) };\n if (injected.service_url && !ctx.service_url)\n ctx.service_url = injected.service_url;\n }\n } catch {}\n\n return ctx;\n }\n\n static async captureAsync(\n baseContext: HostAppContext,\n ): Promise<HostAppContext> {\n const ctx = ContextBridge.capture(baseContext);\n\n if (!ctx.service_url) {\n ctx.service_url = ContextBridge._discoverServiceUrl() ?? undefined;\n }\n\n if (ctx.service_url) {\n try {\n const token = (ctx.extra as any)?.auth_token ?? null;\n const docs = await ODataProbe.fetchSchemaDocuments(\n ctx.service_url,\n token,\n );\n if (docs.length > 0) {\n const schemaHint = docs\n .map((d) => `## ${d.title}\\n${d.content}`)\n .join(\"\\n\\n\");\n ctx.extra = { ...(ctx.extra ?? {}), schema_hint: schemaHint };\n }\n } catch {}\n }\n\n return ctx;\n }\n\n private static _discoverServiceUrl(): string | null {\n try {\n const url = UI5Probe.getServiceUrl();\n if (url) return url;\n } catch {}\n\n try {\n const entries = performance.getEntriesByType(\n \"resource\",\n ) as PerformanceResourceTiming[];\n for (const e of entries) {\n const m = e.name.match(/^(https?:\\/\\/[^?#]+)\\/\\$metadata/);\n if (m) return m[1];\n }\n } catch {}\n\n try {\n const m = window.location.href.match(\n /(https?:\\/\\/[^/]+(?:\\/odata\\/v[24]\\/[^/?#]+|\\/sap\\/opu\\/odata\\/[^/?#]+))/,\n );\n if (m) return m[1];\n } catch {}\n\n return null;\n }\n\n static async discoverFromManifest(): Promise<string | null> {\n try {\n const resp = await fetch(\"/manifest.json\");\n if (!resp.ok) return null;\n const manifest = await resp.json();\n const sources: Record<string, any> =\n manifest?.[\"sap.app\"]?.dataSources ?? {};\n for (const key of Object.keys(sources)) {\n const src = sources[key];\n if (src?.type === \"ODataAnnotation\") continue;\n const uri: unknown = src?.uri;\n if (typeof uri === \"string\" && uri.length > 0) {\n return new URL(uri, window.location.href)\n .toString()\n .replace(/\\/$/, \"\");\n }\n }\n } catch {}\n return null;\n }\n\n static listenForUpdates(\n onContextUpdate: (ctx: Partial<HostAppContext>) => void,\n onMessage: (text: string) => void,\n onOpen: () => void,\n onClose: () => void,\n ): () => void {\n const handler = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== \"object\") return;\n const { type, payload, text } = event.data as {\n type?: string;\n payload?: Partial<HostAppContext>;\n text?: string;\n };\n switch (type) {\n case \"btp-copilot:set-context\":\n if (payload) onContextUpdate(payload);\n break;\n case \"btp-copilot:send-message\":\n if (text) onMessage(text);\n break;\n case \"btp-copilot:open\":\n onOpen();\n break;\n case \"btp-copilot:close\":\n onClose();\n break;\n }\n };\n window.addEventListener(\"message\", handler);\n return () => window.removeEventListener(\"message\", handler);\n }\n}\n","export default \"/* ── Host element ─────────────────────────────────────────────────────────── */\\n:host {\\n position: fixed;\\n z-index: 2147483647;\\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\\n}\\n\\n*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\\n\\n/* ── Toggle (FAB) button ─────────────────────────────────────────────────── */\\n.toggle-btn {\\n position: fixed;\\n bottom: 1.25rem;\\n width: 3.25rem;\\n height: 3.25rem;\\n border-radius: 50%;\\n border: none;\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\\n color: #fff;\\n box-shadow: 0 4px 14px rgba(102, 126, 234, 0.45);\\n z-index: 2147483647;\\n transition: transform 0.2s ease, box-shadow 0.2s ease;\\n outline: none;\\n}\\n\\n.toggle-btn.bottom-right { right: 1.25rem; }\\n.toggle-btn.bottom-left { left: 1.25rem; }\\n\\n.toggle-btn:hover {\\n transform: scale(1.08);\\n box-shadow: 0 6px 20px rgba(102, 126, 234, 0.55);\\n}\\n.toggle-btn:active { transform: scale(0.95); }\\n.toggle-btn:focus-visible { outline: 3px solid #60a5fa; outline-offset: 2px; }\\n\\n.toggle-btn[aria-expanded=\\\"false\\\"] .icon-close { display: none; }\\n.toggle-btn[aria-expanded=\\\"true\\\"] .icon-chat { display: none; }\\n.toggle-btn svg { width: 1.375rem; height: 1.375rem; pointer-events: none; }\\n\\n/* Unread-message badge */\\n.badge {\\n position: absolute;\\n top: 0.125rem;\\n right: 0.125rem;\\n width: 0.625rem;\\n height: 0.625rem;\\n border-radius: 50%;\\n background: #ef4444;\\n border: 2px solid #fff;\\n opacity: 0;\\n transform: scale(0);\\n transition: opacity 0.2s ease, transform 0.2s ease;\\n}\\n.badge.visible { opacity: 1; transform: scale(1); }\\n\\n/* ── Chat panel ──────────────────────────────────────────────────────────── */\\n.panel {\\n position: fixed;\\n bottom: 5.5rem;\\n width: 26rem;\\n height: 70vh;\\n min-height: 25rem;\\n max-height: 47.5rem;\\n background: transparent;\\n border-radius: 1rem;\\n box-shadow: 0 8px 40px rgba(0, 0, 0, 0.22), 0 0 0 1px rgba(0, 0, 0, 0.06);\\n z-index: 2147483646;\\n overflow: hidden;\\n display: flex;\\n flex-direction: column;\\n transform-origin: bottom center;\\n transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.34, 1.3, 0.64, 1),\\n width 0.3s cubic-bezier(0.4, 0, 0.2, 1), height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\\n bottom 0.3s cubic-bezier(0.4, 0, 0.2, 1), border-radius 0.3s ease;\\n}\\n\\n.panel.bottom-right { right: 1.25rem; }\\n.panel.bottom-left { left: 1.25rem; }\\n\\n.panel.closed {\\n opacity: 0;\\n pointer-events: none;\\n transform: translateY(0.5rem) scale(0.97);\\n}\\n\\n/* Fullscreen mode */\\n.panel.fullscreen {\\n width: 100vw !important;\\n height: 100vh !important;\\n height: 100dvh !important;\\n bottom: 0 !important;\\n right: 0 !important;\\n left: 0 !important;\\n border-radius: 0 !important;\\n max-height: none !important;\\n}\\n\\n.panel.fullscreen .chat-iframe {\\n border-radius: 0 !important;\\n}\\n\\n/* Iframe fills the entire panel */\\n.chat-iframe {\\n width: 100%;\\n height: 100%;\\n border: none;\\n border-radius: 1rem;\\n display: block;\\n background: #fff;\\n}\\n\\n/* ── Mobile: full-screen ─────────────────────────────────────────────────── */\\n@media (max-width: 30rem) {\\n .panel {\\n width: 100vw;\\n height: 85dvh;\\n bottom: 0;\\n right: 0 !important;\\n left: 0 !important;\\n border-radius: 1rem 1rem 0 0;\\n }\\n .chat-iframe { border-radius: 1rem 1rem 0 0; }\\n}\\n\"","/**\n * BtpCopilotElement — <btp-copilot> Custom Element.\n *\n * Renders a fixed floating FAB button. When opened, shows your deployed\n * BTP Copilot React chatbot in an iframe. Context from the host UI5/Fiori\n * app is auto-captured and forwarded into the iframe via postMessage so the\n * chatbot is always aware of what the user is looking at.\n *\n * Attributes:\n * iframe-url Full URL of the deployed React chatbot frontend (required)\n * app-id Stable identifier of the host application (required)\n * app-name Human-readable app name\n * service-url OData service URL for context auto-capture\n * auto-context \"true\"|\"false\" — auto-capture UI5/OData context (default: true)\n * position \"bottom-right\"|\"bottom-left\" (default: bottom-right)\n * theme \"auto\"|\"light\"|\"dark\" (default: auto)\n * token Bearer token forwarded to the chatbot iframe\n * context-interval Context re-capture interval in ms (default: 3000)\n *\n * postMessage protocol (outgoing → iframe):\n * { type: 'btp-copilot:set-context', payload: HostAppContext }\n * { type: 'btp-copilot:auth', token: string }\n *\n * postMessage protocol (incoming ← iframe or host page):\n * { type: 'btp-copilot:close' }\n * { type: 'btp-copilot:open' }\n */\n\nimport type { HostAppContext, WidgetConfig } from \"./types\";\nimport { TokenManager } from \"./api/TokenManager\";\nimport { ContextBridge } from \"./context/ContextBridge\";\nimport widgetCss from \"./styles/widget.css?raw\";\n\nconst OBSERVED = [\n \"iframe-url\",\n \"app-id\",\n \"app-name\",\n \"service-url\",\n \"auto-context\",\n \"position\",\n \"theme\",\n \"token\",\n \"context-interval\",\n] as const;\n\nexport class BtpCopilotElement extends HTMLElement {\n static observedAttributes = [...OBSERVED];\n\n private _config!: WidgetConfig;\n private _open = false;\n private _isFullscreen = false;\n private _iframeEl: HTMLIFrameElement | null = null;\n private _contextTimer: ReturnType<typeof setInterval> | null = null;\n private _removeMessageListener?: () => void;\n\n connectedCallback() {\n this._config = this._readConfig();\n this._buildShadow();\n this._startContextPolling();\n\n const msgHandler = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== \"object\") return;\n const { type } = event.data as { type?: string };\n if (type === \"btp-copilot:close\") this.close();\n if (type === \"btp-copilot:open\") this.open();\n if (type === \"btp-copilot:fullscreen\") this._toggleFullscreen();\n if (type === \"btp-copilot:minimize\") this.close();\n };\n window.addEventListener(\"message\", msgHandler);\n this._removeMessageListener = () =>\n window.removeEventListener(\"message\", msgHandler);\n }\n\n disconnectedCallback() {\n this._removeMessageListener?.();\n this._stopContextPolling();\n }\n\n attributeChangedCallback(\n _name: string,\n old: string | null,\n next: string | null\n ) {\n if (old === next || !this.isConnected) return;\n this._config = this._readConfig();\n this._updateAfterAttributeChange();\n }\n\n // ── Public API ─────────────────────────────────────────────────────────────\n open() {\n this._open = true;\n this.shadowRoot!.querySelector(\".panel\")!.classList.remove(\"closed\");\n this.shadowRoot!\n .querySelector(\".toggle-btn\")!\n .setAttribute(\"aria-expanded\", \"true\");\n this._clearBadge();\n this._pushContextToIframe();\n }\n\n close() {\n this._open = false;\n const panel = this.shadowRoot!.querySelector(\".panel\")!;\n panel.classList.add(\"closed\");\n panel.classList.remove(\"fullscreen\");\n this._isFullscreen = false;\n this.shadowRoot!\n .querySelector(\".toggle-btn\")!\n .setAttribute(\"aria-expanded\", \"false\");\n }\n\n private _toggleFullscreen() {\n this._isFullscreen = !this._isFullscreen;\n const panel = this.shadowRoot!.querySelector(\".panel\")!;\n const fab = this.shadowRoot!.querySelector(\".toggle-btn\") as HTMLElement;\n if (this._isFullscreen) {\n panel.classList.add(\"fullscreen\");\n fab.style.display = \"none\";\n } else {\n panel.classList.remove(\"fullscreen\");\n fab.style.display = \"\";\n }\n }\n\n sendMessage(text: string) {\n if (!this._open) this.open();\n setTimeout(() => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:send-message\", text },\n \"*\"\n );\n }, 100);\n }\n\n // ── Shadow DOM ─────────────────────────────────────────────────────────────\n private _buildShadow() {\n const shadow = this.attachShadow({ mode: \"open\" });\n\n const styleEl = document.createElement(\"style\");\n styleEl.textContent = widgetCss;\n shadow.appendChild(styleEl);\n\n const wrapper = document.createElement(\"div\");\n wrapper.innerHTML = this._template();\n while (wrapper.firstChild) shadow.appendChild(wrapper.firstChild);\n\n shadow.querySelector(\".toggle-btn\")!.addEventListener(\"click\", () => {\n this._open ? this.close() : this.open();\n });\n\n this._iframeEl = shadow.querySelector(\".chat-iframe\");\n\n this._iframeEl?.addEventListener(\"load\", () => {\n this._pushAuthToIframe();\n this._pushContextToIframe();\n });\n }\n\n private _template(): string {\n const pos = this._config?.position ?? \"bottom-right\";\n const src = this._esc(this._buildIframeUrl());\n return `\n<button class=\"toggle-btn ${pos}\" aria-label=\"Open AI assistant\" aria-expanded=\"false\" aria-haspopup=\"dialog\">\n <svg class=\"icon-chat\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>\n </svg>\n <svg class=\"icon-close\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n <span class=\"badge\" aria-hidden=\"true\"></span>\n</button>\n\n<div class=\"panel closed ${pos}\" role=\"dialog\" aria-label=\"AI Assistant\" aria-modal=\"true\">\n <iframe\n class=\"chat-iframe\"\n src=\"${src}\"\n title=\"AI Assistant\"\n allow=\"clipboard-read; clipboard-write\"\n loading=\"lazy\">\n </iframe>\n</div>`;\n }\n\n // ── Context + Auth ─────────────────────────────────────────────────────────\n private _buildBaseContext(): HostAppContext {\n const token = TokenManager.resolve(this._config.token);\n return {\n app_id: this._config.appId,\n app_name: this._config.appName,\n service_url: this._config.serviceUrl,\n // Include the resolved auth token in extra so the backend can\n // proxy OData calls on behalf of the user to fetch real data\n ...(token ? { extra: { auth_token: token } } : {}),\n };\n }\n\n private _buildIframeUrl(): string {\n const base = this._config?.iframeUrl ?? \"\";\n if (!base) return \"\";\n try {\n const url = new URL(base);\n const { appId, appName, serviceUrl } = this._config;\n if (appId) url.searchParams.set(\"appId\", appId);\n if (appName) url.searchParams.set(\"appName\", appName);\n if (serviceUrl) url.searchParams.set(\"serviceUrl\", serviceUrl);\n // Pass token as URL param so the chatbot can auto-authenticate in iframe mode\n const token = TokenManager.resolve(this._config.token);\n if (token) url.searchParams.set(\"token\", token);\n return url.toString();\n } catch {\n return base;\n }\n }\n\n /** Derive the allowed postMessage target origin from the configured iframe URL.\n * Falls back to \"*\" only when the URL cannot be parsed (e.g. empty string). */\n private _iframeOrigin(): string {\n try {\n return new URL(this._config.iframeUrl).origin;\n } catch {\n return \"*\";\n }\n }\n\n private _pushContextToIframe() {\n if (!this._iframeEl?.contentWindow) return;\n const origin = this._iframeOrigin();\n\n if (this._config.autoContext) {\n ContextBridge.captureAsync(this._buildBaseContext())\n .then((ctx) => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:set-context\", payload: ctx },\n origin\n );\n if (ctx.service_url && !this._config.serviceUrl) {\n this._config = { ...this._config, serviceUrl: ctx.service_url };\n }\n })\n .catch(() => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:set-context\", payload: this._buildBaseContext() },\n origin\n );\n });\n } else {\n this._iframeEl.contentWindow.postMessage(\n { type: \"btp-copilot:set-context\", payload: this._buildBaseContext() },\n origin\n );\n }\n }\n\n private _pushAuthToIframe() {\n const token = TokenManager.resolve(this._config.token);\n if (!token || !this._iframeEl?.contentWindow) return;\n this._iframeEl.contentWindow.postMessage(\n { type: \"btp-copilot:auth\", token },\n this._iframeOrigin()\n );\n }\n\n private _startContextPolling() {\n if (!this._config.autoContext) return;\n this._contextTimer = setInterval(() => {\n if (this._open) this._pushContextToIframe();\n }, this._config.contextInterval);\n }\n\n private _stopContextPolling() {\n if (this._contextTimer !== null) {\n clearInterval(this._contextTimer);\n this._contextTimer = null;\n }\n }\n\n // ── Config ─────────────────────────────────────────────────────────────────\n private _readConfig(): WidgetConfig {\n const get = (attr: string) => this.getAttribute(attr);\n return {\n iframeUrl: get(\"iframe-url\") ?? \"\",\n appId: get(\"app-id\") ?? \"default\",\n appName: get(\"app-name\") ?? undefined,\n serviceUrl: get(\"service-url\") ?? undefined,\n autoContext: get(\"auto-context\") !== \"false\",\n position: (get(\"position\") ?? \"bottom-right\") as WidgetConfig[\"position\"],\n theme: (get(\"theme\") ?? \"auto\") as WidgetConfig[\"theme\"],\n token: get(\"token\") ?? undefined,\n contextInterval: Math.max(500, Number(get(\"context-interval\")) || 3000),\n };\n }\n\n private _updateAfterAttributeChange() {\n const style = this.shadowRoot?.querySelector(\"style\");\n if (style) style.textContent = widgetCss;\n\n const newSrc = this._buildIframeUrl();\n if (this._iframeEl && this._iframeEl.src !== newSrc && newSrc) {\n this._iframeEl.src = newSrc;\n }\n\n this._stopContextPolling();\n this._startContextPolling();\n }\n\n private _clearBadge() {\n this.shadowRoot?.querySelector(\".badge\")?.classList.remove(\"visible\");\n }\n\n private _esc(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n }\n}\n","import { BtpCopilotElement } from \"./BtpCopilotElement\";\n\nif (!customElements.get(\"btp-copilot\")) {\n customElements.define(\"btp-copilot\", BtpCopilotElement);\n}\n\nexport { BtpCopilotElement };\nexport type { HostAppContext, WidgetConfig, AppDocument } from \"./types\";\nexport { ContextBridge } from \"./context/ContextBridge\";\n"],"names":["_TokenManager","explicitToken","windowToken","cookieToken","lsToken","token","cookies","cookie","name","rest","TokenManager","ShellProbe","nav","_c","_b","_a","href","_d","err","match","_f","_e","UI5Probe","core","el","id","control","ctx","obj","elements","model","url","clean","k","v","_ODataProbe","serviceUrl","cacheKey","stored","docs","metaUrl","headers","resp","xml","schemas","entityTypes","et","keyRefs","keyNames","properties","p","navProperties","n","full","schema","keyProps","otherProps","lines","s","key","ODataProbe","ContextBridge","baseContext","hash","entity","injected","schemaHint","d","entries","m","manifest","sources","src","uri","onContextUpdate","onMessage","onOpen","onClose","handler","event","type","payload","text","widgetCss","OBSERVED","_BtpCopilotElement","msgHandler","_name","old","next","panel","fab","shadow","styleEl","wrapper","pos","base","appId","appName","origin","get","attr","style","newSrc","BtpCopilotElement"],"mappings":"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"}
1
+ {"version":3,"file":"btp-copilot.js","sources":["../src/api/TokenManager.ts","../src/context/ShellProbe.ts","../src/context/UI5Probe.ts","../src/context/ODataProbe.ts","../src/context/ContextBridge.ts","../src/styles/widget.css?raw","../src/BtpCopilotElement.ts","../src/index.ts"],"sourcesContent":["export class TokenManager {\n private static readonly XSUAA_COOKIE_NAMES = [\n \"x-uaa-token\",\n \"xsuaa_token\",\n \"access_token\",\n \"X-Authorization\",\n ];\n\n static resolve(explicitToken?: string | null): string | null {\n if (explicitToken) return explicitToken.replace(/^Bearer\\s+/i, \"\");\n\n const windowToken = (window as any).__BTP_COPILOT_TOKEN__ as\n | string\n | undefined;\n if (windowToken) return windowToken.replace(/^Bearer\\s+/i, \"\");\n\n const cookieToken = TokenManager._fromCookie();\n if (cookieToken) return cookieToken;\n\n try {\n const lsToken = localStorage.getItem(\"access_token\");\n if (lsToken) return lsToken;\n } catch {}\n\n return null;\n }\n\n static getAuthHeader(token: string | null): Record<string, string> {\n return token ? { Authorization: `Bearer ${token}` } : {};\n }\n\n private static _fromCookie(): string | null {\n try {\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, ...rest] = cookie.trim().split(\"=\");\n if (TokenManager.XSUAA_COOKIE_NAMES.includes(name.trim())) {\n return decodeURIComponent(rest.join(\"=\").trim());\n }\n }\n } catch {}\n return null;\n }\n}\n","declare const sap: any;\n\nexport class ShellProbe {\n static getHash(): string {\n try {\n const nav = sap?.ushell?.Container?.getService?.(\n \"CrossApplicationNavigation\",\n );\n if (nav) {\n const href = nav.hrefForExternal?.() as string | undefined;\n if (href) return href;\n }\n } catch (err) {\n console.log(err);\n }\n return window.location.hash || \"\";\n }\n\n static getCurrentAppId(): string | null {\n try {\n const hash = ShellProbe.getHash();\n const match = hash.match(/^#([^&?/]+)/);\n return match ? match[1] : null;\n } catch {\n return null;\n }\n }\n\n static getUserLocale(): string {\n try {\n return (\n sap?.ui?.getCore?.()?.getConfiguration?.()?.getLanguageTag?.() ??\n navigator.language ??\n \"en\"\n );\n } catch {\n return navigator.language ?? \"en\";\n }\n }\n}\n","declare const sap: any;\n\nexport class UI5Probe {\n static getCurrentEntity(): Record<string, unknown> | null {\n try {\n const core = sap?.ui?.getCore?.();\n if (!core) return null;\n\n let el: Element | null = document.activeElement;\n while (el) {\n const id = el.getAttribute(\"id\") || el.getAttribute(\"data-sap-ui\");\n if (id) {\n const control = core.byId(id);\n const ctx = control?.getBindingContext?.();\n if (ctx) {\n const obj = ctx.getObject?.();\n if (obj && typeof obj === \"object\") {\n return UI5Probe._sanitize(obj as Record<string, unknown>);\n }\n }\n }\n el = el.parentElement;\n }\n return UI5Probe._scanAllControls(core);\n } catch {\n return null;\n }\n }\n\n private static _scanAllControls(core: any): Record<string, unknown> | null {\n try {\n const elements = core.mElements ?? {};\n for (const id of Object.keys(elements)) {\n const control = elements[id];\n const ctx = control?.getBindingContext?.();\n if (ctx) {\n const obj = ctx.getObject?.();\n if (obj && typeof obj === \"object\" && Object.keys(obj).length > 0) {\n return UI5Probe._sanitize(obj as Record<string, unknown>);\n }\n }\n }\n } catch {}\n return null;\n }\n\n static getServiceUrl(): string | null {\n try {\n const core = sap?.ui?.getCore?.();\n if (!core) return null;\n const elements = core.mElements ?? {};\n for (const id of Object.keys(elements)) {\n const control = elements[id];\n if (!control?.getModel) continue;\n const model = control.getModel();\n if (!model) continue;\n const url: unknown = model.sServiceUrl ?? (model as any)._sServiceUrl;\n if (typeof url === \"string\" && url.length > 4) {\n return url.replace(/\\/$/, \"\");\n }\n }\n } catch {}\n return null;\n }\n\n private static _sanitize(\n obj: Record<string, unknown>,\n ): Record<string, unknown> {\n const clean: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (k.startsWith(\"__\")) continue;\n if (v === null || typeof v !== \"object\") {\n clean[k] = v;\n } else if ((v as any).__deferred) {\n // navigation property stub — skip\n } else {\n clean[k] = v;\n }\n }\n return clean;\n }\n}\n","import type {\n EntitySchema,\n EntityProperty,\n NavProperty,\n AppDocument,\n} from \"../types\";\n\nexport class ODataProbe {\n private static _cache = new Map<string, AppDocument[]>();\n\n static async fetchSchemaDocuments(\n serviceUrl: string,\n token?: string | null,\n ): Promise<AppDocument[]> {\n const cacheKey = `btp-copilot-meta-${serviceUrl}`;\n\n if (ODataProbe._cache.has(cacheKey)) {\n return ODataProbe._cache.get(cacheKey)!;\n }\n\n const stored = sessionStorage.getItem(cacheKey);\n if (stored) {\n try {\n const docs = JSON.parse(stored) as AppDocument[];\n ODataProbe._cache.set(cacheKey, docs);\n return docs;\n } catch {}\n }\n\n try {\n const metaUrl = `${serviceUrl}/$metadata`;\n const headers: Record<string, string> = { Accept: \"application/xml\" };\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\n const resp = await fetch(metaUrl, { headers });\n if (!resp.ok) return [];\n\n const xml = await resp.text();\n const schemas = ODataProbe._parseEDMX(xml);\n const docs = ODataProbe._schemasToDocuments(schemas, serviceUrl);\n\n ODataProbe._cache.set(cacheKey, docs);\n sessionStorage.setItem(cacheKey, JSON.stringify(docs));\n return docs;\n } catch {\n return [];\n }\n }\n\n private static _parseEDMX(xml: string): EntitySchema[] {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, \"text/xml\");\n const entityTypes = doc.querySelectorAll(\"EntityType\");\n return Array.from(entityTypes).map((et) => {\n const name = et.getAttribute(\"Name\") ?? \"\";\n const keyRefs = et.querySelectorAll(\"Key > PropertyRef\");\n const keyNames = new Set(\n Array.from(keyRefs).map((k) => k.getAttribute(\"Name\") ?? \"\"),\n );\n const properties: EntityProperty[] = Array.from(\n et.querySelectorAll(\"Property\"),\n ).map((p) => ({\n name: p.getAttribute(\"Name\") ?? \"\",\n type: ODataProbe._shortType(p.getAttribute(\"Type\") ?? \"\"),\n isKey: keyNames.has(p.getAttribute(\"Name\") ?? \"\"),\n nullable: p.getAttribute(\"Nullable\") !== \"false\",\n }));\n const navProperties: NavProperty[] = Array.from(\n et.querySelectorAll(\"NavigationProperty\"),\n ).map((n) => ({\n name: n.getAttribute(\"Name\") ?? \"\",\n type: ODataProbe._shortType(\n n.getAttribute(\"Type\") ?? n.getAttribute(\"ToRole\") ?? \"\",\n ),\n }));\n return { name, properties, navProperties };\n });\n } catch {\n return [];\n }\n }\n\n private static _shortType(full: string): string {\n if (full.startsWith(\"Collection(\")) {\n const inner = full.slice(11, -1);\n return `${inner.split(\".\").pop()}[]`;\n }\n return full.split(\".\").pop() ?? full;\n }\n\n private static _schemasToDocuments(\n schemas: EntitySchema[],\n serviceUrl: string,\n ): AppDocument[] {\n const docs: AppDocument[] = [];\n\n for (const schema of schemas) {\n if (!schema.name) continue;\n const keyProps = schema.properties.filter((p) => p.isKey);\n const otherProps = schema.properties.filter((p) => !p.isKey);\n const lines = [\n `Entity: ${schema.name}`,\n `OData service: ${serviceUrl}`,\n `Entity set path: ${serviceUrl}/${schema.name}`,\n `Count path: ${serviceUrl}/${schema.name}/$count`,\n ];\n if (keyProps.length) {\n lines.push(\n `Key fields: ${keyProps.map((p) => `${p.name} (${p.type})`).join(\", \")}`,\n );\n }\n if (otherProps.length) {\n lines.push(\n `Fields: ${otherProps\n .map(\n (p) => `${p.name} (${p.type}${p.nullable ? \"\" : \", required\"})`,\n )\n .join(\", \")}`,\n );\n }\n if (schema.navProperties.length) {\n lines.push(\n `Navigation: ${schema.navProperties.map((n) => `${n.name} → ${n.type}`).join(\", \")}`,\n );\n }\n docs.push({\n title: `${schema.name} entity schema`,\n content: lines.join(\"\\n\"),\n });\n }\n\n if (schemas.length > 0) {\n docs.push({\n title: \"Available OData entity sets\",\n content: [\n `OData service: ${serviceUrl}`,\n `Entities: ${schemas.map((s) => s.name).join(\", \")}`,\n \"GET {entity}/$count | ?$filter=field eq 'value' | ?$top=10&$skip=0 | ?$orderby=field desc\",\n ].join(\"\\n\"),\n });\n }\n\n return docs;\n }\n\n static invalidate(serviceUrl: string) {\n const key = `btp-copilot-meta-${serviceUrl}`;\n ODataProbe._cache.delete(key);\n sessionStorage.removeItem(key);\n }\n}\n","import type { HostAppContext } from \"../types\";\nimport { ShellProbe } from \"./ShellProbe\";\nimport { UI5Probe } from \"./UI5Probe\";\nimport { ODataProbe } from \"./ODataProbe\";\n\nexport class ContextBridge {\n static capture(baseContext: HostAppContext): HostAppContext {\n const ctx: HostAppContext = { ...baseContext };\n\n // ── SAP-specific probes (no-ops on non-SAP apps) ──────────────────────────\n try {\n const hash = ShellProbe.getHash();\n if (hash) ctx.current_view = hash;\n } catch {}\n\n try {\n const entity = UI5Probe.getCurrentEntity();\n if (entity && Object.keys(entity).length > 0) ctx.entity_data = entity;\n } catch {}\n\n try {\n if (!ctx.user_locale) ctx.user_locale = ShellProbe.getUserLocale();\n } catch {}\n\n // ── Generic web context (works for any app) ───────────────────────────────\n // current_view: full path + search + hash (more useful than hash alone)\n try {\n const fullPath =\n window.location.pathname +\n window.location.search +\n window.location.hash;\n if (!ctx.current_view || ctx.current_view === \"\") {\n ctx.current_view = fullPath;\n }\n } catch {}\n\n // locale fallback\n try {\n if (!ctx.user_locale) {\n ctx.user_locale =\n navigator.language || (navigator as any).languages?.[0] || \"en\";\n }\n } catch {}\n\n // page_title and page_url give the LLM meaningful screen context\n try {\n ctx.extra = {\n ...(ctx.extra ?? {}),\n page_title:\n (ctx.extra as any)?.page_title ?? document.title ?? \"\",\n page_url:\n (ctx.extra as any)?.page_url ?? window.location.href ?? \"\",\n };\n } catch {}\n\n // ── Host-app injected context (highest priority) ──────────────────────────\n try {\n const injected = (window as any).__APP_CONTEXT__ as\n | Partial<HostAppContext>\n | undefined;\n if (injected) {\n if (injected.entity_data)\n ctx.entity_data = { ...injected.entity_data, ...ctx.entity_data };\n if (injected.current_view && !ctx.current_view)\n ctx.current_view = injected.current_view;\n if (injected.extra)\n ctx.extra = { ...injected.extra, ...(ctx.extra ?? {}) };\n if (injected.service_url && !ctx.service_url)\n ctx.service_url = injected.service_url;\n }\n } catch {}\n\n return ctx;\n }\n\n static async captureAsync(\n baseContext: HostAppContext,\n ): Promise<HostAppContext> {\n const ctx = ContextBridge.capture(baseContext);\n\n if (!ctx.service_url) {\n ctx.service_url = ContextBridge._discoverServiceUrl() ?? undefined;\n }\n\n if (ctx.service_url) {\n try {\n const token = (ctx.extra as any)?.auth_token ?? null;\n const docs = await ODataProbe.fetchSchemaDocuments(\n ctx.service_url,\n token,\n );\n if (docs.length > 0) {\n const schemaHint = docs\n .map((d) => `## ${d.title}\\n${d.content}`)\n .join(\"\\n\\n\");\n ctx.extra = { ...(ctx.extra ?? {}), schema_hint: schemaHint };\n }\n } catch {}\n }\n\n return ctx;\n }\n\n private static _discoverServiceUrl(): string | null {\n try {\n const url = UI5Probe.getServiceUrl();\n if (url) return url;\n } catch {}\n\n try {\n const entries = performance.getEntriesByType(\n \"resource\",\n ) as PerformanceResourceTiming[];\n for (const e of entries) {\n const m = e.name.match(/^(https?:\\/\\/[^?#]+)\\/\\$metadata/);\n if (m) return m[1];\n }\n } catch {}\n\n try {\n const m = window.location.href.match(\n /(https?:\\/\\/[^/]+(?:\\/odata\\/v[24]\\/[^/?#]+|\\/sap\\/opu\\/odata\\/[^/?#]+))/,\n );\n if (m) return m[1];\n } catch {}\n\n return null;\n }\n\n static async discoverFromManifest(): Promise<string | null> {\n try {\n const resp = await fetch(\"/manifest.json\");\n if (!resp.ok) return null;\n const manifest = await resp.json();\n const sources: Record<string, any> =\n manifest?.[\"sap.app\"]?.dataSources ?? {};\n for (const key of Object.keys(sources)) {\n const src = sources[key];\n if (src?.type === \"ODataAnnotation\") continue;\n const uri: unknown = src?.uri;\n if (typeof uri === \"string\" && uri.length > 0) {\n return new URL(uri, window.location.href)\n .toString()\n .replace(/\\/$/, \"\");\n }\n }\n } catch {}\n return null;\n }\n\n static listenForUpdates(\n onContextUpdate: (ctx: Partial<HostAppContext>) => void,\n onMessage: (text: string) => void,\n onOpen: () => void,\n onClose: () => void,\n ): () => void {\n const handler = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== \"object\") return;\n const { type, payload, text } = event.data as {\n type?: string;\n payload?: Partial<HostAppContext>;\n text?: string;\n };\n switch (type) {\n case \"btp-copilot:set-context\":\n if (payload) onContextUpdate(payload);\n break;\n case \"btp-copilot:send-message\":\n if (text) onMessage(text);\n break;\n case \"btp-copilot:open\":\n onOpen();\n break;\n case \"btp-copilot:close\":\n onClose();\n break;\n }\n };\n window.addEventListener(\"message\", handler);\n return () => window.removeEventListener(\"message\", handler);\n }\n}\n","export default \"/* ── Host element ─────────────────────────────────────────────────────────── */\\n:host {\\n position: fixed;\\n z-index: 2147483647;\\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\\n}\\n\\n*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\\n\\n/* ── Toggle (FAB) button ─────────────────────────────────────────────────── */\\n.toggle-btn {\\n position: fixed;\\n bottom: 1.25rem;\\n width: 3.25rem;\\n height: 3.25rem;\\n border-radius: 50%;\\n border: none;\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\\n color: #fff;\\n box-shadow: 0 4px 14px rgba(102, 126, 234, 0.45);\\n z-index: 2147483647;\\n transition: transform 0.2s ease, box-shadow 0.2s ease;\\n outline: none;\\n}\\n\\n.toggle-btn.bottom-right { right: 1.25rem; }\\n.toggle-btn.bottom-left { left: 1.25rem; }\\n\\n.toggle-btn:hover {\\n transform: scale(1.08);\\n box-shadow: 0 6px 20px rgba(102, 126, 234, 0.55);\\n}\\n.toggle-btn:active { transform: scale(0.95); }\\n.toggle-btn:focus-visible { outline: 3px solid #60a5fa; outline-offset: 2px; }\\n\\n.toggle-btn[aria-expanded=\\\"false\\\"] .icon-close { display: none; }\\n.toggle-btn[aria-expanded=\\\"true\\\"] .icon-chat { display: none; }\\n.toggle-btn svg { width: 1.375rem; height: 1.375rem; pointer-events: none; }\\n\\n/* Unread-message badge */\\n.badge {\\n position: absolute;\\n top: 0.125rem;\\n right: 0.125rem;\\n width: 0.625rem;\\n height: 0.625rem;\\n border-radius: 50%;\\n background: #ef4444;\\n border: 2px solid #fff;\\n opacity: 0;\\n transform: scale(0);\\n transition: opacity 0.2s ease, transform 0.2s ease;\\n}\\n.badge.visible { opacity: 1; transform: scale(1); }\\n\\n/* ── Chat panel ──────────────────────────────────────────────────────────── */\\n.panel {\\n position: fixed;\\n bottom: 5.5rem;\\n width: 26rem;\\n height: 70vh;\\n min-height: 25rem;\\n max-height: 47.5rem;\\n background: transparent;\\n border-radius: 1rem;\\n box-shadow: 0 8px 40px rgba(0, 0, 0, 0.22), 0 0 0 1px rgba(0, 0, 0, 0.06);\\n z-index: 2147483646;\\n overflow: hidden;\\n display: flex;\\n flex-direction: column;\\n transform-origin: bottom center;\\n transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.34, 1.3, 0.64, 1),\\n width 0.3s cubic-bezier(0.4, 0, 0.2, 1), height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\\n bottom 0.3s cubic-bezier(0.4, 0, 0.2, 1), border-radius 0.3s ease;\\n}\\n\\n.panel.bottom-right { right: 1.25rem; }\\n.panel.bottom-left { left: 1.25rem; }\\n\\n.panel.closed {\\n opacity: 0;\\n pointer-events: none;\\n transform: translateY(0.5rem) scale(0.97);\\n}\\n\\n/* Fullscreen mode */\\n.panel.fullscreen {\\n width: 100vw !important;\\n height: 100vh !important;\\n height: 100dvh !important;\\n bottom: 0 !important;\\n right: 0 !important;\\n left: 0 !important;\\n border-radius: 0 !important;\\n max-height: none !important;\\n}\\n\\n.panel.fullscreen .chat-iframe {\\n border-radius: 0 !important;\\n}\\n\\n/* Iframe fills the entire panel */\\n.chat-iframe {\\n width: 100%;\\n height: 100%;\\n border: none;\\n border-radius: 1rem;\\n display: block;\\n background: #fff;\\n}\\n\\n/* ── Mobile: full-screen ─────────────────────────────────────────────────── */\\n@media (max-width: 30rem) {\\n .panel {\\n width: 100vw;\\n height: 85dvh;\\n bottom: 0;\\n right: 0 !important;\\n left: 0 !important;\\n border-radius: 1rem 1rem 0 0;\\n }\\n .chat-iframe { border-radius: 1rem 1rem 0 0; }\\n}\\n\"","/**\n * BtpCopilotElement — <btp-copilot> Custom Element.\n *\n * Renders a fixed floating FAB button. When opened, shows your deployed\n * BTP Copilot React chatbot in an iframe. Context from the host UI5/Fiori\n * app is auto-captured and forwarded into the iframe via postMessage so the\n * chatbot is always aware of what the user is looking at.\n *\n * Attributes:\n * iframe-url Full URL of the deployed React chatbot frontend (required)\n * app-id Stable identifier of the host application (required)\n * app-name Human-readable app name\n * service-url OData service URL for context auto-capture\n * auto-context \"true\"|\"false\" — auto-capture UI5/OData context (default: true)\n * position \"bottom-right\"|\"bottom-left\" (default: bottom-right)\n * theme \"auto\"|\"light\"|\"dark\" (default: auto)\n * token Bearer token forwarded to the chatbot iframe\n * context-interval Context re-capture interval in ms (default: 3000)\n *\n * postMessage protocol (outgoing → iframe):\n * { type: 'btp-copilot:set-context', payload: HostAppContext }\n * { type: 'btp-copilot:auth', token: string }\n *\n * postMessage protocol (incoming ← iframe or host page):\n * { type: 'btp-copilot:close' }\n * { type: 'btp-copilot:open' }\n */\n\nimport type { HostAppContext, WidgetConfig } from \"./types\";\nimport { TokenManager } from \"./api/TokenManager\";\nimport { ContextBridge } from \"./context/ContextBridge\";\nimport widgetCss from \"./styles/widget.css?raw\";\n\nconst OBSERVED = [\n \"iframe-url\",\n \"app-id\",\n \"app-name\",\n \"service-url\",\n \"auto-context\",\n \"position\",\n \"theme\",\n \"token\",\n \"context-interval\",\n] as const;\n\nexport class BtpCopilotElement extends HTMLElement {\n static observedAttributes = [...OBSERVED];\n\n private _config!: WidgetConfig;\n private _open = false;\n private _isFullscreen = false;\n private _iframeEl: HTMLIFrameElement | null = null;\n private _contextTimer: ReturnType<typeof setInterval> | null = null;\n private _removeMessageListener?: () => void;\n\n connectedCallback() {\n this._config = this._readConfig();\n this._buildShadow();\n this._startContextPolling();\n\n const msgHandler = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== \"object\") return;\n const { type } = event.data as { type?: string };\n if (type === \"btp-copilot:close\") this.close();\n if (type === \"btp-copilot:open\") this.open();\n if (type === \"btp-copilot:fullscreen\") this._toggleFullscreen();\n if (type === \"btp-copilot:minimize\") this.close();\n };\n window.addEventListener(\"message\", msgHandler);\n this._removeMessageListener = () =>\n window.removeEventListener(\"message\", msgHandler);\n }\n\n disconnectedCallback() {\n this._removeMessageListener?.();\n this._stopContextPolling();\n }\n\n attributeChangedCallback(\n _name: string,\n old: string | null,\n next: string | null\n ) {\n if (old === next || !this.isConnected) return;\n this._config = this._readConfig();\n this._updateAfterAttributeChange();\n }\n\n // ── Public API ─────────────────────────────────────────────────────────────\n open() {\n this._open = true;\n this.shadowRoot!.querySelector(\".panel\")!.classList.remove(\"closed\");\n this.shadowRoot!\n .querySelector(\".toggle-btn\")!\n .setAttribute(\"aria-expanded\", \"true\");\n this._clearBadge();\n this._pushContextToIframe();\n }\n\n close() {\n this._open = false;\n this._isFullscreen = false;\n const panel = this.shadowRoot!.querySelector(\".panel\")!;\n panel.classList.add(\"closed\");\n panel.classList.remove(\"fullscreen\");\n const fab = this.shadowRoot!.querySelector(\".toggle-btn\") as HTMLElement;\n fab.style.display = \"\"; // always restore FAB — covers minimize-from-fullscreen\n fab.setAttribute(\"aria-expanded\", \"false\");\n }\n\n private _toggleFullscreen() {\n this._isFullscreen = !this._isFullscreen;\n const panel = this.shadowRoot!.querySelector(\".panel\")!;\n const fab = this.shadowRoot!.querySelector(\".toggle-btn\") as HTMLElement;\n if (this._isFullscreen) {\n panel.classList.add(\"fullscreen\");\n fab.style.display = \"none\";\n } else {\n panel.classList.remove(\"fullscreen\");\n fab.style.display = \"\";\n }\n }\n\n sendMessage(text: string) {\n if (!this._open) this.open();\n setTimeout(() => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:send-message\", text },\n \"*\"\n );\n }, 100);\n }\n\n // ── Shadow DOM ─────────────────────────────────────────────────────────────\n private _buildShadow() {\n const shadow = this.attachShadow({ mode: \"open\" });\n\n const styleEl = document.createElement(\"style\");\n styleEl.textContent = widgetCss;\n shadow.appendChild(styleEl);\n\n const wrapper = document.createElement(\"div\");\n wrapper.innerHTML = this._template();\n while (wrapper.firstChild) shadow.appendChild(wrapper.firstChild);\n\n shadow.querySelector(\".toggle-btn\")!.addEventListener(\"click\", () => {\n this._open ? this.close() : this.open();\n });\n\n this._iframeEl = shadow.querySelector(\".chat-iframe\");\n\n this._iframeEl?.addEventListener(\"load\", () => {\n this._pushAuthToIframe();\n this._pushContextToIframe();\n });\n }\n\n private _template(): string {\n const pos = this._config?.position ?? \"bottom-right\";\n const src = this._esc(this._buildIframeUrl());\n return `\n<button class=\"toggle-btn ${pos}\" aria-label=\"Open AI assistant\" aria-expanded=\"false\" aria-haspopup=\"dialog\">\n <svg class=\"icon-chat\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/>\n </svg>\n <svg class=\"icon-close\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n <span class=\"badge\" aria-hidden=\"true\"></span>\n</button>\n\n<div class=\"panel closed ${pos}\" role=\"dialog\" aria-label=\"AI Assistant\" aria-modal=\"true\">\n <iframe\n class=\"chat-iframe\"\n src=\"${src}\"\n title=\"AI Assistant\"\n allow=\"clipboard-read; clipboard-write\"\n loading=\"lazy\">\n </iframe>\n</div>`;\n }\n\n // ── Context + Auth ─────────────────────────────────────────────────────────\n private _buildBaseContext(): HostAppContext {\n const token = TokenManager.resolve(this._config.token);\n return {\n app_id: this._config.appId,\n app_name: this._config.appName,\n service_url: this._config.serviceUrl,\n // Include the resolved auth token in extra so the backend can\n // proxy OData calls on behalf of the user to fetch real data\n ...(token ? { extra: { auth_token: token } } : {}),\n };\n }\n\n private _buildIframeUrl(): string {\n const base = this._config?.iframeUrl ?? \"\";\n if (!base) return \"\";\n try {\n const url = new URL(base);\n const { appId, appName, serviceUrl } = this._config;\n if (appId) url.searchParams.set(\"appId\", appId);\n if (appName) url.searchParams.set(\"appName\", appName);\n if (serviceUrl) url.searchParams.set(\"serviceUrl\", serviceUrl);\n // Pass token as URL param so the chatbot can auto-authenticate in iframe mode\n const token = TokenManager.resolve(this._config.token);\n if (token) url.searchParams.set(\"token\", token);\n return url.toString();\n } catch {\n return base;\n }\n }\n\n /** Derive the allowed postMessage target origin from the configured iframe URL.\n * Falls back to \"*\" only when the URL cannot be parsed (e.g. empty string). */\n private _iframeOrigin(): string {\n try {\n return new URL(this._config.iframeUrl).origin;\n } catch {\n return \"*\";\n }\n }\n\n private _pushContextToIframe() {\n if (!this._iframeEl?.contentWindow) return;\n const origin = this._iframeOrigin();\n\n if (this._config.autoContext) {\n ContextBridge.captureAsync(this._buildBaseContext())\n .then((ctx) => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:set-context\", payload: ctx },\n origin\n );\n if (ctx.service_url && !this._config.serviceUrl) {\n this._config = { ...this._config, serviceUrl: ctx.service_url };\n }\n })\n .catch(() => {\n this._iframeEl?.contentWindow?.postMessage(\n { type: \"btp-copilot:set-context\", payload: this._buildBaseContext() },\n origin\n );\n });\n } else {\n this._iframeEl.contentWindow.postMessage(\n { type: \"btp-copilot:set-context\", payload: this._buildBaseContext() },\n origin\n );\n }\n }\n\n private _pushAuthToIframe() {\n const token = TokenManager.resolve(this._config.token);\n if (!token || !this._iframeEl?.contentWindow) return;\n this._iframeEl.contentWindow.postMessage(\n { type: \"btp-copilot:auth\", token },\n this._iframeOrigin()\n );\n }\n\n private _startContextPolling() {\n if (!this._config.autoContext) return;\n this._contextTimer = setInterval(() => {\n if (this._open) this._pushContextToIframe();\n }, this._config.contextInterval);\n }\n\n private _stopContextPolling() {\n if (this._contextTimer !== null) {\n clearInterval(this._contextTimer);\n this._contextTimer = null;\n }\n }\n\n // ── Config ─────────────────────────────────────────────────────────────────\n private _readConfig(): WidgetConfig {\n const get = (attr: string) => this.getAttribute(attr);\n return {\n iframeUrl: get(\"iframe-url\") ?? \"\",\n appId: get(\"app-id\") ?? \"default\",\n appName: get(\"app-name\") ?? undefined,\n serviceUrl: get(\"service-url\") ?? undefined,\n autoContext: get(\"auto-context\") !== \"false\",\n position: (get(\"position\") ?? \"bottom-right\") as WidgetConfig[\"position\"],\n theme: (get(\"theme\") ?? \"auto\") as WidgetConfig[\"theme\"],\n token: get(\"token\") ?? undefined,\n contextInterval: Math.max(500, Number(get(\"context-interval\")) || 3000),\n };\n }\n\n private _updateAfterAttributeChange() {\n const style = this.shadowRoot?.querySelector(\"style\");\n if (style) style.textContent = widgetCss;\n\n const newSrc = this._buildIframeUrl();\n if (this._iframeEl && this._iframeEl.src !== newSrc && newSrc) {\n this._iframeEl.src = newSrc;\n }\n\n this._stopContextPolling();\n this._startContextPolling();\n }\n\n private _clearBadge() {\n this.shadowRoot?.querySelector(\".badge\")?.classList.remove(\"visible\");\n }\n\n private _esc(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n }\n}\n","import { BtpCopilotElement } from \"./BtpCopilotElement\";\n\nif (!customElements.get(\"btp-copilot\")) {\n customElements.define(\"btp-copilot\", BtpCopilotElement);\n}\n\nexport { BtpCopilotElement };\nexport type { HostAppContext, WidgetConfig, AppDocument } from \"./types\";\nexport { ContextBridge } from \"./context/ContextBridge\";\n"],"names":["_TokenManager","explicitToken","windowToken","cookieToken","lsToken","token","cookies","cookie","name","rest","TokenManager","ShellProbe","nav","_c","_b","_a","href","_d","err","match","_f","_e","UI5Probe","core","el","id","control","ctx","obj","elements","model","url","clean","k","v","_ODataProbe","serviceUrl","cacheKey","stored","docs","metaUrl","headers","resp","xml","schemas","entityTypes","et","keyRefs","keyNames","properties","p","navProperties","n","full","schema","keyProps","otherProps","lines","s","key","ODataProbe","ContextBridge","baseContext","hash","entity","fullPath","injected","schemaHint","d","entries","m","manifest","sources","src","uri","onContextUpdate","onMessage","onOpen","onClose","handler","event","type","payload","text","widgetCss","OBSERVED","_BtpCopilotElement","msgHandler","_name","old","next","panel","fab","shadow","styleEl","wrapper","pos","base","appId","appName","origin","get","attr","style","newSrc","BtpCopilotElement"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cap-copilot-widget",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "BTP Copilot floating chat widget — Web Component (iframe launcher)",
5
5
  "main": "dist/btp-copilot.js",
6
6
  "module": "dist/btp-copilot.esm.js",