@aikaara/chat-sdk 0.7.2 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/headless.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./MountTenant-BNpG6T7E.cjs");class s extends i.EventEmitter{registration=null;pendingEdits=[];constructor(e){super(),this.setupListeners(e)}registerForm(e){this.registration=e;const t=this.pendingEdits.filter(r=>r.entity_type===e.entityType&&String(r.entity_id)===String(e.entityId));if(t.length>0){for(const r of t)e.onFieldUpdate(r.fields),this.emit("edit:applied",{entityType:r.entity_type,entityId:r.entity_id,fields:r.fields});this.pendingEdits=this.pendingEdits.filter(r=>!(r.entity_type===e.entityType&&String(r.entity_id)===String(e.entityId)))}}unregisterForm(e,t){this.registration?.entityType===e&&String(this.registration?.entityId)===String(t)&&(this.registration=null)}get currentForm(){return this.registration}pushFieldUpdates(e,t,r){this.registration&&this.registration.entityType===e&&String(this.registration.entityId)===String(t)?(this.registration.onFieldUpdate(r),this.emit("edit:applied",{entityType:e,entityId:t,fields:r})):(this.pendingEdits.push({action:"edit_entity",entity_type:e,entity_id:t,fields:r}),this.emit("edit:pending",{entityType:e,entityId:t,fields:r}))}async requestSave(){if(!this.registration)return{success:!1,error:"No form registered"};try{return await this.registration.onSave(),this.emit("save:success",{entityType:this.registration.entityType,entityId:this.registration.entityId}),{success:!0}}catch(e){const t=e instanceof Error?e.message:"Save failed";return this.emit("save:error",{entityType:this.registration.entityType,entityId:this.registration.entityId,error:t}),{success:!1,error:t}}}async requestTest(e){if(!this.registration?.onTest)return{success:!1,error:"Current form does not support testing"};try{return await this.registration.onTest(e),{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Test failed"}}}setupListeners(e){e.on("action:edit_entity",t=>{this.pushFieldUpdates(t.entity_type,t.entity_id,t.fields)}),e.on("action:save_entity",t=>{this.requestSave()}),e.on("action:test_tool",t=>{this.emit("test:triggered",{toolId:t.tool_id,parameters:t.parameters}),this.requestTest(t.parameters)})}}exports.ActionCableClient=i.ActionCableClient;exports.AikaaraChatClient=i.AikaaraChatClient;exports.ApiClient=i.ApiClient;exports.ChannelSubscription=i.ChannelSubscription;exports.ConnectionManager=i.ConnectionManager;exports.ConversationManager=i.ConversationManager;exports.EventEmitter=i.EventEmitter;exports.MessageStore=i.MessageStore;exports.SessionAuthAdapter=i.SessionAuthAdapter;exports.TiledeskTransport=i.TiledeskTransport;exports.clearPersistedConversationId=i.clearPersistedConversationId;exports.createFetchUploadAdapter=i.createFetchUploadAdapter;exports.createPresigned3StepUploadAdapter=i.createPresigned3StepUploadAdapter;exports.createTiledeskHistoryAdapter=i.createTiledeskHistoryAdapter;exports.extractTiledeskFileEnvelope=i.extractTiledeskFileEnvelope;exports.inferTiledeskRole=i.inferTiledeskRole;exports.isTiledeskSelfEcho=i.isTiledeskSelfEcho;exports.mountFromSlug=i.mountFromSlug;exports.mountTenantWidget=i.mount;exports.parseTiledeskTemplate=i.parseTiledeskTemplate;exports.FormBridge=s;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./MountTenant-Dcp2KDZo.cjs");class r extends i.EventEmitter{registration=null;pendingEdits=[];constructor(e){super(),this.setupListeners(e)}registerForm(e){this.registration=e;const t=this.pendingEdits.filter(s=>s.entity_type===e.entityType&&String(s.entity_id)===String(e.entityId));if(t.length>0){for(const s of t)e.onFieldUpdate(s.fields),this.emit("edit:applied",{entityType:s.entity_type,entityId:s.entity_id,fields:s.fields});this.pendingEdits=this.pendingEdits.filter(s=>!(s.entity_type===e.entityType&&String(s.entity_id)===String(e.entityId)))}}unregisterForm(e,t){this.registration?.entityType===e&&String(this.registration?.entityId)===String(t)&&(this.registration=null)}get currentForm(){return this.registration}pushFieldUpdates(e,t,s){this.registration&&this.registration.entityType===e&&String(this.registration.entityId)===String(t)?(this.registration.onFieldUpdate(s),this.emit("edit:applied",{entityType:e,entityId:t,fields:s})):(this.pendingEdits.push({action:"edit_entity",entity_type:e,entity_id:t,fields:s}),this.emit("edit:pending",{entityType:e,entityId:t,fields:s}))}async requestSave(){if(!this.registration)return{success:!1,error:"No form registered"};try{return await this.registration.onSave(),this.emit("save:success",{entityType:this.registration.entityType,entityId:this.registration.entityId}),{success:!0}}catch(e){const t=e instanceof Error?e.message:"Save failed";return this.emit("save:error",{entityType:this.registration.entityType,entityId:this.registration.entityId,error:t}),{success:!1,error:t}}}async requestTest(e){if(!this.registration?.onTest)return{success:!1,error:"Current form does not support testing"};try{return await this.registration.onTest(e),{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Test failed"}}}setupListeners(e){e.on("action:edit_entity",t=>{this.pushFieldUpdates(t.entity_type,t.entity_id,t.fields)}),e.on("action:save_entity",t=>{this.requestSave()}),e.on("action:test_tool",t=>{this.emit("test:triggered",{toolId:t.tool_id,parameters:t.parameters}),this.requestTest(t.parameters)})}}exports.ActionCableClient=i.ActionCableClient;exports.AikaaraChatClient=i.AikaaraChatClient;exports.ApiClient=i.ApiClient;exports.ChannelSubscription=i.ChannelSubscription;exports.ConnectionManager=i.ConnectionManager;exports.ConversationManager=i.ConversationManager;exports.EventEmitter=i.EventEmitter;exports.MessageStore=i.MessageStore;exports.SessionAuthAdapter=i.SessionAuthAdapter;exports.SsoExchangeAdapter=i.SsoExchangeAdapter;exports.TiledeskTransport=i.TiledeskTransport;exports.clearPersistedConversationId=i.clearPersistedConversationId;exports.collectSsoCredentials=i.collectSsoCredentials;exports.createFetchUploadAdapter=i.createFetchUploadAdapter;exports.createPresigned3StepUploadAdapter=i.createPresigned3StepUploadAdapter;exports.createTiledeskHistoryAdapter=i.createTiledeskHistoryAdapter;exports.extractTiledeskFileEnvelope=i.extractTiledeskFileEnvelope;exports.inferTiledeskRole=i.inferTiledeskRole;exports.isTiledeskSelfEcho=i.isTiledeskSelfEcho;exports.mountFromSlug=i.mountFromSlug;exports.mountTenantWidget=i.mount;exports.parseTiledeskTemplate=i.parseTiledeskTemplate;exports.FormBridge=r;
@@ -440,6 +440,9 @@ declare interface ChatEvents_2 {
440
440
 
441
441
  export declare function clearPersistedConversationId(userId: string, projectId: string): void;
442
442
 
443
+ /** Read every credential listed in `spec`. Throws on missing required. */
444
+ export declare function collectSsoCredentials(opts: SsoCollectorOptions): Promise<Record<string, string>>;
445
+
443
446
  export declare interface ConnectionConfig {
444
447
  baseUrl: string;
445
448
  wsUrl?: string;
@@ -531,6 +534,8 @@ export declare function createPresigned3StepUploadAdapter(config: Presigned3Step
531
534
 
532
535
  export declare function createTiledeskHistoryAdapter(config: TiledeskHistoryAdapterConfig): ConversationHistoryAdapter;
533
536
 
537
+ export declare type CredentialProviders = Record<string, () => string | Promise<string>>;
538
+
534
539
  export declare interface EditEntityAction {
535
540
  action: 'edit_entity';
536
541
  entity_type: string;
@@ -585,6 +590,34 @@ declare interface FieldUpdate_2 {
585
590
  previousValue?: unknown;
586
591
  }
587
592
 
593
+ export declare interface FlowDescriptor {
594
+ /** Heading rendered above the step list (e.g. "ITR filing process"). */
595
+ title?: string;
596
+ steps: FlowStep[];
597
+ }
598
+
599
+ /**
600
+ * Static side-rail process taxonomy (e.g. bandhan's "ITR filing process").
601
+ * Fully descriptor-driven — dashboard owns the steps. The runtime state
602
+ * (which step is `done` / `active`) is calculated host-side from chat
603
+ * events (or overlaid from a backend status endpoint like
604
+ * `/itr/life-cycle-status`).
605
+ */
606
+ export declare interface FlowStep {
607
+ /** Stable id used by the host's reducer to address this step. */
608
+ id: string;
609
+ /** Display title. */
610
+ title: string;
611
+ /** Initial status. The host's `onMessage` reducer flips these as the
612
+ * conversation progresses. */
613
+ state?: 'done' | 'active' | 'pending';
614
+ /** Optional nested sub-steps (one level deep — bandhan style). */
615
+ sub?: FlowStep[];
616
+ /** Free-form metadata the host can use in its reducer (templateId
617
+ * patterns the bot uses to advance the step, copy text, hint, etc.). */
618
+ meta?: Record<string, unknown>;
619
+ }
620
+
588
621
  export declare class FormBridge extends EventEmitter<FormBridgeEvents> {
589
622
  private registration;
590
623
  private pendingEdits;
@@ -714,7 +747,7 @@ export declare function isTiledeskSelfEcho(message: TiledeskMessage, userId: str
714
747
  * Descriptor entry for intercepting link clicks. `match` is a glob pattern
715
748
  * (`*` = any, `?` = single char) tested against the full clicked URL.
716
749
  */
717
- declare interface LinkHandler {
750
+ export declare interface LinkHandler {
718
751
  /** Glob pattern matched against the clicked URL. */
719
752
  match: string;
720
753
  /** What to do on match. `tab` opens in new tab, `iframe` uses default modal,
@@ -870,7 +903,7 @@ export declare function parseTiledeskTemplate(message: TiledeskMessage): Tiledes
870
903
  * One HTTP call run by the SDK before auth. Failure of `soft: true` steps
871
904
  * is logged and ignored; failure of strict steps aborts the mount.
872
905
  */
873
- declare interface PreflightStep {
906
+ export declare interface PreflightStep {
874
907
  url: string;
875
908
  method?: 'GET' | 'POST' | 'PUT';
876
909
  body?: Record<string, unknown>;
@@ -983,6 +1016,9 @@ export declare type SessionTokenProvider = string | (() => string | Promise<stri
983
1016
 
984
1017
  export declare interface SlugMountedWidget extends MountedTenantWidget {
985
1018
  fullName: string;
1019
+ /** Resolved descriptor (fallback ⊕ fetched ⊕ overrides). Host reads
1020
+ * `descriptor.itrFlow`, `descriptor.theme`, etc. */
1021
+ descriptor: WidgetConfigDescriptor;
986
1022
  /** Force a fresh /chatbuddy/auth-style refetch (clears cached requestId). */
987
1023
  refreshAuth(): Promise<void>;
988
1024
  }
@@ -997,6 +1033,12 @@ export declare interface SlugMountOptions {
997
1033
  /** Additional headers for the descriptor fetch. */
998
1034
  configHeaders?: Record<string, string>;
999
1035
  user: {
1036
+ /**
1037
+ * Initial identifier. When `descriptor.sso` is configured, the
1038
+ * server-issued `ext_uid` from the SSO exchange overrides this
1039
+ * value. For SSO-only flows you can pass an empty string and rely
1040
+ * on the exchange to populate the identity.
1041
+ */
1000
1042
  id: string;
1001
1043
  /** Display name fallback when descriptor.auth doesn't return one. */
1002
1044
  name?: string;
@@ -1007,12 +1049,31 @@ export declare interface SlugMountOptions {
1007
1049
  * or a getter that re-resolves on each refresh.
1008
1050
  */
1009
1051
  token: SessionTokenProvider;
1052
+ /**
1053
+ * Async getters for SSO credentials with `source: "callback"`. Each
1054
+ * key matches a `descriptor.sso.collect[].name` entry. Lets the host
1055
+ * app supply tokens that don't live in cookies / localStorage (e.g.
1056
+ * an in-memory auth context, a parent-frame postMessage).
1057
+ */
1058
+ credentialProviders?: CredentialProviders;
1059
+ /**
1060
+ * Free-form identity bag forwarded to descriptor.preflight URL and
1061
+ * body templates. Keys become `{name}` placeholders. Useful for
1062
+ * tenant-specific fields the SDK doesn't know about (`pan`, `mobile`,
1063
+ * `dob`, etc.) so the descriptor can drive the full warm-up chain
1064
+ * without host code per call.
1065
+ */
1066
+ identity?: Record<string, string | undefined>;
1010
1067
  };
1011
1068
  /** Optional escape hatches; merge over descriptor-driven defaults. */
1012
1069
  hooks?: {
1013
1070
  upload?: UploadAdapter;
1014
1071
  history?: ConversationHistoryAdapter;
1015
1072
  onError?: (err: Error) => void;
1073
+ /** Fired for every chat message (incoming + outgoing). Host apps can
1074
+ * use this to advance UI state outside the widget — e.g. update an
1075
+ * ITR-filing-process side rail when the bot moves the flow forward. */
1076
+ onMessage?: (message: Message) => void;
1016
1077
  };
1017
1078
  /** Per-mount visual overrides. */
1018
1079
  overrides?: Partial<WidgetConfigDescriptor>;
@@ -1025,6 +1086,105 @@ export declare interface SlugMountOptions {
1025
1086
  fallbackConfig?: WidgetConfigDescriptor;
1026
1087
  }
1027
1088
 
1089
+ export declare interface SsoCollectorOptions {
1090
+ /** Spec from `descriptor.sso.collect`. */
1091
+ spec: SsoCollectSpec[];
1092
+ /** Async getters for `source: "callback"` entries (host-supplied). */
1093
+ providers?: CredentialProviders;
1094
+ }
1095
+
1096
+ export declare interface SsoCollectSpec {
1097
+ /** Field name sent to aikaara-ai as `credentials[name]`. */
1098
+ name: string;
1099
+ /** Where to read it from. */
1100
+ source: SsoSourceKind;
1101
+ /** Source-specific key (cookie name, storage key, query param, etc). */
1102
+ key?: string;
1103
+ /** When true, throw if the credential is absent / empty. */
1104
+ required?: boolean;
1105
+ /** Default value if the source doesn't provide one (and not required). */
1106
+ default?: string;
1107
+ }
1108
+
1109
+ export declare interface SsoDescriptor {
1110
+ /**
1111
+ * Aikaara-ai endpoint that runs the server-side SSO + provisioning chain.
1112
+ * Optional — when omitted the SDK derives it from the same `configBase`
1113
+ * it used to fetch `widget_configs/:slug`:
1114
+ * `${configBase}/api/v1/projects/by-slug/${slug}/sso_exchange`
1115
+ * Set this only when self-hosted aikaara-ai sits at a different host
1116
+ * than the widget-config endpoint.
1117
+ */
1118
+ exchangeEndpoint?: string;
1119
+ /** localStorage key for the cached identity. Null/empty → no cache. */
1120
+ cacheKey?: string;
1121
+ /** Cache TTL in seconds. Default 1800 (30 min). */
1122
+ cacheTtlSec?: number;
1123
+ /** Per-widget API key sent as `X-Api-Key` to aikaara-ai. */
1124
+ apiKey?: string;
1125
+ /** Extra static headers attached to the exchange POST. */
1126
+ headers?: Record<string, string>;
1127
+ /** Browser credential collection spec. */
1128
+ collect: SsoCollectSpec[];
1129
+ }
1130
+
1131
+ export declare class SsoExchangeAdapter {
1132
+ private readonly opts;
1133
+ private cache;
1134
+ private inflight;
1135
+ constructor(opts: SsoExchangeOptions);
1136
+ /** Drop any cached identity. Forces a fresh exchange on next `get()`. */
1137
+ reset(): void;
1138
+ /**
1139
+ * Resolve the SSO identity. Returns cached when fresh; otherwise runs the
1140
+ * collect → POST → response flow once and caches the result.
1141
+ */
1142
+ get(force?: boolean): Promise<SsoIdentity>;
1143
+ private exchange;
1144
+ private computeExpiry;
1145
+ private loadCache;
1146
+ private persistCache;
1147
+ private clearCache;
1148
+ }
1149
+
1150
+ export declare interface SsoExchangeOptions {
1151
+ descriptor: SsoDescriptor;
1152
+ /** Host-supplied async getters for `source: "callback"` entries. */
1153
+ providers?: CredentialProviders;
1154
+ /**
1155
+ * Resolved exchange URL. When `descriptor.exchangeEndpoint` is set it
1156
+ * wins; otherwise `mountFromSlug` builds this from
1157
+ * `${configBase}/api/v1/projects/by-slug/${slug}/sso_exchange`.
1158
+ */
1159
+ exchangeUrl?: string;
1160
+ }
1161
+
1162
+ export declare interface SsoIdentity {
1163
+ /** Aikaara `User.id` (UUID/int). Useful for support / audit. */
1164
+ id?: string | number;
1165
+ /** Partner system user id, mirrored as Aikaara `User.ext_uid`. */
1166
+ extUid: string;
1167
+ /** Aikaara user token (ActionCable / Aikaara REST bearer). */
1168
+ userToken: string;
1169
+ email?: string;
1170
+ displayName?: string;
1171
+ /** Free-form properties the provisioner wrote on the user row. */
1172
+ properties?: Record<string, unknown>;
1173
+ /** Unix-ms expiry for the cache row (not the token itself). */
1174
+ expiresAt?: number;
1175
+ }
1176
+
1177
+ /**
1178
+ * Browser-side credential collector for `descriptor.sso.collect`.
1179
+ *
1180
+ * Each entry tells the SDK where to read one credential from. The collected
1181
+ * map gets POSTed to aikaara-ai's `sso_exchange` endpoint, where the
1182
+ * server-side resolver swaps it for a partner identity + provisions an
1183
+ * Aikaara user. No secrets ever live in the public descriptor — this just
1184
+ * tells us "go look at cookie X" or "ask the host app for token Y".
1185
+ */
1186
+ export declare type SsoSourceKind = 'cookie' | 'localStorage' | 'sessionStorage' | 'url_param' | 'header_meta' | 'callback';
1187
+
1028
1188
  declare type SubscriptionCallback = (data: unknown) => void;
1029
1189
 
1030
1190
  declare interface TemplateMessageEvent {
@@ -1084,8 +1244,17 @@ export declare interface TenantMountOptions {
1084
1244
  overrides?: Partial<WidgetConfigDescriptor>;
1085
1245
  /** Surfaced from the SDK. */
1086
1246
  onError?: (err: Error) => void;
1247
+ /** Forwarded to `WidgetConfig.onMessage` — fires for every message. */
1248
+ onMessage?: (message: Message) => void;
1087
1249
  /** Bearer source for descriptor.linkHandlers fetches. */
1088
1250
  getLinkBearer?: (source: 'session' | 'chat' | 'none') => Promise<string | null>;
1251
+ /**
1252
+ * Aikaara user token used by the ActionCable transport
1253
+ * (`?token=<userToken>` on the cable URL). Comes from the SSO exchange
1254
+ * when present. Tiledesk-only widgets ignore it; defaults to `userId`
1255
+ * for backwards compatibility.
1256
+ */
1257
+ userToken?: string;
1089
1258
  }
1090
1259
 
1091
1260
  export declare interface TestToolAction {
@@ -1577,6 +1746,12 @@ export declare interface WidgetConfigDescriptor {
1577
1746
  };
1578
1747
  /** Defaults merged into every form-action postback */
1579
1748
  templateActionAttributes?: Record<string, unknown>;
1749
+ /**
1750
+ * Static side-rail flow (e.g. bandhan's "ITR filing process"). The
1751
+ * dashboard owns this — host renders it next to the chat. Live state
1752
+ * is overlaid by host code from chat events / status endpoints.
1753
+ */
1754
+ itrFlow?: FlowDescriptor;
1580
1755
  /** Adapter endpoints — SDK builds the actual fetch calls */
1581
1756
  uploadEndpoint?: string;
1582
1757
  uploadFieldName?: string;
@@ -1595,6 +1770,17 @@ export declare interface WidgetConfigDescriptor {
1595
1770
  * itself — the host app no longer needs a `tokenProvider` callback.
1596
1771
  */
1597
1772
  auth?: SessionAuthDescriptor;
1773
+ /**
1774
+ * Aikaara-ai-side SSO + provisioning. When present, the SDK collects the
1775
+ * partner credentials listed in `sso.collect`, POSTs them to
1776
+ * `sso.exchangeEndpoint`, and aikaara-ai resolves a partner identity +
1777
+ * provisions an Aikaara user. The returned `ext_uid` overrides
1778
+ * `opts.user.id` and the returned `userToken` populates
1779
+ * `widgetConfig.userToken` (used by the ActionCable transport). This
1780
+ * runs **before** `auth` — so partner SSO seeds the identity, then
1781
+ * `auth` mints chat-platform JWTs against that identity.
1782
+ */
1783
+ sso?: SsoDescriptor;
1598
1784
  /**
1599
1785
  * HTTP calls fired in order before `auth`. Use for backend warmups whose
1600
1786
  * side effects the auth call depends on (e.g. bandhan's bootstrap
@@ -1664,7 +1850,7 @@ export declare interface WidgetConfigDescriptor {
1664
1850
  * (`--aikaara-<kebab-cased-key>`), so renderers (built-in or
1665
1851
  * tenant-supplied) can style themselves consistently.
1666
1852
  */
1667
- declare interface WidgetTheme {
1853
+ export declare interface WidgetTheme {
1668
1854
  primary?: string;
1669
1855
  primaryHover?: string;
1670
1856
  primaryContrast?: string;
package/dist/headless.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { E as s } from "./MountTenant-Bdm9wkBa.mjs";
2
- import { A as p, b as g, k as l, C as h, l as y, m as c, M as u, S as m, T as f, n as T, o as S, p as _, q as v, s as E, t as C, u as F, v as A, w as k, x as I } from "./MountTenant-Bdm9wkBa.mjs";
1
+ import { E as s } from "./MountTenant-7DxQIsTh.mjs";
2
+ import { A as p, b as l, k as g, C as h, l as c, m as y, M as u, S as m, n as f, T as S, o as T, p as _, q as E, s as v, t as C, u as F, v as A, w as k, x as I, y as x, z as U } from "./MountTenant-7DxQIsTh.mjs";
3
3
  class a extends s {
4
4
  registration = null;
5
5
  pendingEdits = [];
@@ -94,24 +94,26 @@ class a extends s {
94
94
  }
95
95
  export {
96
96
  p as ActionCableClient,
97
- g as AikaaraChatClient,
98
- l as ApiClient,
97
+ l as AikaaraChatClient,
98
+ g as ApiClient,
99
99
  h as ChannelSubscription,
100
- y as ConnectionManager,
101
- c as ConversationManager,
100
+ c as ConnectionManager,
101
+ y as ConversationManager,
102
102
  s as EventEmitter,
103
103
  a as FormBridge,
104
104
  u as MessageStore,
105
105
  m as SessionAuthAdapter,
106
- f as TiledeskTransport,
106
+ f as SsoExchangeAdapter,
107
+ S as TiledeskTransport,
107
108
  T as clearPersistedConversationId,
108
- S as createFetchUploadAdapter,
109
- _ as createPresigned3StepUploadAdapter,
110
- v as createTiledeskHistoryAdapter,
111
- E as extractTiledeskFileEnvelope,
112
- C as inferTiledeskRole,
113
- F as isTiledeskSelfEcho,
114
- A as mountFromSlug,
115
- k as mountTenantWidget,
116
- I as parseTiledeskTemplate
109
+ _ as collectSsoCredentials,
110
+ E as createFetchUploadAdapter,
111
+ v as createPresigned3StepUploadAdapter,
112
+ C as createTiledeskHistoryAdapter,
113
+ F as extractTiledeskFileEnvelope,
114
+ A as inferTiledeskRole,
115
+ k as isTiledeskSelfEcho,
116
+ I as mountFromSlug,
117
+ x as mountTenantWidget,
118
+ U as parseTiledeskTemplate
117
119
  };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MountTenant-BNpG6T7E.cjs"),s=require("./headless.cjs");function l(a){e.registerComponents();const t=document.createElement("aikaara-chat-widget"),i={baseUrl:"base-url",userToken:"user-token",apiKey:"api-key",title:"title",subtitle:"subtitle",theme:"theme",primaryColor:"primary-color",position:"position",width:"width",height:"height",placeholder:"placeholder",welcomeMessage:"welcome-message",avatarUrl:"avatar-url"};for(const[n,o]of Object.entries(i)){const r=a[n];r!=null&&t.setAttribute(o,String(r))}return t.configure(a),document.body.appendChild(t),t}function d(){const a=document.querySelector("aikaara-chat-widget");a&&a.remove()}exports.ActionCableClient=e.ActionCableClient;exports.AikaaraChatBubble=e.AikaaraChatBubble;exports.AikaaraChatClient=e.AikaaraChatClient;exports.AikaaraChatHeader=e.AikaaraChatHeader;exports.AikaaraChatInput=e.AikaaraChatInput;exports.AikaaraChatWidget=e.AikaaraChatWidget;exports.AikaaraErrorBanner=e.AikaaraErrorBanner;exports.AikaaraMessageBubble=e.AikaaraMessageBubble;exports.AikaaraMessageList=e.AikaaraMessageList;exports.AikaaraStreamingMessage=e.AikaaraStreamingMessage;exports.AikaaraTypingIndicator=e.AikaaraTypingIndicator;exports.ApiClient=e.ApiClient;exports.ChannelSubscription=e.ChannelSubscription;exports.ConnectionManager=e.ConnectionManager;exports.ConversationManager=e.ConversationManager;exports.EventEmitter=e.EventEmitter;exports.MessageStore=e.MessageStore;exports.SessionAuthAdapter=e.SessionAuthAdapter;exports.TiledeskTransport=e.TiledeskTransport;exports.clearPersistedConversationId=e.clearPersistedConversationId;exports.createFetchUploadAdapter=e.createFetchUploadAdapter;exports.createPresigned3StepUploadAdapter=e.createPresigned3StepUploadAdapter;exports.createTiledeskHistoryAdapter=e.createTiledeskHistoryAdapter;exports.extractTiledeskFileEnvelope=e.extractTiledeskFileEnvelope;exports.inferTiledeskRole=e.inferTiledeskRole;exports.isTiledeskSelfEcho=e.isTiledeskSelfEcho;exports.mountFromSlug=e.mountFromSlug;exports.mountTenantWidget=e.mount;exports.parseTiledeskTemplate=e.parseTiledeskTemplate;exports.registerComponents=e.registerComponents;exports.FormBridge=s.FormBridge;exports.mount=l;exports.unmount=d;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MountTenant-Dcp2KDZo.cjs"),s=require("./headless.cjs");function l(a){e.registerComponents();const t=document.createElement("aikaara-chat-widget"),i={baseUrl:"base-url",userToken:"user-token",apiKey:"api-key",title:"title",subtitle:"subtitle",theme:"theme",primaryColor:"primary-color",position:"position",width:"width",height:"height",placeholder:"placeholder",welcomeMessage:"welcome-message",avatarUrl:"avatar-url"};for(const[n,o]of Object.entries(i)){const r=a[n];r!=null&&t.setAttribute(o,String(r))}return t.configure(a),document.body.appendChild(t),t}function d(){const a=document.querySelector("aikaara-chat-widget");a&&a.remove()}exports.ActionCableClient=e.ActionCableClient;exports.AikaaraChatBubble=e.AikaaraChatBubble;exports.AikaaraChatClient=e.AikaaraChatClient;exports.AikaaraChatHeader=e.AikaaraChatHeader;exports.AikaaraChatInput=e.AikaaraChatInput;exports.AikaaraChatWidget=e.AikaaraChatWidget;exports.AikaaraErrorBanner=e.AikaaraErrorBanner;exports.AikaaraMessageBubble=e.AikaaraMessageBubble;exports.AikaaraMessageList=e.AikaaraMessageList;exports.AikaaraStreamingMessage=e.AikaaraStreamingMessage;exports.AikaaraTypingIndicator=e.AikaaraTypingIndicator;exports.ApiClient=e.ApiClient;exports.ChannelSubscription=e.ChannelSubscription;exports.ConnectionManager=e.ConnectionManager;exports.ConversationManager=e.ConversationManager;exports.EventEmitter=e.EventEmitter;exports.MessageStore=e.MessageStore;exports.SessionAuthAdapter=e.SessionAuthAdapter;exports.SsoExchangeAdapter=e.SsoExchangeAdapter;exports.TiledeskTransport=e.TiledeskTransport;exports.clearPersistedConversationId=e.clearPersistedConversationId;exports.collectSsoCredentials=e.collectSsoCredentials;exports.createFetchUploadAdapter=e.createFetchUploadAdapter;exports.createPresigned3StepUploadAdapter=e.createPresigned3StepUploadAdapter;exports.createTiledeskHistoryAdapter=e.createTiledeskHistoryAdapter;exports.extractTiledeskFileEnvelope=e.extractTiledeskFileEnvelope;exports.inferTiledeskRole=e.inferTiledeskRole;exports.isTiledeskSelfEcho=e.isTiledeskSelfEcho;exports.mountFromSlug=e.mountFromSlug;exports.mountTenantWidget=e.mount;exports.parseTiledeskTemplate=e.parseTiledeskTemplate;exports.registerComponents=e.registerComponents;exports.FormBridge=s.FormBridge;exports.mount=l;exports.unmount=d;
package/dist/index.d.ts CHANGED
@@ -407,6 +407,9 @@ export declare interface ChatEvents {
407
407
 
408
408
  export declare function clearPersistedConversationId(userId: string, projectId: string): void;
409
409
 
410
+ /** Read every credential listed in `spec`. Throws on missing required. */
411
+ export declare function collectSsoCredentials(opts: SsoCollectorOptions): Promise<Record<string, string>>;
412
+
410
413
  export declare interface ConnectionConfig {
411
414
  baseUrl: string;
412
415
  wsUrl?: string;
@@ -473,6 +476,8 @@ export declare function createPresigned3StepUploadAdapter(config: Presigned3Step
473
476
 
474
477
  export declare function createTiledeskHistoryAdapter(config: TiledeskHistoryAdapterConfig): ConversationHistoryAdapter;
475
478
 
479
+ export declare type CredentialProviders = Record<string, () => string | Promise<string>>;
480
+
476
481
  export declare interface EditEntityAction {
477
482
  action: 'edit_entity';
478
483
  entity_type: string;
@@ -506,6 +511,34 @@ export declare interface FieldUpdate {
506
511
  previousValue?: unknown;
507
512
  }
508
513
 
514
+ export declare interface FlowDescriptor {
515
+ /** Heading rendered above the step list (e.g. "ITR filing process"). */
516
+ title?: string;
517
+ steps: FlowStep[];
518
+ }
519
+
520
+ /**
521
+ * Static side-rail process taxonomy (e.g. bandhan's "ITR filing process").
522
+ * Fully descriptor-driven — dashboard owns the steps. The runtime state
523
+ * (which step is `done` / `active`) is calculated host-side from chat
524
+ * events (or overlaid from a backend status endpoint like
525
+ * `/itr/life-cycle-status`).
526
+ */
527
+ export declare interface FlowStep {
528
+ /** Stable id used by the host's reducer to address this step. */
529
+ id: string;
530
+ /** Display title. */
531
+ title: string;
532
+ /** Initial status. The host's `onMessage` reducer flips these as the
533
+ * conversation progresses. */
534
+ state?: 'done' | 'active' | 'pending';
535
+ /** Optional nested sub-steps (one level deep — bandhan style). */
536
+ sub?: FlowStep[];
537
+ /** Free-form metadata the host can use in its reducer (templateId
538
+ * patterns the bot uses to advance the step, copy text, hint, etc.). */
539
+ meta?: Record<string, unknown>;
540
+ }
541
+
509
542
  export declare class FormBridge extends EventEmitter<FormBridgeEvents> {
510
543
  private registration;
511
544
  private pendingEdits;
@@ -635,7 +668,7 @@ export declare function isTiledeskSelfEcho(message: TiledeskMessage, userId: str
635
668
  * Descriptor entry for intercepting link clicks. `match` is a glob pattern
636
669
  * (`*` = any, `?` = single char) tested against the full clicked URL.
637
670
  */
638
- declare interface LinkHandler {
671
+ export declare interface LinkHandler {
639
672
  /** Glob pattern matched against the clicked URL. */
640
673
  match: string;
641
674
  /** What to do on match. `tab` opens in new tab, `iframe` uses default modal,
@@ -763,7 +796,7 @@ export declare function parseTiledeskTemplate(message: TiledeskMessage): Tiledes
763
796
  * One HTTP call run by the SDK before auth. Failure of `soft: true` steps
764
797
  * is logged and ignored; failure of strict steps aborts the mount.
765
798
  */
766
- declare interface PreflightStep {
799
+ export declare interface PreflightStep {
767
800
  url: string;
768
801
  method?: 'GET' | 'POST' | 'PUT';
769
802
  body?: Record<string, unknown>;
@@ -874,6 +907,9 @@ export declare type SessionTokenProvider = string | (() => string | Promise<stri
874
907
 
875
908
  export declare interface SlugMountedWidget extends MountedTenantWidget {
876
909
  fullName: string;
910
+ /** Resolved descriptor (fallback ⊕ fetched ⊕ overrides). Host reads
911
+ * `descriptor.itrFlow`, `descriptor.theme`, etc. */
912
+ descriptor: WidgetConfigDescriptor;
877
913
  /** Force a fresh /chatbuddy/auth-style refetch (clears cached requestId). */
878
914
  refreshAuth(): Promise<void>;
879
915
  }
@@ -888,6 +924,12 @@ export declare interface SlugMountOptions {
888
924
  /** Additional headers for the descriptor fetch. */
889
925
  configHeaders?: Record<string, string>;
890
926
  user: {
927
+ /**
928
+ * Initial identifier. When `descriptor.sso` is configured, the
929
+ * server-issued `ext_uid` from the SSO exchange overrides this
930
+ * value. For SSO-only flows you can pass an empty string and rely
931
+ * on the exchange to populate the identity.
932
+ */
891
933
  id: string;
892
934
  /** Display name fallback when descriptor.auth doesn't return one. */
893
935
  name?: string;
@@ -898,12 +940,31 @@ export declare interface SlugMountOptions {
898
940
  * or a getter that re-resolves on each refresh.
899
941
  */
900
942
  token: SessionTokenProvider;
943
+ /**
944
+ * Async getters for SSO credentials with `source: "callback"`. Each
945
+ * key matches a `descriptor.sso.collect[].name` entry. Lets the host
946
+ * app supply tokens that don't live in cookies / localStorage (e.g.
947
+ * an in-memory auth context, a parent-frame postMessage).
948
+ */
949
+ credentialProviders?: CredentialProviders;
950
+ /**
951
+ * Free-form identity bag forwarded to descriptor.preflight URL and
952
+ * body templates. Keys become `{name}` placeholders. Useful for
953
+ * tenant-specific fields the SDK doesn't know about (`pan`, `mobile`,
954
+ * `dob`, etc.) so the descriptor can drive the full warm-up chain
955
+ * without host code per call.
956
+ */
957
+ identity?: Record<string, string | undefined>;
901
958
  };
902
959
  /** Optional escape hatches; merge over descriptor-driven defaults. */
903
960
  hooks?: {
904
961
  upload?: UploadAdapter;
905
962
  history?: ConversationHistoryAdapter;
906
963
  onError?: (err: Error) => void;
964
+ /** Fired for every chat message (incoming + outgoing). Host apps can
965
+ * use this to advance UI state outside the widget — e.g. update an
966
+ * ITR-filing-process side rail when the bot moves the flow forward. */
967
+ onMessage?: (message: Message) => void;
907
968
  };
908
969
  /** Per-mount visual overrides. */
909
970
  overrides?: Partial<WidgetConfigDescriptor>;
@@ -916,6 +977,105 @@ export declare interface SlugMountOptions {
916
977
  fallbackConfig?: WidgetConfigDescriptor;
917
978
  }
918
979
 
980
+ export declare interface SsoCollectorOptions {
981
+ /** Spec from `descriptor.sso.collect`. */
982
+ spec: SsoCollectSpec[];
983
+ /** Async getters for `source: "callback"` entries (host-supplied). */
984
+ providers?: CredentialProviders;
985
+ }
986
+
987
+ export declare interface SsoCollectSpec {
988
+ /** Field name sent to aikaara-ai as `credentials[name]`. */
989
+ name: string;
990
+ /** Where to read it from. */
991
+ source: SsoSourceKind;
992
+ /** Source-specific key (cookie name, storage key, query param, etc). */
993
+ key?: string;
994
+ /** When true, throw if the credential is absent / empty. */
995
+ required?: boolean;
996
+ /** Default value if the source doesn't provide one (and not required). */
997
+ default?: string;
998
+ }
999
+
1000
+ export declare interface SsoDescriptor {
1001
+ /**
1002
+ * Aikaara-ai endpoint that runs the server-side SSO + provisioning chain.
1003
+ * Optional — when omitted the SDK derives it from the same `configBase`
1004
+ * it used to fetch `widget_configs/:slug`:
1005
+ * `${configBase}/api/v1/projects/by-slug/${slug}/sso_exchange`
1006
+ * Set this only when self-hosted aikaara-ai sits at a different host
1007
+ * than the widget-config endpoint.
1008
+ */
1009
+ exchangeEndpoint?: string;
1010
+ /** localStorage key for the cached identity. Null/empty → no cache. */
1011
+ cacheKey?: string;
1012
+ /** Cache TTL in seconds. Default 1800 (30 min). */
1013
+ cacheTtlSec?: number;
1014
+ /** Per-widget API key sent as `X-Api-Key` to aikaara-ai. */
1015
+ apiKey?: string;
1016
+ /** Extra static headers attached to the exchange POST. */
1017
+ headers?: Record<string, string>;
1018
+ /** Browser credential collection spec. */
1019
+ collect: SsoCollectSpec[];
1020
+ }
1021
+
1022
+ export declare class SsoExchangeAdapter {
1023
+ private readonly opts;
1024
+ private cache;
1025
+ private inflight;
1026
+ constructor(opts: SsoExchangeOptions);
1027
+ /** Drop any cached identity. Forces a fresh exchange on next `get()`. */
1028
+ reset(): void;
1029
+ /**
1030
+ * Resolve the SSO identity. Returns cached when fresh; otherwise runs the
1031
+ * collect → POST → response flow once and caches the result.
1032
+ */
1033
+ get(force?: boolean): Promise<SsoIdentity>;
1034
+ private exchange;
1035
+ private computeExpiry;
1036
+ private loadCache;
1037
+ private persistCache;
1038
+ private clearCache;
1039
+ }
1040
+
1041
+ export declare interface SsoExchangeOptions {
1042
+ descriptor: SsoDescriptor;
1043
+ /** Host-supplied async getters for `source: "callback"` entries. */
1044
+ providers?: CredentialProviders;
1045
+ /**
1046
+ * Resolved exchange URL. When `descriptor.exchangeEndpoint` is set it
1047
+ * wins; otherwise `mountFromSlug` builds this from
1048
+ * `${configBase}/api/v1/projects/by-slug/${slug}/sso_exchange`.
1049
+ */
1050
+ exchangeUrl?: string;
1051
+ }
1052
+
1053
+ export declare interface SsoIdentity {
1054
+ /** Aikaara `User.id` (UUID/int). Useful for support / audit. */
1055
+ id?: string | number;
1056
+ /** Partner system user id, mirrored as Aikaara `User.ext_uid`. */
1057
+ extUid: string;
1058
+ /** Aikaara user token (ActionCable / Aikaara REST bearer). */
1059
+ userToken: string;
1060
+ email?: string;
1061
+ displayName?: string;
1062
+ /** Free-form properties the provisioner wrote on the user row. */
1063
+ properties?: Record<string, unknown>;
1064
+ /** Unix-ms expiry for the cache row (not the token itself). */
1065
+ expiresAt?: number;
1066
+ }
1067
+
1068
+ /**
1069
+ * Browser-side credential collector for `descriptor.sso.collect`.
1070
+ *
1071
+ * Each entry tells the SDK where to read one credential from. The collected
1072
+ * map gets POSTed to aikaara-ai's `sso_exchange` endpoint, where the
1073
+ * server-side resolver swaps it for a partner identity + provisions an
1074
+ * Aikaara user. No secrets ever live in the public descriptor — this just
1075
+ * tells us "go look at cookie X" or "ask the host app for token Y".
1076
+ */
1077
+ export declare type SsoSourceKind = 'cookie' | 'localStorage' | 'sessionStorage' | 'url_param' | 'header_meta' | 'callback';
1078
+
919
1079
  declare type SubscriptionCallback = (data: unknown) => void;
920
1080
 
921
1081
  declare interface TemplateMessageEvent {
@@ -964,8 +1124,17 @@ export declare interface TenantMountOptions {
964
1124
  overrides?: Partial<WidgetConfigDescriptor>;
965
1125
  /** Surfaced from the SDK. */
966
1126
  onError?: (err: Error) => void;
1127
+ /** Forwarded to `WidgetConfig.onMessage` — fires for every message. */
1128
+ onMessage?: (message: Message) => void;
967
1129
  /** Bearer source for descriptor.linkHandlers fetches. */
968
1130
  getLinkBearer?: (source: 'session' | 'chat' | 'none') => Promise<string | null>;
1131
+ /**
1132
+ * Aikaara user token used by the ActionCable transport
1133
+ * (`?token=<userToken>` on the cable URL). Comes from the SSO exchange
1134
+ * when present. Tiledesk-only widgets ignore it; defaults to `userId`
1135
+ * for backwards compatibility.
1136
+ */
1137
+ userToken?: string;
969
1138
  }
970
1139
 
971
1140
  export declare interface TestToolAction {
@@ -1329,6 +1498,12 @@ export declare interface WidgetConfigDescriptor {
1329
1498
  };
1330
1499
  /** Defaults merged into every form-action postback */
1331
1500
  templateActionAttributes?: Record<string, unknown>;
1501
+ /**
1502
+ * Static side-rail flow (e.g. bandhan's "ITR filing process"). The
1503
+ * dashboard owns this — host renders it next to the chat. Live state
1504
+ * is overlaid by host code from chat events / status endpoints.
1505
+ */
1506
+ itrFlow?: FlowDescriptor;
1332
1507
  /** Adapter endpoints — SDK builds the actual fetch calls */
1333
1508
  uploadEndpoint?: string;
1334
1509
  uploadFieldName?: string;
@@ -1347,6 +1522,17 @@ export declare interface WidgetConfigDescriptor {
1347
1522
  * itself — the host app no longer needs a `tokenProvider` callback.
1348
1523
  */
1349
1524
  auth?: SessionAuthDescriptor;
1525
+ /**
1526
+ * Aikaara-ai-side SSO + provisioning. When present, the SDK collects the
1527
+ * partner credentials listed in `sso.collect`, POSTs them to
1528
+ * `sso.exchangeEndpoint`, and aikaara-ai resolves a partner identity +
1529
+ * provisions an Aikaara user. The returned `ext_uid` overrides
1530
+ * `opts.user.id` and the returned `userToken` populates
1531
+ * `widgetConfig.userToken` (used by the ActionCable transport). This
1532
+ * runs **before** `auth` — so partner SSO seeds the identity, then
1533
+ * `auth` mints chat-platform JWTs against that identity.
1534
+ */
1535
+ sso?: SsoDescriptor;
1350
1536
  /**
1351
1537
  * HTTP calls fired in order before `auth`. Use for backend warmups whose
1352
1538
  * side effects the auth call depends on (e.g. bandhan's bootstrap
@@ -1416,7 +1602,7 @@ export declare interface WidgetConfigDescriptor {
1416
1602
  * (`--aikaara-<kebab-cased-key>`), so renderers (built-in or
1417
1603
  * tenant-supplied) can style themselves consistently.
1418
1604
  */
1419
- declare interface WidgetTheme {
1605
+ export declare interface WidgetTheme {
1420
1606
  primary?: string;
1421
1607
  primaryHover?: string;
1422
1608
  primaryContrast?: string;