@aikaara/chat-sdk 0.3.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{cdn/aikaara-chat.iife.js → MountTenant-B4Py61gI.cjs} +33 -33
- package/dist/{ui-BMGa0gZH.mjs → MountTenant-DT5Vr6Yr.mjs} +4415 -3957
- package/dist/headless.cjs +1 -1
- package/dist/headless.d.ts +175 -0
- package/dist/headless.mjs +54 -251
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +175 -0
- package/dist/index.mjs +31 -28
- package/dist/ui.cjs +1 -1
- package/dist/ui.d.ts +34 -0
- package/dist/ui.mjs +14 -13
- package/package.json +1 -1
- package/dist/ui-B0-Np9Dn.cjs +0 -792
package/dist/headless.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./MountTenant-B4Py61gI.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;
|
package/dist/headless.d.ts
CHANGED
|
@@ -514,6 +514,8 @@ declare interface CreateConversationResponse {
|
|
|
514
514
|
|
|
515
515
|
export declare function createFetchUploadAdapter(config: FetchUploadAdapterConfig): UploadAdapter;
|
|
516
516
|
|
|
517
|
+
export declare function createPresigned3StepUploadAdapter(config: Presigned3StepAdapterConfig): UploadAdapter;
|
|
518
|
+
|
|
517
519
|
export declare function createTiledeskHistoryAdapter(config: TiledeskHistoryAdapterConfig): ConversationHistoryAdapter;
|
|
518
520
|
|
|
519
521
|
export declare interface EditEntityAction {
|
|
@@ -789,6 +791,22 @@ export declare interface MountedTenantWidget {
|
|
|
789
791
|
destroy: () => void;
|
|
790
792
|
}
|
|
791
793
|
|
|
794
|
+
/**
|
|
795
|
+
* Single-call mount. Pulls the descriptor from `widget_configs/:slug`, runs
|
|
796
|
+
* descriptor.auth to mint chat JWT + requestId, builds upload + history
|
|
797
|
+
* adapters from descriptor.upload, and mounts the web component. Host app
|
|
798
|
+
* supplies only the user id + their session JWT.
|
|
799
|
+
*
|
|
800
|
+
* import { mountFromSlug } from '@aikaara/chat-sdk';
|
|
801
|
+
*
|
|
802
|
+
* await mountFromSlug({
|
|
803
|
+
* container: '#chat',
|
|
804
|
+
* slug: 'bandhan-itr',
|
|
805
|
+
* user: { id: '33568', token: () => getCognitoJwt() },
|
|
806
|
+
* });
|
|
807
|
+
*/
|
|
808
|
+
export declare function mountFromSlug(opts: SlugMountOptions): Promise<SlugMountedWidget>;
|
|
809
|
+
|
|
792
810
|
/**
|
|
793
811
|
* Standard tenant mount. Fetches the descriptor (when `configUrl` is set),
|
|
794
812
|
* merges per-mount overrides, builds default adapters from the descriptor's
|
|
@@ -806,6 +824,39 @@ declare interface NavigateAction_2 {
|
|
|
806
824
|
|
|
807
825
|
export declare function parseTiledeskTemplate(message: TiledeskMessage): TiledeskParsedTemplate;
|
|
808
826
|
|
|
827
|
+
/**
|
|
828
|
+
* Three-step presigned-S3 upload (sign → PUT → register). Driven entirely
|
|
829
|
+
* by descriptor — no tenant-specific code in host apps.
|
|
830
|
+
*/
|
|
831
|
+
export declare interface Presigned3StepAdapterConfig {
|
|
832
|
+
/** GET endpoint that returns a presigned URL. `{fileName}` placeholder. */
|
|
833
|
+
signEndpoint: string;
|
|
834
|
+
signMethod?: 'GET' | 'POST';
|
|
835
|
+
/** Dot path into the response JSON for the presigned URL. Default `data.s3SignedUrl`. */
|
|
836
|
+
signedUrlPath?: string;
|
|
837
|
+
/** Optional POST registering the upload (e.g. `/chatbuddy/file-upload`). */
|
|
838
|
+
registerEndpoint?: string;
|
|
839
|
+
/**
|
|
840
|
+
* Body JSON for the register POST. Tokens: `{fileName}`, `{userId}`,
|
|
841
|
+
* `{requestId}` (alias `{conversationId}`).
|
|
842
|
+
*/
|
|
843
|
+
registerBody?: Record<string, unknown>;
|
|
844
|
+
/**
|
|
845
|
+
* Final URL the chat message will carry. Tokens: `{fileName}`, `{userId}`,
|
|
846
|
+
* `{requestId}`. When omitted the presigned URL itself is used.
|
|
847
|
+
*/
|
|
848
|
+
viewerTemplate?: string;
|
|
849
|
+
/**
|
|
850
|
+
* Rewrite the host portion of the presigned URL before PUTting (used for
|
|
851
|
+
* dev proxies). E.g. `/s3-upload`. Leave empty for direct.
|
|
852
|
+
*/
|
|
853
|
+
s3HostRewrite?: string;
|
|
854
|
+
/** Bearer token getter for sign + register calls. */
|
|
855
|
+
authHeader?: () => string | Promise<string>;
|
|
856
|
+
/** Static extra headers for sign + register. */
|
|
857
|
+
extraHeaders?: Record<string, string>;
|
|
858
|
+
}
|
|
859
|
+
|
|
809
860
|
export declare interface SaveEntityAction {
|
|
810
861
|
action: 'save_entity';
|
|
811
862
|
}
|
|
@@ -814,6 +865,108 @@ declare interface SaveEntityAction_2 {
|
|
|
814
865
|
action: 'save_entity';
|
|
815
866
|
}
|
|
816
867
|
|
|
868
|
+
export declare class SessionAuthAdapter {
|
|
869
|
+
private readonly descriptor;
|
|
870
|
+
private readonly sessionToken;
|
|
871
|
+
private cache;
|
|
872
|
+
private inflight;
|
|
873
|
+
constructor(descriptor: SessionAuthDescriptor, sessionToken: SessionTokenProvider);
|
|
874
|
+
/** Force-refresh by clearing cache. Next `get()` call refetches. */
|
|
875
|
+
reset(): void;
|
|
876
|
+
get(): Promise<SessionAuthData>;
|
|
877
|
+
private fetchOnce;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
export declare interface SessionAuthData {
|
|
881
|
+
token: string;
|
|
882
|
+
requestId: string;
|
|
883
|
+
fullName: string;
|
|
884
|
+
expiresAt: number;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* Descriptor-driven session auth.
|
|
889
|
+
*
|
|
890
|
+
* The host app supplies a "session token" — typically a JWT issued by their
|
|
891
|
+
* own auth (Cognito/Auth0/firebase/etc) — and the descriptor declares how to
|
|
892
|
+
* exchange it for a chat-platform JWT + conversation requestId. The SDK runs
|
|
893
|
+
* the exchange itself, caches the result, and refreshes when the chat JWT
|
|
894
|
+
* approaches expiry. The original requestId is preserved across refreshes so
|
|
895
|
+
* the conversation thread is stable.
|
|
896
|
+
*/
|
|
897
|
+
export declare interface SessionAuthDescriptor {
|
|
898
|
+
/** Absolute or same-origin URL — POSTed with the session token as bearer. */
|
|
899
|
+
endpoint: string;
|
|
900
|
+
method?: 'POST' | 'GET';
|
|
901
|
+
/** JSON body for the request. POST only. */
|
|
902
|
+
body?: Record<string, unknown>;
|
|
903
|
+
/** Extra static headers (e.g. partnerid). */
|
|
904
|
+
headers?: Record<string, string>;
|
|
905
|
+
/** Header carrying the session token. Default `Authorization`. */
|
|
906
|
+
authHeader?: string;
|
|
907
|
+
/**
|
|
908
|
+
* Template for the session-token header value. `{token}` is replaced.
|
|
909
|
+
* Default: `Bearer {token}`. Use `JWT {token}` etc. when required.
|
|
910
|
+
*/
|
|
911
|
+
authHeaderTemplate?: string;
|
|
912
|
+
/** Dot path into the response JSON for the chat JWT. Default `data.token`. */
|
|
913
|
+
tokenPath?: string;
|
|
914
|
+
/** Stripped from the extracted token before use (e.g. `JWT `). */
|
|
915
|
+
tokenStripPrefix?: string;
|
|
916
|
+
/** Dot path for the conversation requestId. Default `data.requestId`. */
|
|
917
|
+
requestIdPath?: string;
|
|
918
|
+
/** Dot path for the user display name. Default `data.fullName`. */
|
|
919
|
+
fullNamePath?: string;
|
|
920
|
+
/** Refetch when the JWT is within this many ms of expiry. Default 60_000. */
|
|
921
|
+
expiryBufferMs?: number;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
export declare type SessionTokenProvider = string | (() => string | Promise<string>);
|
|
925
|
+
|
|
926
|
+
export declare interface SlugMountedWidget extends MountedTenantWidget {
|
|
927
|
+
fullName: string;
|
|
928
|
+
/** Force a fresh /chatbuddy/auth-style refetch (clears cached requestId). */
|
|
929
|
+
refreshAuth(): Promise<void>;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
export declare interface SlugMountOptions {
|
|
933
|
+
/** Container element or CSS selector (e.g. `#chat`). */
|
|
934
|
+
container: HTMLElement | string;
|
|
935
|
+
/** Tenant identifier — the SDK fetches `${configBase}/widget_configs/${slug}`. */
|
|
936
|
+
slug: string;
|
|
937
|
+
/** Defaults to `https://api.aikaara.com`. Override for self-hosted aikaara. */
|
|
938
|
+
configBase?: string;
|
|
939
|
+
/** Additional headers for the descriptor fetch. */
|
|
940
|
+
configHeaders?: Record<string, string>;
|
|
941
|
+
user: {
|
|
942
|
+
id: string;
|
|
943
|
+
/** Display name fallback when descriptor.auth doesn't return one. */
|
|
944
|
+
name?: string;
|
|
945
|
+
departmentId?: string;
|
|
946
|
+
/**
|
|
947
|
+
* Session JWT (Cognito/Auth0/firebase/etc) — passed as bearer to
|
|
948
|
+
* `descriptor.auth.endpoint`. Can be a string (static for the session)
|
|
949
|
+
* or a getter that re-resolves on each refresh.
|
|
950
|
+
*/
|
|
951
|
+
token: SessionTokenProvider;
|
|
952
|
+
};
|
|
953
|
+
/** Optional escape hatches; merge over descriptor-driven defaults. */
|
|
954
|
+
hooks?: {
|
|
955
|
+
upload?: UploadAdapter;
|
|
956
|
+
history?: ConversationHistoryAdapter;
|
|
957
|
+
onError?: (err: Error) => void;
|
|
958
|
+
};
|
|
959
|
+
/** Per-mount visual overrides. */
|
|
960
|
+
overrides?: Partial<WidgetConfigDescriptor>;
|
|
961
|
+
/**
|
|
962
|
+
* Inline descriptor used when the slug fetch fails (e.g. 404, network
|
|
963
|
+
* error). Lets host apps ship without requiring the aikaara backend to be
|
|
964
|
+
* seeded — useful for demos / first-run / offline dev. When the fetch
|
|
965
|
+
* succeeds the response wins; this is purely a safety net.
|
|
966
|
+
*/
|
|
967
|
+
fallbackConfig?: WidgetConfigDescriptor;
|
|
968
|
+
}
|
|
969
|
+
|
|
817
970
|
declare type SubscriptionCallback = (data: unknown) => void;
|
|
818
971
|
|
|
819
972
|
declare interface TemplateMessageEvent {
|
|
@@ -1358,6 +1511,28 @@ export declare interface WidgetConfigDescriptor {
|
|
|
1358
1511
|
historyApiBase?: string;
|
|
1359
1512
|
historyPageSize?: number;
|
|
1360
1513
|
historyPathTemplate?: string;
|
|
1514
|
+
/**
|
|
1515
|
+
* Server-side session-token exchange. When set, the SDK exchanges the
|
|
1516
|
+
* caller-supplied `sessionToken` for a chat JWT + conversation requestId
|
|
1517
|
+
* itself — the host app no longer needs a `tokenProvider` callback.
|
|
1518
|
+
*/
|
|
1519
|
+
auth?: SessionAuthDescriptor;
|
|
1520
|
+
/**
|
|
1521
|
+
* Built-in upload strategy. `mode: "presigned-3step"` runs sign → PUT →
|
|
1522
|
+
* register entirely from descriptor config; `mode: "direct"` POSTs as
|
|
1523
|
+
* multipart to a single endpoint; `mode: "none"` disables uploads. Host
|
|
1524
|
+
* apps can still override with `opts.uploadAdapter`.
|
|
1525
|
+
*/
|
|
1526
|
+
upload?: {
|
|
1527
|
+
mode: 'none';
|
|
1528
|
+
} | {
|
|
1529
|
+
mode: 'direct';
|
|
1530
|
+
endpoint: string;
|
|
1531
|
+
fieldName?: string;
|
|
1532
|
+
extraFields?: Record<string, string>;
|
|
1533
|
+
} | ({
|
|
1534
|
+
mode: 'presigned-3step';
|
|
1535
|
+
} & Presigned3StepAdapterConfig);
|
|
1361
1536
|
}
|
|
1362
1537
|
|
|
1363
1538
|
export { }
|
package/dist/headless.mjs
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import { E as
|
|
2
|
-
import { A as
|
|
3
|
-
class
|
|
1
|
+
import { E as s } from "./MountTenant-DT5Vr6Yr.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-DT5Vr6Yr.mjs";
|
|
3
|
+
class a extends s {
|
|
4
4
|
registration = null;
|
|
5
5
|
pendingEdits = [];
|
|
6
|
-
constructor(
|
|
7
|
-
super(), this.setupListeners(
|
|
6
|
+
constructor(t) {
|
|
7
|
+
super(), this.setupListeners(t);
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* Register a form to receive AI-driven edits.
|
|
11
11
|
* Only one form can be registered at a time (the active page).
|
|
12
12
|
*/
|
|
13
|
-
registerForm(
|
|
14
|
-
this.registration =
|
|
15
|
-
const
|
|
16
|
-
(i) => i.entity_type ===
|
|
13
|
+
registerForm(t) {
|
|
14
|
+
this.registration = t;
|
|
15
|
+
const e = this.pendingEdits.filter(
|
|
16
|
+
(i) => i.entity_type === t.entityType && String(i.entity_id) === String(t.entityId)
|
|
17
17
|
);
|
|
18
|
-
if (
|
|
19
|
-
for (const i of
|
|
20
|
-
|
|
18
|
+
if (e.length > 0) {
|
|
19
|
+
for (const i of e)
|
|
20
|
+
t.onFieldUpdate(i.fields), this.emit("edit:applied", {
|
|
21
21
|
entityType: i.entity_type,
|
|
22
22
|
entityId: i.entity_id,
|
|
23
23
|
fields: i.fields
|
|
24
24
|
});
|
|
25
25
|
this.pendingEdits = this.pendingEdits.filter(
|
|
26
|
-
(i) => !(i.entity_type ===
|
|
26
|
+
(i) => !(i.entity_type === t.entityType && String(i.entity_id) === String(t.entityId))
|
|
27
27
|
);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Unregister the form (call on unmount).
|
|
32
32
|
*/
|
|
33
|
-
unregisterForm(
|
|
34
|
-
this.registration?.entityType ===
|
|
33
|
+
unregisterForm(t, e) {
|
|
34
|
+
this.registration?.entityType === t && String(this.registration?.entityId) === String(e) && (this.registration = null);
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* Get the current form registration (if any).
|
|
@@ -42,13 +42,13 @@ class F extends I {
|
|
|
42
42
|
/**
|
|
43
43
|
* Manually push field updates (for custom tool handling).
|
|
44
44
|
*/
|
|
45
|
-
pushFieldUpdates(
|
|
46
|
-
this.registration && this.registration.entityType ===
|
|
45
|
+
pushFieldUpdates(t, e, i) {
|
|
46
|
+
this.registration && this.registration.entityType === t && String(this.registration.entityId) === String(e) ? (this.registration.onFieldUpdate(i), this.emit("edit:applied", { entityType: t, entityId: e, fields: i })) : (this.pendingEdits.push({
|
|
47
47
|
action: "edit_entity",
|
|
48
|
-
entity_type:
|
|
49
|
-
entity_id:
|
|
48
|
+
entity_type: t,
|
|
49
|
+
entity_id: e,
|
|
50
50
|
fields: i
|
|
51
|
-
}), this.emit("edit:pending", { entityType:
|
|
51
|
+
}), this.emit("edit:pending", { entityType: t, entityId: e, fields: i }));
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
54
|
* Request the current form to save.
|
|
@@ -61,254 +61,57 @@ class F extends I {
|
|
|
61
61
|
entityType: this.registration.entityType,
|
|
62
62
|
entityId: this.registration.entityId
|
|
63
63
|
}), { success: !0 };
|
|
64
|
-
} catch (
|
|
65
|
-
const
|
|
64
|
+
} catch (t) {
|
|
65
|
+
const e = t instanceof Error ? t.message : "Save failed";
|
|
66
66
|
return this.emit("save:error", {
|
|
67
67
|
entityType: this.registration.entityType,
|
|
68
68
|
entityId: this.registration.entityId,
|
|
69
|
-
error:
|
|
70
|
-
}), { success: !1, error:
|
|
69
|
+
error: e
|
|
70
|
+
}), { success: !1, error: e };
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
74
|
* Request the current form to run a test.
|
|
75
75
|
*/
|
|
76
|
-
async requestTest(
|
|
76
|
+
async requestTest(t) {
|
|
77
77
|
if (!this.registration?.onTest)
|
|
78
78
|
return { success: !1, error: "Current form does not support testing" };
|
|
79
79
|
try {
|
|
80
|
-
return await this.registration.onTest(
|
|
81
|
-
} catch (
|
|
82
|
-
return { success: !1, error:
|
|
80
|
+
return await this.registration.onTest(t), { success: !0 };
|
|
81
|
+
} catch (e) {
|
|
82
|
+
return { success: !1, error: e instanceof Error ? e.message : "Test failed" };
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
setupListeners(
|
|
86
|
-
|
|
87
|
-
this.pushFieldUpdates(
|
|
88
|
-
}),
|
|
85
|
+
setupListeners(t) {
|
|
86
|
+
t.on("action:edit_entity", (e) => {
|
|
87
|
+
this.pushFieldUpdates(e.entity_type, e.entity_id, e.fields);
|
|
88
|
+
}), t.on("action:save_entity", (e) => {
|
|
89
89
|
this.requestSave();
|
|
90
|
-
}),
|
|
91
|
-
this.emit("test:triggered", { toolId:
|
|
90
|
+
}), t.on("action:test_tool", (e) => {
|
|
91
|
+
this.emit("test:triggered", { toolId: e.tool_id, parameters: e.parameters }), this.requestTest(e.parameters);
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
function T(t) {
|
|
96
|
-
return {
|
|
97
|
-
async upload(e, r) {
|
|
98
|
-
const i = new FormData(), a = t.fieldName ?? "file";
|
|
99
|
-
i.append(a, e, e.name);
|
|
100
|
-
const n = typeof t.extraFields == "function" ? t.extraFields(r) : t.extraFields;
|
|
101
|
-
if (n)
|
|
102
|
-
for (const [y, h] of Object.entries(n)) i.append(y, h);
|
|
103
|
-
i.append("conversationId", r.conversationId), i.append("userId", r.userId), r.projectId && i.append("projectId", r.projectId);
|
|
104
|
-
const o = typeof t.headers == "function" ? await t.headers() : t.headers ?? {}, p = await fetch(t.endpoint, {
|
|
105
|
-
method: t.method ?? "POST",
|
|
106
|
-
body: i,
|
|
107
|
-
headers: o,
|
|
108
|
-
credentials: t.credentials
|
|
109
|
-
});
|
|
110
|
-
if (!p.ok)
|
|
111
|
-
throw new Error(`Upload failed: ${p.status} ${p.statusText}`);
|
|
112
|
-
const d = await p.json().catch(() => ({}));
|
|
113
|
-
if (t.parseResponse) return t.parseResponse(d, r);
|
|
114
|
-
const s = d, c = s.url ?? s.fileUrl ?? s.publicUrl, m = s.fileName ?? s.name ?? e.name;
|
|
115
|
-
if (!c) throw new Error('Upload response missing "url" / "fileUrl" / "publicUrl"');
|
|
116
|
-
return {
|
|
117
|
-
url: c,
|
|
118
|
-
fileName: m,
|
|
119
|
-
cloudFileId: typeof s.cloudFileId == "string" ? s.cloudFileId : void 0,
|
|
120
|
-
relativePath: typeof s.path == "string" ? s.path : void 0,
|
|
121
|
-
contentType: typeof s.contentType == "string" ? s.contentType : void 0,
|
|
122
|
-
byteSize: typeof s.byteSize == "number" ? s.byteSize : void 0,
|
|
123
|
-
meta: s
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
const x = "/tilechat/{userId}/conversations/{conversationId}/messages?pageSize={pageSize}";
|
|
129
|
-
function v(t) {
|
|
130
|
-
const e = t.apiBase.replace(/\/$/, ""), r = t.pageSize ?? 200, i = t.pathTemplate ?? x;
|
|
131
|
-
return {
|
|
132
|
-
async fetchMessages(a, n) {
|
|
133
|
-
const o = i.replace("{userId}", encodeURIComponent(n.userId)).replace("{conversationId}", encodeURIComponent(a)).replace("{appId}", encodeURIComponent(n.appId ?? "tilechat")).replace("{projectId}", encodeURIComponent(n.projectId ?? "")).replace("{pageSize}", String(r)), p = o.startsWith("http") ? o : `${e}${o.startsWith("/") ? o : `/${o}`}`, d = {
|
|
134
|
-
accept: "application/json",
|
|
135
|
-
// Some Spring/chat21 backends reject GETs without an explicit
|
|
136
|
-
// Content-Type — match bandhan's chatapi which sends it on GETs.
|
|
137
|
-
"content-type": "application/json",
|
|
138
|
-
...t.extraHeaders ?? {}
|
|
139
|
-
};
|
|
140
|
-
if (t.getToken) {
|
|
141
|
-
const y = await t.getToken();
|
|
142
|
-
y && (d.authorization = y);
|
|
143
|
-
}
|
|
144
|
-
const s = await fetch(p, { method: "GET", headers: d, credentials: "include" }), c = await s.json().catch(() => null);
|
|
145
|
-
if (t.parseResponse && c) return t.parseResponse(c);
|
|
146
|
-
const m = c;
|
|
147
|
-
if (m && Array.isArray(m.result))
|
|
148
|
-
return m.result;
|
|
149
|
-
if (!s.ok) throw new Error(`History fetch failed: ${s.status} ${s.statusText}`);
|
|
150
|
-
return [];
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
function w() {
|
|
155
|
-
const t = typeof crypto < "u" ? crypto : null;
|
|
156
|
-
if (t?.randomUUID) return t.randomUUID();
|
|
157
|
-
if (t?.getRandomValues) {
|
|
158
|
-
const e = new Uint8Array(16);
|
|
159
|
-
t.getRandomValues(e), e[6] = e[6] & 15 | 64, e[8] = e[8] & 63 | 128;
|
|
160
|
-
const r = [...e].map((i) => i.toString(16).padStart(2, "0")).join("");
|
|
161
|
-
return `${r.slice(0, 8)}-${r.slice(8, 12)}-${r.slice(12, 16)}-${r.slice(16, 20)}-${r.slice(20)}`;
|
|
162
|
-
}
|
|
163
|
-
return "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, (e) => {
|
|
164
|
-
const r = Math.random() * 16 | 0;
|
|
165
|
-
return (e === "x" ? r : r & 3 | 8).toString(16);
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
const S = "aikaara_chat:requestId";
|
|
169
|
-
function f(t, e) {
|
|
170
|
-
return `${S}:${t}:${e}`;
|
|
171
|
-
}
|
|
172
|
-
function b(t, e) {
|
|
173
|
-
try {
|
|
174
|
-
return localStorage.getItem(f(t, e));
|
|
175
|
-
} catch {
|
|
176
|
-
return null;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
function k(t, e, r) {
|
|
180
|
-
try {
|
|
181
|
-
localStorage.setItem(f(t, e), r);
|
|
182
|
-
} catch {
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
function C(t, e) {
|
|
186
|
-
try {
|
|
187
|
-
localStorage.removeItem(f(t, e));
|
|
188
|
-
} catch {
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
async function E(t, e) {
|
|
192
|
-
const r = await fetch(t, {
|
|
193
|
-
method: "GET",
|
|
194
|
-
headers: { accept: "application/json", ...e ?? {} }
|
|
195
|
-
});
|
|
196
|
-
if (!r.ok) {
|
|
197
|
-
const a = await r.text().catch(() => "");
|
|
198
|
-
throw new Error(`Widget config fetch failed: ${r.status} ${r.statusText} ${a.slice(0, 200)}`);
|
|
199
|
-
}
|
|
200
|
-
const i = await r.json();
|
|
201
|
-
if (i && typeof i == "object") {
|
|
202
|
-
if ("config" in i) return i.config;
|
|
203
|
-
if ("data" in i) return i.data;
|
|
204
|
-
}
|
|
205
|
-
return i;
|
|
206
|
-
}
|
|
207
|
-
function A(t, e) {
|
|
208
|
-
return t.replace("{projectId}", e).replace("{uuid}", w().replace(/-/g, ""));
|
|
209
|
-
}
|
|
210
|
-
async function j(t) {
|
|
211
|
-
const e = {
|
|
212
|
-
...t.config ?? (t.configUrl ? await E(t.configUrl, t.configHeaders) : {}),
|
|
213
|
-
...t.overrides ?? {}
|
|
214
|
-
}, r = e.transport ?? "tiledesk", i = e.tiledesk;
|
|
215
|
-
if ((r === "tiledesk" || r === "dual") && !i)
|
|
216
|
-
throw new Error("mount: descriptor.tiledesk is required for tiledesk/dual transport");
|
|
217
|
-
const a = i?.projectId ?? "", n = t.identity.userId, o = t.forceNewConversation ? null : b(n, a), p = i?.requestIdTemplate ?? "support-group-{projectId}-{uuid}", d = t.conversationId ?? o ?? A(p, a);
|
|
218
|
-
(!o || t.forceNewConversation) && a && k(n, a, d);
|
|
219
|
-
const s = await t.tokenProvider(), c = t.tokenProvider, m = t.historyTokenProvider ?? c, y = i ? {
|
|
220
|
-
mqttEndpoint: i.mqttEndpoint,
|
|
221
|
-
jwtToken: s,
|
|
222
|
-
userId: n,
|
|
223
|
-
userName: t.identity.userName,
|
|
224
|
-
projectId: i.projectId,
|
|
225
|
-
appId: i.appId,
|
|
226
|
-
mqttUsername: i.mqttUsername,
|
|
227
|
-
protocolId: i.protocolId,
|
|
228
|
-
protocolVersion: i.protocolVersion,
|
|
229
|
-
keepAliveSec: i.keepAliveSec,
|
|
230
|
-
connectTimeoutMs: i.connectTimeoutMs,
|
|
231
|
-
maxReconnectAttempts: i.maxReconnectAttempts,
|
|
232
|
-
reconnectMaxDelayMs: i.reconnectMaxDelayMs,
|
|
233
|
-
wildcardSubscribe: i.wildcardSubscribe,
|
|
234
|
-
enablePresence: i.enablePresence,
|
|
235
|
-
autoInitiateOnEmpty: i.autoInitiateOnEmpty,
|
|
236
|
-
chatInitiatedAttributes: i.chatInitiatedAttributes,
|
|
237
|
-
messageDefaults: {
|
|
238
|
-
...i.messageDefaults,
|
|
239
|
-
...t.identity.departmentId ? { departmentId: t.identity.departmentId } : i.messageDefaults?.departmentId ? { departmentId: i.messageDefaults.departmentId } : {}
|
|
240
|
-
},
|
|
241
|
-
fileTemplate: i.fileTemplate,
|
|
242
|
-
topicTemplates: i.topicTemplates,
|
|
243
|
-
debug: i.debug,
|
|
244
|
-
senderFullname: t.identity.senderFullname ?? t.identity.userName,
|
|
245
|
-
tokenProvider: c
|
|
246
|
-
} : void 0, h = t.uploadAdapter ?? (e.uploadEndpoint ? T({
|
|
247
|
-
endpoint: e.uploadEndpoint,
|
|
248
|
-
fieldName: e.uploadFieldName,
|
|
249
|
-
extraFields: e.uploadExtraFields
|
|
250
|
-
}) : void 0), g = t.historyAdapter ?? (e.historyApiBase ? v({
|
|
251
|
-
apiBase: e.historyApiBase,
|
|
252
|
-
pageSize: e.historyPageSize ?? 200,
|
|
253
|
-
pathTemplate: e.historyPathTemplate,
|
|
254
|
-
getToken: m
|
|
255
|
-
}) : void 0), l = {
|
|
256
|
-
transport: r,
|
|
257
|
-
baseUrl: "",
|
|
258
|
-
userToken: n,
|
|
259
|
-
conversationId: d,
|
|
260
|
-
display: e.display ?? "embed",
|
|
261
|
-
position: e.position,
|
|
262
|
-
primaryColor: e.primaryColor,
|
|
263
|
-
title: e.title,
|
|
264
|
-
subtitle: e.subtitle,
|
|
265
|
-
avatarUrl: e.avatarUrl,
|
|
266
|
-
width: e.width,
|
|
267
|
-
height: e.height,
|
|
268
|
-
borderRadius: e.borderRadius,
|
|
269
|
-
fontFamily: e.fontFamily,
|
|
270
|
-
welcomeMessage: e.welcomeMessage,
|
|
271
|
-
placeholder: e.placeholder,
|
|
272
|
-
showTimestamps: e.showTimestamps,
|
|
273
|
-
persistConversation: e.persistConversation,
|
|
274
|
-
tiledesk: y,
|
|
275
|
-
tiledeskIdentity: {
|
|
276
|
-
userId: n,
|
|
277
|
-
userName: t.identity.userName,
|
|
278
|
-
departmentId: t.identity.departmentId,
|
|
279
|
-
senderFullname: t.identity.senderFullname ?? t.identity.userName
|
|
280
|
-
},
|
|
281
|
-
templateActionAttributes: e.templateActionAttributes,
|
|
282
|
-
uploadAdapter: h,
|
|
283
|
-
historyAdapter: g,
|
|
284
|
-
onError: t.onError
|
|
285
|
-
}, u = document.createElement("aikaara-chat-widget");
|
|
286
|
-
return u.configure(l), l.title && u.setAttribute("title", l.title), l.primaryColor && u.setAttribute("primary-color", l.primaryColor), l.display && u.setAttribute("display", l.display), l.display === "embed" && (u.style.cssText = "display:flex;flex-direction:column;width:100%;height:100%;min-height:0;"), t.container.appendChild(u), {
|
|
287
|
-
widget: u,
|
|
288
|
-
requestId: d,
|
|
289
|
-
config: l,
|
|
290
|
-
destroy() {
|
|
291
|
-
u.remove();
|
|
292
|
-
}
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
95
|
export {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
T as
|
|
96
|
+
p as ActionCableClient,
|
|
97
|
+
g as AikaaraChatClient,
|
|
98
|
+
l as ApiClient,
|
|
99
|
+
h as ChannelSubscription,
|
|
100
|
+
y as ConnectionManager,
|
|
101
|
+
c as ConversationManager,
|
|
102
|
+
s as EventEmitter,
|
|
103
|
+
a as FormBridge,
|
|
104
|
+
u as MessageStore,
|
|
105
|
+
m as SessionAuthAdapter,
|
|
106
|
+
f as TiledeskTransport,
|
|
107
|
+
T as clearPersistedConversationId,
|
|
108
|
+
S as createFetchUploadAdapter,
|
|
109
|
+
_ as createPresigned3StepUploadAdapter,
|
|
308
110
|
v as createTiledeskHistoryAdapter,
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
111
|
+
E as extractTiledeskFileEnvelope,
|
|
112
|
+
C as inferTiledeskRole,
|
|
113
|
+
F as isTiledeskSelfEcho,
|
|
114
|
+
A as mountFromSlug,
|
|
115
|
+
k as mountTenantWidget,
|
|
116
|
+
I as parseTiledeskTemplate
|
|
314
117
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MountTenant-B4Py61gI.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;
|