@athenaintel/react 0.10.35 → 0.10.36

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.
@@ -23,5 +23,9 @@ export interface AthenaAssetEmbedConfigEvent {
23
23
  token?: string;
24
24
  citationBehavior: AthenaAssetCitationBehavior;
25
25
  }
26
+ export declare function resolveAthenaAssetCitationBehavior({ citationBehavior, hasCitationClickHandler, }: {
27
+ citationBehavior?: AthenaAssetCitationBehavior;
28
+ hasCitationClickHandler: boolean;
29
+ }): AthenaAssetCitationBehavior;
26
30
  export declare function isAthenaAssetEmbedReadyEvent(value: unknown): value is AthenaAssetEmbedReadyEvent;
27
31
  export declare function isAthenaAssetCitationClickEvent(value: unknown): value is AthenaAssetCitationClickEvent;
@@ -26,6 +26,11 @@ export declare function resolveAssetEmbedUrl({ embedUrl, appUrl, backendUrl, cur
26
26
  backendUrl?: string | null;
27
27
  currentOrigin?: string | null;
28
28
  }): string;
29
+ export declare function buildSdkAssetEmbedUrl(embedUrl: string): string;
30
+ export declare function getAssetEmbedAuthContext({ token, apiKey }: {
31
+ token?: string | null;
32
+ apiKey?: string;
33
+ }): string;
29
34
  /**
30
35
  * Hook to generate an embed URL for rendering an asset in an iframe.
31
36
  * Calls the Athena embed token endpoint.
package/dist/index.cjs CHANGED
@@ -56254,6 +56254,13 @@ const AthenaUserMessage = ({
56254
56254
  const ATHENA_ASSET_EMBED_READY_MESSAGE = "athena:asset-embed-ready";
56255
56255
  const ATHENA_ASSET_EMBED_CONFIG_MESSAGE = "athena:asset-embed-config";
56256
56256
  const ATHENA_ASSET_CITATION_CLICK_MESSAGE = "athena:asset-citation-click";
56257
+ function resolveAthenaAssetCitationBehavior({
56258
+ citationBehavior,
56259
+ hasCitationClickHandler
56260
+ }) {
56261
+ if (citationBehavior === "host" && !hasCitationClickHandler) return "browser";
56262
+ return citationBehavior ?? (hasCitationClickHandler ? "host" : "browser");
56263
+ }
56257
56264
  function isAthenaAssetEmbedReadyEvent(value) {
56258
56265
  return typeof value === "object" && value !== null && "type" in value && value.type === ATHENA_ASSET_EMBED_READY_MESSAGE && "version" in value && value.version === 1;
56259
56266
  }
@@ -56356,7 +56363,11 @@ function resolveAssetEmbedUrl({
56356
56363
  if (!resolvedEmbedUrl.pathname.startsWith("/embed/")) {
56357
56364
  return embedUrl;
56358
56365
  }
56359
- const embedAppUrl = resolveEmbedAppUrl({ appUrl, backendUrl, currentOrigin });
56366
+ const embedAppUrl = resolveEmbedAppUrl({
56367
+ appUrl,
56368
+ backendUrl,
56369
+ currentOrigin
56370
+ });
56360
56371
  if (!embedAppUrl) {
56361
56372
  return embedUrl;
56362
56373
  }
@@ -56368,6 +56379,41 @@ function resolveAssetEmbedUrl({
56368
56379
  return embedUrl;
56369
56380
  }
56370
56381
  }
56382
+ function buildSdkAssetEmbedUrl(embedUrl) {
56383
+ try {
56384
+ const url = new URL(embedUrl);
56385
+ url.searchParams.set("athena_sdk_bridge", "1");
56386
+ return url.toString();
56387
+ } catch {
56388
+ return embedUrl;
56389
+ }
56390
+ }
56391
+ const getJwtPayload = (token) => {
56392
+ try {
56393
+ const payloadSegment = token.split(".")[1];
56394
+ if (!payloadSegment || typeof atob !== "function") return null;
56395
+ const normalized = payloadSegment.replace(/-/g, "+").replace(/_/g, "/");
56396
+ const payload = JSON.parse(
56397
+ atob(normalized.padEnd(normalized.length + (4 - normalized.length % 4) % 4, "="))
56398
+ );
56399
+ return payload && typeof payload === "object" ? payload : null;
56400
+ } catch {
56401
+ return null;
56402
+ }
56403
+ };
56404
+ function getAssetEmbedAuthContext({ token, apiKey }) {
56405
+ if (!token) return apiKey ? `api-key:${apiKey}` : "anonymous";
56406
+ const payload = getJwtPayload(token);
56407
+ const userId = (payload == null ? void 0 : payload.user_id) ?? (payload == null ? void 0 : payload.sub);
56408
+ if (typeof userId !== "string" || !userId) return `opaque-token:${token}`;
56409
+ return `jwt:${JSON.stringify({
56410
+ issuer: (payload == null ? void 0 : payload.iss) ?? null,
56411
+ userId,
56412
+ activeOrgId: (payload == null ? void 0 : payload.active_org_id) ?? (payload == null ? void 0 : payload.org_id) ?? null,
56413
+ workspaceId: (payload == null ? void 0 : payload.workspace_id) ?? null,
56414
+ orgMemberships: (payload == null ? void 0 : payload.org_id_to_org_member_info) ?? null
56415
+ })}`;
56416
+ }
56371
56417
  function useAssetEmbed(assetId, options = {
56372
56418
  backendUrl: ""
56373
56419
  }) {
@@ -56386,7 +56432,7 @@ function useAssetEmbed(assetId, options = {
56386
56432
  const abortRef = React.useRef(null);
56387
56433
  const tokenRef = React.useRef(token);
56388
56434
  tokenRef.current = token;
56389
- const hasToken = !!token;
56435
+ const authContext = getAssetEmbedAuthContext({ token, apiKey });
56390
56436
  React.useEffect(() => {
56391
56437
  var _a2;
56392
56438
  if (!assetId || !backendUrl) {
@@ -56395,7 +56441,6 @@ function useAssetEmbed(assetId, options = {
56395
56441
  setError(null);
56396
56442
  return;
56397
56443
  }
56398
- const authContext = hasToken ? "token" : apiKey ?? "anon";
56399
56444
  const cacheKey = `${assetId}:${readOnly}:${displayMode}:${authContext}:${backendUrl}:${appUrl ?? ""}`;
56400
56445
  const cached2 = embedCache.get(cacheKey);
56401
56446
  if (cached2 && cached2.expiresAt > Date.now() / 1e3) {
@@ -56411,10 +56456,12 @@ function useAssetEmbed(assetId, options = {
56411
56456
  abortRef.current = controller;
56412
56457
  setIsLoading(true);
56413
56458
  setError(null);
56414
- const headers = { "Content-Type": "application/json" };
56459
+ const headers = {
56460
+ "Content-Type": "application/json"
56461
+ };
56415
56462
  const currentToken = tokenRef.current;
56416
56463
  if (currentToken) {
56417
- headers["Authorization"] = `Bearer ${currentToken}`;
56464
+ headers.Authorization = `Bearer ${currentToken}`;
56418
56465
  } else if (apiKey) {
56419
56466
  headers["X-API-KEY"] = apiKey;
56420
56467
  }
@@ -56422,7 +56469,12 @@ function useAssetEmbed(assetId, options = {
56422
56469
  method: "POST",
56423
56470
  headers,
56424
56471
  body: JSON.stringify(
56425
- buildAssetEmbedRequestBody({ assetId, readOnly, expiresInSeconds, displayMode })
56472
+ buildAssetEmbedRequestBody({
56473
+ assetId,
56474
+ readOnly,
56475
+ expiresInSeconds,
56476
+ displayMode
56477
+ })
56426
56478
  ),
56427
56479
  signal: controller.signal
56428
56480
  }).then(async (res) => {
@@ -56437,7 +56489,10 @@ function useAssetEmbed(assetId, options = {
56437
56489
  appUrl,
56438
56490
  backendUrl
56439
56491
  });
56440
- embedCache.set(cacheKey, { url: resolvedEmbedUrl, expiresAt: data.expires_at });
56492
+ embedCache.set(cacheKey, {
56493
+ url: resolvedEmbedUrl,
56494
+ expiresAt: data.expires_at
56495
+ });
56441
56496
  setEmbedUrl(resolvedEmbedUrl);
56442
56497
  setIsLoading(false);
56443
56498
  }).catch((err) => {
@@ -56446,7 +56501,7 @@ function useAssetEmbed(assetId, options = {
56446
56501
  setIsLoading(false);
56447
56502
  });
56448
56503
  return () => controller.abort();
56449
- }, [assetId, readOnly, expiresInSeconds, displayMode, backendUrl, appUrl, apiKey, hasToken]);
56504
+ }, [assetId, readOnly, expiresInSeconds, displayMode, backendUrl, appUrl, authContext, apiKey]);
56450
56505
  return { embedUrl, isLoading, error: error2 };
56451
56506
  }
56452
56507
  const DEFAULT_STYLE = {
@@ -56492,7 +56547,11 @@ const AthenaAssetEmbed = ({
56492
56547
  return null;
56493
56548
  }
56494
56549
  }, [embedUrl]);
56495
- const effectiveCitationBehavior = citationBehavior ?? (onCitationClick ? "host" : "browser");
56550
+ const iframeSrc = React.useMemo(() => embedUrl ? buildSdkAssetEmbedUrl(embedUrl) : null, [embedUrl]);
56551
+ const effectiveCitationBehavior = resolveAthenaAssetCitationBehavior({
56552
+ citationBehavior,
56553
+ hasCitationClickHandler: !!onCitationClick
56554
+ });
56496
56555
  const sendConfig = React.useCallback(() => {
56497
56556
  var _a2, _b;
56498
56557
  if (!targetOrigin) return;
@@ -56510,8 +56569,7 @@ const AthenaAssetEmbed = ({
56510
56569
  if (!embedUrl || !targetOrigin) return;
56511
56570
  const handleMessage = (event) => {
56512
56571
  var _a2;
56513
- if (event.origin !== targetOrigin || event.source !== ((_a2 = iframeRef.current) == null ? void 0 : _a2.contentWindow))
56514
- return;
56572
+ if (event.origin !== targetOrigin || event.source !== ((_a2 = iframeRef.current) == null ? void 0 : _a2.contentWindow)) return;
56515
56573
  if (isAthenaAssetEmbedReadyEvent(event.data)) {
56516
56574
  sendConfig();
56517
56575
  return;
@@ -56559,7 +56617,7 @@ const AthenaAssetEmbed = ({
56559
56617
  {
56560
56618
  ...iframeProps,
56561
56619
  ref: iframeRef,
56562
- src: embedUrl,
56620
+ src: iframeSrc ?? void 0,
56563
56621
  title: title ?? `Athena asset ${assetId}`,
56564
56622
  allow,
56565
56623
  className: cn("block h-full w-full", className),