@eshal-bot/chat-widget 0.1.63 → 0.1.64
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/chat-widget.esm.js +2 -2
- package/dist/chat-widget.js +39 -76
- package/dist/chat-widget.min.js +2 -2
- package/dist/chat-widget.umd.js +2 -2
- package/package.json +1 -1
package/dist/chat-widget.js
CHANGED
|
@@ -8011,18 +8011,14 @@
|
|
|
8011
8011
|
* @param {object} request - Chat request object
|
|
8012
8012
|
* @param {string} apiBaseUrl - Base URL for the API
|
|
8013
8013
|
*/
|
|
8014
|
-
const sendStreamingRequest = async (request, apiBaseUrl, organizationId
|
|
8014
|
+
const sendStreamingRequest = async (request, apiBaseUrl, organizationId) => {
|
|
8015
8015
|
const headers = {
|
|
8016
8016
|
'Content-Type': 'application/json',
|
|
8017
8017
|
Accept: 'text/event-stream'
|
|
8018
8018
|
};
|
|
8019
8019
|
|
|
8020
|
-
//
|
|
8021
|
-
|
|
8022
|
-
// Mode C — legacy: orgId sent directly
|
|
8023
|
-
if (secretKey) {
|
|
8024
|
-
headers['x-eshal-key'] = secretKey;
|
|
8025
|
-
} else if (organizationId) {
|
|
8020
|
+
// Add organization ID header if provided
|
|
8021
|
+
if (organizationId) {
|
|
8026
8022
|
headers['x-eshal-org'] = organizationId;
|
|
8027
8023
|
}
|
|
8028
8024
|
const response = await fetch("".concat(apiBaseUrl.replace(/\/$/, ''), "/api/v1/support"), {
|
|
@@ -9133,7 +9129,6 @@
|
|
|
9133
9129
|
apiBaseUrl,
|
|
9134
9130
|
apiKey,
|
|
9135
9131
|
organizationId,
|
|
9136
|
-
secretKey,
|
|
9137
9132
|
autoOpen,
|
|
9138
9133
|
openDelay,
|
|
9139
9134
|
darkMode,
|
|
@@ -9770,7 +9765,7 @@
|
|
|
9770
9765
|
if (apiType === 'userName' || apiType === 'email' || apiType === 'phone') {
|
|
9771
9766
|
// For onboarding fields, just consume the stream without processing.
|
|
9772
9767
|
// Single attempt — no retry, no user-visible partial state to clean up.
|
|
9773
|
-
const stream = await sendStreamingRequest(chatRequest, apiBaseUrl, organizationId
|
|
9768
|
+
const stream = await sendStreamingRequest(chatRequest, apiBaseUrl, organizationId);
|
|
9774
9769
|
const reader = stream.getReader();
|
|
9775
9770
|
const decoder = new TextDecoder();
|
|
9776
9771
|
while (true) {
|
|
@@ -9789,7 +9784,7 @@
|
|
|
9789
9784
|
let lastErr;
|
|
9790
9785
|
for (let attempt = 0; attempt <= STREAM_RETRY_DELAYS_MS.length; attempt += 1) {
|
|
9791
9786
|
try {
|
|
9792
|
-
const stream = await sendStreamingRequest(chatRequest, apiBaseUrl, organizationId
|
|
9787
|
+
const stream = await sendStreamingRequest(chatRequest, apiBaseUrl, organizationId);
|
|
9793
9788
|
await processStream(stream, setMessages);
|
|
9794
9789
|
updateActivity(organizationId);
|
|
9795
9790
|
return {
|
|
@@ -99633,7 +99628,6 @@
|
|
|
99633
99628
|
apiBaseUrl,
|
|
99634
99629
|
apiKey,
|
|
99635
99630
|
organizationId,
|
|
99636
|
-
secretKey,
|
|
99637
99631
|
conversationId,
|
|
99638
99632
|
conciergeId,
|
|
99639
99633
|
onboardingQuestions = [],
|
|
@@ -100430,7 +100424,6 @@
|
|
|
100430
100424
|
/**
|
|
100431
100425
|
* @param {string|undefined|null} apiBaseUrl
|
|
100432
100426
|
* @param {string|undefined|null} orgId
|
|
100433
|
-
* @param {string|undefined|null} secretKey — Mode A/B: orgId resolved server-side
|
|
100434
100427
|
* @returns {{
|
|
100435
100428
|
* categories: Array<{id:string,label:string,count:number,tags:string[]}>,
|
|
100436
100429
|
* loading: boolean,
|
|
@@ -100438,17 +100431,14 @@
|
|
|
100438
100431
|
* hasFilters: boolean,
|
|
100439
100432
|
* }}
|
|
100440
100433
|
*/
|
|
100441
|
-
function useFilterCatalog(apiBaseUrl, orgId
|
|
100442
|
-
// Mode A: secretKey present, orgId null → key-based endpoint
|
|
100443
|
-
// Mode C: orgId present (legacy) → orgId-in-path endpoint
|
|
100444
|
-
const hasAuth = !!(apiBaseUrl && (orgId || secretKey));
|
|
100434
|
+
function useFilterCatalog(apiBaseUrl, orgId) {
|
|
100445
100435
|
const [state, setState] = reactExports.useState({
|
|
100446
100436
|
categories: [],
|
|
100447
|
-
loading:
|
|
100437
|
+
loading: !!(apiBaseUrl && orgId),
|
|
100448
100438
|
error: null
|
|
100449
100439
|
});
|
|
100450
100440
|
reactExports.useEffect(() => {
|
|
100451
|
-
if (!apiBaseUrl || !orgId
|
|
100441
|
+
if (!apiBaseUrl || !orgId) {
|
|
100452
100442
|
setState({
|
|
100453
100443
|
categories: [],
|
|
100454
100444
|
loading: false,
|
|
@@ -100456,8 +100446,8 @@
|
|
|
100456
100446
|
});
|
|
100457
100447
|
return;
|
|
100458
100448
|
}
|
|
100459
|
-
const
|
|
100460
|
-
const cached = _PROCESS_CACHE.get(
|
|
100449
|
+
const key = "".concat(apiBaseUrl, "|").concat(orgId);
|
|
100450
|
+
const cached = _PROCESS_CACHE.get(key);
|
|
100461
100451
|
if (cached) {
|
|
100462
100452
|
setState({
|
|
100463
100453
|
categories: cached,
|
|
@@ -100471,15 +100461,12 @@
|
|
|
100471
100461
|
loading: true,
|
|
100472
100462
|
error: null
|
|
100473
100463
|
}));
|
|
100474
|
-
const
|
|
100475
|
-
const url = secretKey ? "".concat(base, "/api/v1/widget/filters") : "".concat(base, "/api/v1/widget/filters/").concat(encodeURIComponent(orgId));
|
|
100476
|
-
const headers = {
|
|
100477
|
-
Accept: "application/json"
|
|
100478
|
-
};
|
|
100479
|
-
if (secretKey) headers["x-eshal-key"] = secretKey;
|
|
100464
|
+
const url = "".concat(apiBaseUrl.replace(/\/$/, ""), "/api/v1/widget/filters/").concat(encodeURIComponent(orgId));
|
|
100480
100465
|
fetch(url, {
|
|
100481
100466
|
method: "GET",
|
|
100482
|
-
headers
|
|
100467
|
+
headers: {
|
|
100468
|
+
Accept: "application/json"
|
|
100469
|
+
}
|
|
100483
100470
|
}).then(async res => {
|
|
100484
100471
|
if (!res.ok) {
|
|
100485
100472
|
throw new Error("filter catalog HTTP ".concat(res.status));
|
|
@@ -100488,7 +100475,7 @@
|
|
|
100488
100475
|
return Array.isArray(body === null || body === void 0 ? void 0 : body.categories) ? body.categories : [];
|
|
100489
100476
|
}).then(categories => {
|
|
100490
100477
|
if (cancelled) return;
|
|
100491
|
-
_PROCESS_CACHE.set(
|
|
100478
|
+
_PROCESS_CACHE.set(key, categories);
|
|
100492
100479
|
setState({
|
|
100493
100480
|
categories,
|
|
100494
100481
|
loading: false,
|
|
@@ -100510,7 +100497,7 @@
|
|
|
100510
100497
|
return () => {
|
|
100511
100498
|
cancelled = true;
|
|
100512
100499
|
};
|
|
100513
|
-
}, [apiBaseUrl, orgId
|
|
100500
|
+
}, [apiBaseUrl, orgId]);
|
|
100514
100501
|
const hasFilters = reactExports.useMemo(() => Array.isArray(state.categories) && state.categories.length > 0, [state.categories]);
|
|
100515
100502
|
return _objectSpread2(_objectSpread2({}, state), {}, {
|
|
100516
100503
|
hasFilters
|
|
@@ -100592,25 +100579,17 @@
|
|
|
100592
100579
|
* @param {string} orgId - Organization ID
|
|
100593
100580
|
* @returns {Promise<object>} Agent configuration object
|
|
100594
100581
|
*/
|
|
100595
|
-
const fetchAgentConfig = async (apiBaseUrl, orgId
|
|
100596
|
-
if (!apiBaseUrl) {
|
|
100597
|
-
throw new Error("apiBaseUrl
|
|
100598
|
-
}
|
|
100599
|
-
if (!secretKey && !orgId) {
|
|
100600
|
-
throw new Error("secretKey or orgId is required");
|
|
100582
|
+
const fetchAgentConfig = async (apiBaseUrl, orgId) => {
|
|
100583
|
+
if (!apiBaseUrl || !orgId) {
|
|
100584
|
+
throw new Error("apiBaseUrl and orgId are required");
|
|
100601
100585
|
}
|
|
100602
100586
|
try {
|
|
100603
|
-
const
|
|
100604
|
-
// Mode A/B: no orgId in URL — backend resolves org from x-eshal-key or HMAC sig
|
|
100605
|
-
// Mode C legacy: orgId in URL path, no header needed
|
|
100606
|
-
const url = secretKey ? "".concat(base, "/api/v1/deploy-agent") : "".concat(base, "/api/v1/deploy-agent/").concat(orgId);
|
|
100607
|
-
const headers = {
|
|
100608
|
-
"Content-Type": "application/json"
|
|
100609
|
-
};
|
|
100610
|
-
if (secretKey) headers['x-eshal-key'] = secretKey;
|
|
100587
|
+
const url = "".concat(apiBaseUrl.replace(/\/$/, ''), "/api/v1/deploy-agent/").concat(orgId);
|
|
100611
100588
|
const response = await fetch(url, {
|
|
100612
100589
|
method: "GET",
|
|
100613
|
-
headers
|
|
100590
|
+
headers: {
|
|
100591
|
+
"Content-Type": "application/json"
|
|
100592
|
+
},
|
|
100614
100593
|
credentials: "include"
|
|
100615
100594
|
});
|
|
100616
100595
|
if (!response.ok) {
|
|
@@ -100627,11 +100606,8 @@
|
|
|
100627
100606
|
const ChatWidget = _ref => {
|
|
100628
100607
|
var _agentConfig$concierg;
|
|
100629
100608
|
let {
|
|
100630
|
-
//
|
|
100631
|
-
secretKey,
|
|
100632
|
-
// sk_live_... from ChatWidget.init({ secretKey, apiBaseUrl })
|
|
100609
|
+
// Required props for dynamic config
|
|
100633
100610
|
orgId,
|
|
100634
|
-
// legacy — kept for backward compatibility
|
|
100635
100611
|
apiBaseUrl,
|
|
100636
100612
|
// Optional override props (will override fetched config if provided)
|
|
100637
100613
|
darkMode,
|
|
@@ -100682,21 +100658,14 @@
|
|
|
100682
100658
|
// Fetch agent configuration on mount
|
|
100683
100659
|
reactExports.useEffect(() => {
|
|
100684
100660
|
const loadAgentConfig = async () => {
|
|
100685
|
-
if (!apiBaseUrl) {
|
|
100686
|
-
setConfigError("apiBaseUrl
|
|
100687
|
-
setIsLoadingConfig(false);
|
|
100688
|
-
return;
|
|
100689
|
-
}
|
|
100690
|
-
if (!secretKey && !orgId) {
|
|
100691
|
-
setConfigError("secretKey or orgId is required");
|
|
100661
|
+
if (!orgId || !apiBaseUrl) {
|
|
100662
|
+
setConfigError("orgId and apiBaseUrl are required");
|
|
100692
100663
|
setIsLoadingConfig(false);
|
|
100693
100664
|
return;
|
|
100694
100665
|
}
|
|
100695
100666
|
try {
|
|
100696
100667
|
setIsLoadingConfig(true);
|
|
100697
|
-
|
|
100698
|
-
// header and omit the orgId path segment. Pass orgId for Mode C legacy.
|
|
100699
|
-
const config = await fetchAgentConfig(apiBaseUrl, orgId, secretKey);
|
|
100668
|
+
const config = await fetchAgentConfig(apiBaseUrl, orgId);
|
|
100700
100669
|
setAgentConfig(config);
|
|
100701
100670
|
setConfigError(null);
|
|
100702
100671
|
} catch (error) {
|
|
@@ -100707,7 +100676,7 @@
|
|
|
100707
100676
|
}
|
|
100708
100677
|
};
|
|
100709
100678
|
loadAgentConfig();
|
|
100710
|
-
}, [orgId,
|
|
100679
|
+
}, [orgId, apiBaseUrl]);
|
|
100711
100680
|
|
|
100712
100681
|
// Map API response to widget props (use props as overrides if provided)
|
|
100713
100682
|
const widgetConfig = reactExports.useMemo(() => {
|
|
@@ -100885,7 +100854,6 @@
|
|
|
100885
100854
|
// knowledge-api LoadBalancer.
|
|
100886
100855
|
apiKey,
|
|
100887
100856
|
organizationId: widgetConfig.organizationId,
|
|
100888
|
-
secretKey,
|
|
100889
100857
|
autoOpen,
|
|
100890
100858
|
openDelay,
|
|
100891
100859
|
darkMode: widgetConfig.darkMode,
|
|
@@ -100912,15 +100880,14 @@
|
|
|
100912
100880
|
// navigation (but not a page refresh — feedback is not written to
|
|
100913
100881
|
// localStorage so it resets on reload as intended).
|
|
100914
100882
|
updateMessageFeedback(messageContent, feedback);
|
|
100915
|
-
if (!orgId
|
|
100883
|
+
if (!orgId || !conversationId || !apiBaseUrl) return;
|
|
100916
100884
|
const base = apiBaseUrl.replace(/\/$/, "");
|
|
100917
|
-
const feedbackHeaders = {
|
|
100918
|
-
"Content-Type": "application/json"
|
|
100919
|
-
};
|
|
100920
|
-
if (secretKey) feedbackHeaders['x-eshal-key'] = secretKey;else if (orgId) feedbackHeaders['x-eshal-org'] = orgId;
|
|
100921
100885
|
fetch("".concat(base, "/api/v1/support/feedback"), {
|
|
100922
100886
|
method: "POST",
|
|
100923
|
-
headers:
|
|
100887
|
+
headers: {
|
|
100888
|
+
"Content-Type": "application/json",
|
|
100889
|
+
"x-eshal-org": orgId
|
|
100890
|
+
},
|
|
100924
100891
|
credentials: "include",
|
|
100925
100892
|
body: JSON.stringify({
|
|
100926
100893
|
messageContent,
|
|
@@ -100946,7 +100913,7 @@
|
|
|
100946
100913
|
const {
|
|
100947
100914
|
categories: filterCategories,
|
|
100948
100915
|
hasFilters: showFilterStep
|
|
100949
|
-
} = useFilterCatalog(apiBaseUrl, orgId
|
|
100916
|
+
} = useFilterCatalog(apiBaseUrl, orgId);
|
|
100950
100917
|
|
|
100951
100918
|
// Copy chat handler — copy all messages to clipboard
|
|
100952
100919
|
const handleCopyChat = reactExports.useCallback(() => {
|
|
@@ -101052,7 +101019,6 @@
|
|
|
101052
101019
|
apiBaseUrl: apiBaseUrl,
|
|
101053
101020
|
apiKey: apiKey,
|
|
101054
101021
|
organizationId: widgetConfig.organizationId,
|
|
101055
|
-
secretKey: secretKey,
|
|
101056
101022
|
conversationId: conversationId,
|
|
101057
101023
|
conciergeId: (_agentConfig$concierg = agentConfig === null || agentConfig === void 0 ? void 0 : agentConfig.conciergeId) !== null && _agentConfig$concierg !== void 0 ? _agentConfig$concierg : agentConfig === null || agentConfig === void 0 ? void 0 : agentConfig.id,
|
|
101058
101024
|
onboardingQuestions: widgetConfig.onboardingQuestions,
|
|
@@ -101200,14 +101166,11 @@
|
|
|
101200
101166
|
}
|
|
101201
101167
|
|
|
101202
101168
|
// Render component
|
|
101203
|
-
//
|
|
101204
|
-
//
|
|
101205
|
-
|
|
101206
|
-
|
|
101207
|
-
|
|
101208
|
-
// Auth props — secretKey replaces orgId in Mode A/B
|
|
101209
|
-
secretKey: config.secretKey || null,
|
|
101210
|
-
orgId: config.orgId || null,
|
|
101169
|
+
// If orgId and apiBaseUrl are provided, use dynamic config
|
|
101170
|
+
// Otherwise, use the old static config approach for backward compatibility
|
|
101171
|
+
const widgetProps = config.orgId && config.apiBaseUrl ? _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({
|
|
101172
|
+
// Required props
|
|
101173
|
+
orgId: config.orgId,
|
|
101211
101174
|
apiBaseUrl: config.apiBaseUrl
|
|
101212
101175
|
}, options.wsBaseUrl !== undefined && {
|
|
101213
101176
|
wsBaseUrl: config.wsBaseUrl
|