@product7/product7-js 0.3.5 → 0.3.6
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/product7-js.js +97 -237
- package/dist/product7-js.js.map +1 -1
- package/dist/product7-js.min.js +1 -1
- package/dist/product7-js.min.js.map +1 -1
- package/package.json +1 -1
- package/src/api/services/FeedbackService.js +7 -0
- package/src/api/services/MessengerService.js +42 -0
- package/src/api/services/SurveyService.js +6 -0
- package/src/core/APIService.js +4 -209
- package/src/core/BaseAPIService.js +10 -0
package/dist/product7-js.js
CHANGED
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
];
|
|
56
56
|
|
|
57
|
-
const MOCK_CONVERSATIONS
|
|
57
|
+
const MOCK_CONVERSATIONS = [
|
|
58
58
|
{
|
|
59
59
|
id: 'conv_1',
|
|
60
60
|
subject: 'Question about pricing',
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
},
|
|
86
86
|
];
|
|
87
87
|
|
|
88
|
-
const MOCK_MESSAGES
|
|
88
|
+
const MOCK_MESSAGES = {
|
|
89
89
|
conv_1: [
|
|
90
90
|
{
|
|
91
91
|
id: 'msg_1',
|
|
@@ -443,12 +443,19 @@
|
|
|
443
443
|
};
|
|
444
444
|
}
|
|
445
445
|
|
|
446
|
+
const contact = this.api.getContactIdentity();
|
|
447
|
+
|
|
446
448
|
const payload = {
|
|
447
449
|
board:
|
|
448
450
|
feedbackData.board_id || feedbackData.board || feedbackData.boardName,
|
|
449
451
|
title: feedbackData.title,
|
|
450
452
|
content: feedbackData.content,
|
|
451
453
|
attachments: feedbackData.attachments || [],
|
|
454
|
+
...(contact?.contactId && {
|
|
455
|
+
contact_id: contact.contactId,
|
|
456
|
+
contact_email: contact.contactEmail,
|
|
457
|
+
contact_name: contact.contactName,
|
|
458
|
+
}),
|
|
452
459
|
};
|
|
453
460
|
|
|
454
461
|
return this.api._handleAuthRetry(async () => {
|
|
@@ -549,6 +556,10 @@
|
|
|
549
556
|
agents_online: true,
|
|
550
557
|
online_count: 2,
|
|
551
558
|
response_time: 'Usually replies within a few minutes',
|
|
559
|
+
available_agents: [
|
|
560
|
+
{ full_name: 'Sarah', picture: '' },
|
|
561
|
+
{ full_name: 'Tom', picture: '' },
|
|
562
|
+
],
|
|
552
563
|
},
|
|
553
564
|
};
|
|
554
565
|
}
|
|
@@ -566,8 +577,8 @@
|
|
|
566
577
|
await delay$1(300);
|
|
567
578
|
return {
|
|
568
579
|
status: true,
|
|
569
|
-
data: MOCK_CONVERSATIONS
|
|
570
|
-
meta: { total: MOCK_CONVERSATIONS
|
|
580
|
+
data: MOCK_CONVERSATIONS,
|
|
581
|
+
meta: { total: MOCK_CONVERSATIONS.length, page: 1, limit: 20 },
|
|
571
582
|
};
|
|
572
583
|
}
|
|
573
584
|
|
|
@@ -586,10 +597,10 @@
|
|
|
586
597
|
|
|
587
598
|
if (this.api.mock) {
|
|
588
599
|
await delay$1(200);
|
|
589
|
-
const conv = MOCK_CONVERSATIONS
|
|
600
|
+
const conv = MOCK_CONVERSATIONS.find((c) => c.id === conversationId);
|
|
590
601
|
return {
|
|
591
602
|
status: true,
|
|
592
|
-
data: { ...conv, messages: MOCK_MESSAGES
|
|
603
|
+
data: { ...conv, messages: MOCK_MESSAGES[conversationId] || [] },
|
|
593
604
|
};
|
|
594
605
|
}
|
|
595
606
|
|
|
@@ -623,8 +634,8 @@
|
|
|
623
634
|
},
|
|
624
635
|
],
|
|
625
636
|
};
|
|
626
|
-
MOCK_CONVERSATIONS
|
|
627
|
-
MOCK_MESSAGES
|
|
637
|
+
MOCK_CONVERSATIONS.unshift(newConv);
|
|
638
|
+
MOCK_MESSAGES[newConv.id] = newConv.messages;
|
|
628
639
|
return { status: true, data: newConv };
|
|
629
640
|
}
|
|
630
641
|
|
|
@@ -654,10 +665,10 @@
|
|
|
654
665
|
created_at: new Date().toISOString(),
|
|
655
666
|
attachments: data.attachments || [],
|
|
656
667
|
};
|
|
657
|
-
if (!MOCK_MESSAGES
|
|
658
|
-
MOCK_MESSAGES
|
|
668
|
+
if (!MOCK_MESSAGES[conversationId]) {
|
|
669
|
+
MOCK_MESSAGES[conversationId] = [];
|
|
659
670
|
}
|
|
660
|
-
MOCK_MESSAGES
|
|
671
|
+
MOCK_MESSAGES[conversationId].push(newMessage);
|
|
661
672
|
return { status: true, data: newMessage };
|
|
662
673
|
}
|
|
663
674
|
|
|
@@ -681,7 +692,7 @@
|
|
|
681
692
|
await this.api._ensureSession();
|
|
682
693
|
|
|
683
694
|
if (this.api.mock) {
|
|
684
|
-
const count = MOCK_CONVERSATIONS
|
|
695
|
+
const count = MOCK_CONVERSATIONS.reduce(
|
|
685
696
|
(sum, c) => sum + (c.unread || 0),
|
|
686
697
|
0
|
|
687
698
|
);
|
|
@@ -720,7 +731,7 @@
|
|
|
720
731
|
await delay$1(200);
|
|
721
732
|
return {
|
|
722
733
|
status: true,
|
|
723
|
-
data: MOCK_MESSAGES
|
|
734
|
+
data: MOCK_MESSAGES[conversationId] || [],
|
|
724
735
|
meta: { total: 0, page: 1, limit: 50 },
|
|
725
736
|
};
|
|
726
737
|
}
|
|
@@ -736,10 +747,48 @@
|
|
|
736
747
|
});
|
|
737
748
|
}
|
|
738
749
|
|
|
750
|
+
async uploadFile(base64Data, filename) {
|
|
751
|
+
await this.api._ensureSession();
|
|
752
|
+
|
|
753
|
+
if (this.api.mock) {
|
|
754
|
+
await delay$1(300);
|
|
755
|
+
return { status: true, url: `https://mock-cdn.example.com/${filename}` };
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
return this.api._makeRequest('/widget/messenger/upload', {
|
|
759
|
+
method: 'POST',
|
|
760
|
+
headers: {
|
|
761
|
+
'Content-Type': 'application/json',
|
|
762
|
+
Authorization: `Bearer ${this.api.sessionToken}`,
|
|
763
|
+
},
|
|
764
|
+
body: JSON.stringify({ file: base64Data, filename }),
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
|
|
739
768
|
async identifyContact(data) {
|
|
740
769
|
return this.api.identify(data);
|
|
741
770
|
}
|
|
742
771
|
|
|
772
|
+
async submitRating(conversationId, data) {
|
|
773
|
+
await this.api._ensureSession();
|
|
774
|
+
|
|
775
|
+
if (this.api.mock) {
|
|
776
|
+
return { status: true, data: { rated: true } };
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
return this.api._makeRequest(
|
|
780
|
+
`/widget/messenger/conversations/${conversationId}/rating`,
|
|
781
|
+
{
|
|
782
|
+
method: 'POST',
|
|
783
|
+
headers: {
|
|
784
|
+
'Content-Type': 'application/json',
|
|
785
|
+
Authorization: `Bearer ${this.api.sessionToken}`,
|
|
786
|
+
},
|
|
787
|
+
body: JSON.stringify(data),
|
|
788
|
+
}
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
|
|
743
792
|
async sendTypingIndicator(conversationId, isTyping) {
|
|
744
793
|
await this.api._ensureSession();
|
|
745
794
|
|
|
@@ -773,7 +822,7 @@
|
|
|
773
822
|
}
|
|
774
823
|
}
|
|
775
824
|
|
|
776
|
-
|
|
825
|
+
class APIError extends Error {
|
|
777
826
|
constructor(status, message, response) {
|
|
778
827
|
super(message);
|
|
779
828
|
this.name = 'APIError';
|
|
@@ -796,7 +845,7 @@
|
|
|
796
845
|
isServerError() {
|
|
797
846
|
return this.status >= 500 && this.status < 600;
|
|
798
847
|
}
|
|
799
|
-
}
|
|
848
|
+
}
|
|
800
849
|
|
|
801
850
|
class WidgetError extends Error {
|
|
802
851
|
constructor(message, widgetType, widgetId) {
|
|
@@ -894,7 +943,7 @@
|
|
|
894
943
|
}
|
|
895
944
|
|
|
896
945
|
async submitSurveyResponse(surveyId, responseData) {
|
|
897
|
-
if (!surveyId) throw new APIError
|
|
946
|
+
if (!surveyId) throw new APIError(400, 'Survey ID is required');
|
|
898
947
|
|
|
899
948
|
await this.api._ensureSession();
|
|
900
949
|
|
|
@@ -912,6 +961,7 @@
|
|
|
912
961
|
}
|
|
913
962
|
|
|
914
963
|
const respondent = this._getRespondentContext(responseData);
|
|
964
|
+
const contact = this.api.getContactIdentity?.() || null;
|
|
915
965
|
|
|
916
966
|
const payload = {
|
|
917
967
|
rating: responseData.rating,
|
|
@@ -921,6 +971,11 @@
|
|
|
921
971
|
respondent_id: respondent.respondent_id,
|
|
922
972
|
}),
|
|
923
973
|
...(respondent.email && { email: respondent.email }),
|
|
974
|
+
...(contact?.contactId && {
|
|
975
|
+
contact_id: contact.contactId,
|
|
976
|
+
contact_email: contact.contactEmail,
|
|
977
|
+
contact_name: contact.contactName,
|
|
978
|
+
}),
|
|
924
979
|
};
|
|
925
980
|
|
|
926
981
|
return this.api._handleAuthRetry(async () => {
|
|
@@ -939,7 +994,7 @@
|
|
|
939
994
|
}
|
|
940
995
|
|
|
941
996
|
async dismissSurvey(surveyId) {
|
|
942
|
-
if (!surveyId) throw new APIError
|
|
997
|
+
if (!surveyId) throw new APIError(400, 'Survey ID is required');
|
|
943
998
|
|
|
944
999
|
await this.api._ensureSession();
|
|
945
1000
|
|
|
@@ -1025,7 +1080,7 @@
|
|
|
1025
1080
|
}
|
|
1026
1081
|
|
|
1027
1082
|
if (!this.workspace) {
|
|
1028
|
-
throw new APIError
|
|
1083
|
+
throw new APIError(400, 'Missing workspace for initialization');
|
|
1029
1084
|
}
|
|
1030
1085
|
|
|
1031
1086
|
if (this.mock) {
|
|
@@ -1081,7 +1136,7 @@
|
|
|
1081
1136
|
configVersion: initData.configVersion,
|
|
1082
1137
|
};
|
|
1083
1138
|
} catch (error) {
|
|
1084
|
-
throw new APIError
|
|
1139
|
+
throw new APIError(
|
|
1085
1140
|
error.status || 500,
|
|
1086
1141
|
`Failed to initialize widget: ${error.message}`,
|
|
1087
1142
|
error.response
|
|
@@ -1099,11 +1154,11 @@
|
|
|
1099
1154
|
const expiresIn = Number(payload.expires_in ?? payload.expiresIn);
|
|
1100
1155
|
|
|
1101
1156
|
if (!sessionToken) {
|
|
1102
|
-
throw new APIError
|
|
1157
|
+
throw new APIError(500, 'Invalid init response: missing session_token');
|
|
1103
1158
|
}
|
|
1104
1159
|
|
|
1105
1160
|
if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
|
|
1106
|
-
throw new APIError
|
|
1161
|
+
throw new APIError(500, 'Invalid init response: missing expires_in');
|
|
1107
1162
|
}
|
|
1108
1163
|
|
|
1109
1164
|
return {
|
|
@@ -1124,7 +1179,7 @@
|
|
|
1124
1179
|
await this.init();
|
|
1125
1180
|
}
|
|
1126
1181
|
if (!this.sessionToken) {
|
|
1127
|
-
throw new APIError
|
|
1182
|
+
throw new APIError(401, 'No valid session token available');
|
|
1128
1183
|
}
|
|
1129
1184
|
}
|
|
1130
1185
|
|
|
@@ -1149,7 +1204,7 @@
|
|
|
1149
1204
|
}
|
|
1150
1205
|
|
|
1151
1206
|
if (!this.metadata) {
|
|
1152
|
-
throw new APIError
|
|
1207
|
+
throw new APIError(400, 'Missing user context for identify');
|
|
1153
1208
|
}
|
|
1154
1209
|
|
|
1155
1210
|
await this._ensureSession();
|
|
@@ -1235,6 +1290,15 @@
|
|
|
1235
1290
|
if (!stored) return false;
|
|
1236
1291
|
|
|
1237
1292
|
const sessionData = JSON.parse(stored);
|
|
1293
|
+
|
|
1294
|
+
// Invalidate mock tokens when not in mock mode (and vice versa)
|
|
1295
|
+
const isMockToken =
|
|
1296
|
+
sessionData.token && sessionData.token.startsWith('mock_');
|
|
1297
|
+
if (isMockToken !== this.mock) {
|
|
1298
|
+
localStorage.removeItem('product7_session');
|
|
1299
|
+
return false;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1238
1302
|
if (
|
|
1239
1303
|
this.workspace &&
|
|
1240
1304
|
sessionData.workspace &&
|
|
@@ -1243,6 +1307,7 @@
|
|
|
1243
1307
|
localStorage.removeItem('product7_session');
|
|
1244
1308
|
return false;
|
|
1245
1309
|
}
|
|
1310
|
+
|
|
1246
1311
|
this.sessionToken = sessionData.token;
|
|
1247
1312
|
this.sessionExpiry = new Date(sessionData.expiry);
|
|
1248
1313
|
|
|
@@ -1308,7 +1373,7 @@
|
|
|
1308
1373
|
errorMessage = (await response.text()) || errorMessage;
|
|
1309
1374
|
}
|
|
1310
1375
|
|
|
1311
|
-
throw new APIError
|
|
1376
|
+
throw new APIError(response.status, errorMessage, responseData);
|
|
1312
1377
|
}
|
|
1313
1378
|
|
|
1314
1379
|
const contentType = response.headers.get('content-type');
|
|
@@ -1318,8 +1383,8 @@
|
|
|
1318
1383
|
|
|
1319
1384
|
return await response.text();
|
|
1320
1385
|
} catch (error) {
|
|
1321
|
-
if (error instanceof APIError
|
|
1322
|
-
throw new APIError
|
|
1386
|
+
if (error instanceof APIError) throw error;
|
|
1387
|
+
throw new APIError(0, error.message, null);
|
|
1323
1388
|
}
|
|
1324
1389
|
}
|
|
1325
1390
|
|
|
@@ -1404,29 +1469,7 @@
|
|
|
1404
1469
|
}
|
|
1405
1470
|
|
|
1406
1471
|
async checkAgentsOnline() {
|
|
1407
|
-
|
|
1408
|
-
await this.init();
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
|
-
if (this.mock) {
|
|
1412
|
-
return {
|
|
1413
|
-
status: true,
|
|
1414
|
-
data: {
|
|
1415
|
-
agents_online: true,
|
|
1416
|
-
online_count: 2,
|
|
1417
|
-
response_time: 'Usually replies within a few minutes',
|
|
1418
|
-
available_agents: [
|
|
1419
|
-
{ full_name: 'Sarah', picture: '' },
|
|
1420
|
-
{ full_name: 'Tom', picture: '' },
|
|
1421
|
-
],
|
|
1422
|
-
},
|
|
1423
|
-
};
|
|
1424
|
-
}
|
|
1425
|
-
|
|
1426
|
-
return this._makeRequest('/widget/messenger/agents/online', {
|
|
1427
|
-
method: 'GET',
|
|
1428
|
-
headers: { Authorization: `Bearer ${this.sessionToken}` },
|
|
1429
|
-
});
|
|
1472
|
+
return this.messenger.checkAgentsOnline();
|
|
1430
1473
|
}
|
|
1431
1474
|
|
|
1432
1475
|
async getConversations(options) {
|
|
@@ -1442,137 +1485,15 @@
|
|
|
1442
1485
|
}
|
|
1443
1486
|
|
|
1444
1487
|
async startConversation(data) {
|
|
1445
|
-
|
|
1446
|
-
console.log(
|
|
1447
|
-
'[APIService] startConversation: session invalid, calling init...'
|
|
1448
|
-
);
|
|
1449
|
-
try {
|
|
1450
|
-
await this.init();
|
|
1451
|
-
console.log(
|
|
1452
|
-
'[APIService] startConversation: init result, token:',
|
|
1453
|
-
this.sessionToken ? 'set' : 'null'
|
|
1454
|
-
);
|
|
1455
|
-
} catch (initError) {
|
|
1456
|
-
console.error(
|
|
1457
|
-
'[APIService] startConversation: init failed:',
|
|
1458
|
-
initError.message
|
|
1459
|
-
);
|
|
1460
|
-
throw initError;
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
if (!this.sessionToken) {
|
|
1465
|
-
console.error(
|
|
1466
|
-
'[APIService] startConversation: no session token after init'
|
|
1467
|
-
);
|
|
1468
|
-
throw new APIError(401, 'No valid session token available');
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
|
-
console.log(
|
|
1472
|
-
'[APIService] startConversation: sending to',
|
|
1473
|
-
`${this.baseURL}/widget/messenger/conversations`,
|
|
1474
|
-
'mock:',
|
|
1475
|
-
this.mock
|
|
1476
|
-
);
|
|
1477
|
-
|
|
1478
|
-
if (this.mock) {
|
|
1479
|
-
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1480
|
-
const newConv = {
|
|
1481
|
-
id: 'conv_' + Date.now(),
|
|
1482
|
-
subject: data.subject || 'New conversation',
|
|
1483
|
-
status: 'open',
|
|
1484
|
-
last_message_at: new Date().toISOString(),
|
|
1485
|
-
created_at: new Date().toISOString(),
|
|
1486
|
-
messages: [
|
|
1487
|
-
{
|
|
1488
|
-
id: 'msg_' + Date.now(),
|
|
1489
|
-
content: data.message,
|
|
1490
|
-
sender_type: 'customer',
|
|
1491
|
-
created_at: new Date().toISOString(),
|
|
1492
|
-
},
|
|
1493
|
-
],
|
|
1494
|
-
};
|
|
1495
|
-
MOCK_CONVERSATIONS.unshift(newConv);
|
|
1496
|
-
MOCK_MESSAGES[newConv.id] = newConv.messages;
|
|
1497
|
-
return { status: true, data: newConv };
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
|
-
return this._makeRequest('/widget/messenger/conversations', {
|
|
1501
|
-
method: 'POST',
|
|
1502
|
-
headers: {
|
|
1503
|
-
'Content-Type': 'application/json',
|
|
1504
|
-
Authorization: `Bearer ${this.sessionToken}`,
|
|
1505
|
-
},
|
|
1506
|
-
body: JSON.stringify({
|
|
1507
|
-
message: data.message,
|
|
1508
|
-
subject: data.subject || '',
|
|
1509
|
-
}),
|
|
1510
|
-
});
|
|
1488
|
+
return this.messenger.startConversation(data);
|
|
1511
1489
|
}
|
|
1512
1490
|
|
|
1513
1491
|
async sendMessage(conversationId, data) {
|
|
1514
|
-
|
|
1515
|
-
await this.init();
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
if (this.mock) {
|
|
1519
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
1520
|
-
const newMessage = {
|
|
1521
|
-
id: 'msg_' + Date.now(),
|
|
1522
|
-
content: data.content,
|
|
1523
|
-
attachments: data.attachments || [],
|
|
1524
|
-
sender_type: 'customer',
|
|
1525
|
-
created_at: new Date().toISOString(),
|
|
1526
|
-
};
|
|
1527
|
-
if (!MOCK_MESSAGES[conversationId]) {
|
|
1528
|
-
MOCK_MESSAGES[conversationId] = [];
|
|
1529
|
-
}
|
|
1530
|
-
MOCK_MESSAGES[conversationId].push(newMessage);
|
|
1531
|
-
return { status: true, data: newMessage };
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1534
|
-
const payload = { content: data.content };
|
|
1535
|
-
if (data.attachments && data.attachments.length > 0) {
|
|
1536
|
-
payload.attachments = data.attachments;
|
|
1537
|
-
}
|
|
1538
|
-
|
|
1539
|
-
return this._makeRequest(
|
|
1540
|
-
`/widget/messenger/conversations/${conversationId}/messages`,
|
|
1541
|
-
{
|
|
1542
|
-
method: 'POST',
|
|
1543
|
-
headers: {
|
|
1544
|
-
'Content-Type': 'application/json',
|
|
1545
|
-
Authorization: `Bearer ${this.sessionToken}`,
|
|
1546
|
-
},
|
|
1547
|
-
body: JSON.stringify(payload),
|
|
1548
|
-
}
|
|
1549
|
-
);
|
|
1492
|
+
return this.messenger.sendMessage(conversationId, data);
|
|
1550
1493
|
}
|
|
1551
1494
|
|
|
1552
|
-
/**
|
|
1553
|
-
* Upload a file to CDN via widget endpoint
|
|
1554
|
-
* @param {string} base64Data - Base64 encoded file data (with or without data URI prefix)
|
|
1555
|
-
* @param {string} filename - Original filename
|
|
1556
|
-
* @returns {Promise<Object>} Response with url
|
|
1557
|
-
*/
|
|
1558
1495
|
async uploadFile(base64Data, filename) {
|
|
1559
|
-
|
|
1560
|
-
await this.init();
|
|
1561
|
-
}
|
|
1562
|
-
|
|
1563
|
-
if (this.mock) {
|
|
1564
|
-
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1565
|
-
return { status: true, url: `https://mock-cdn.example.com/${filename}` };
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
return this._makeRequest('/widget/messenger/upload', {
|
|
1569
|
-
method: 'POST',
|
|
1570
|
-
headers: {
|
|
1571
|
-
'Content-Type': 'application/json',
|
|
1572
|
-
Authorization: `Bearer ${this.sessionToken}`,
|
|
1573
|
-
},
|
|
1574
|
-
body: JSON.stringify({ file: base64Data, filename }),
|
|
1575
|
-
});
|
|
1496
|
+
return this.messenger.uploadFile(base64Data, filename);
|
|
1576
1497
|
}
|
|
1577
1498
|
|
|
1578
1499
|
async sendTypingIndicator(conversationId, isTyping) {
|
|
@@ -1692,67 +1613,6 @@
|
|
|
1692
1613
|
async getChangelogs(options) {
|
|
1693
1614
|
return this.changelog.getChangelogs(options);
|
|
1694
1615
|
}
|
|
1695
|
-
|
|
1696
|
-
_loadStoredSession() {
|
|
1697
|
-
if (typeof localStorage === 'undefined') return false;
|
|
1698
|
-
|
|
1699
|
-
try {
|
|
1700
|
-
const stored = localStorage.getItem('product7_session');
|
|
1701
|
-
if (!stored) return false;
|
|
1702
|
-
|
|
1703
|
-
const sessionData = JSON.parse(stored);
|
|
1704
|
-
|
|
1705
|
-
// Invalidate mock tokens when not in mock mode (and vice versa)
|
|
1706
|
-
const isMockToken =
|
|
1707
|
-
sessionData.token && sessionData.token.startsWith('mock_');
|
|
1708
|
-
if (isMockToken !== this.mock) {
|
|
1709
|
-
localStorage.removeItem('product7_session');
|
|
1710
|
-
return false;
|
|
1711
|
-
}
|
|
1712
|
-
|
|
1713
|
-
this.sessionToken = sessionData.token;
|
|
1714
|
-
this.sessionExpiry = new Date(sessionData.expiry);
|
|
1715
|
-
|
|
1716
|
-
return this.isSessionValid();
|
|
1717
|
-
} catch (error) {
|
|
1718
|
-
return false;
|
|
1719
|
-
}
|
|
1720
|
-
}
|
|
1721
|
-
|
|
1722
|
-
async _makeRequest(endpoint, options = {}) {
|
|
1723
|
-
const url = `${this.baseURL}${endpoint}`;
|
|
1724
|
-
|
|
1725
|
-
try {
|
|
1726
|
-
const response = await fetch(url, options);
|
|
1727
|
-
|
|
1728
|
-
if (!response.ok) {
|
|
1729
|
-
let errorMessage = `HTTP ${response.status}`;
|
|
1730
|
-
let responseData = null;
|
|
1731
|
-
|
|
1732
|
-
try {
|
|
1733
|
-
responseData = await response.json();
|
|
1734
|
-
errorMessage =
|
|
1735
|
-
responseData.message || responseData.error || errorMessage;
|
|
1736
|
-
} catch (e) {
|
|
1737
|
-
errorMessage = (await response.text()) || errorMessage;
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
throw new APIError(response.status, errorMessage, responseData);
|
|
1741
|
-
}
|
|
1742
|
-
|
|
1743
|
-
const contentType = response.headers.get('content-type');
|
|
1744
|
-
if (contentType && contentType.includes('application/json')) {
|
|
1745
|
-
return await response.json();
|
|
1746
|
-
}
|
|
1747
|
-
|
|
1748
|
-
return await response.text();
|
|
1749
|
-
} catch (error) {
|
|
1750
|
-
if (error instanceof APIError) {
|
|
1751
|
-
throw error;
|
|
1752
|
-
}
|
|
1753
|
-
throw new APIError(0, error.message, null);
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1756
1616
|
}
|
|
1757
1617
|
|
|
1758
1618
|
class EventBus {
|
|
@@ -15774,7 +15634,7 @@
|
|
|
15774
15634
|
EventBus,
|
|
15775
15635
|
APIService,
|
|
15776
15636
|
SDKError,
|
|
15777
|
-
APIError
|
|
15637
|
+
APIError,
|
|
15778
15638
|
WidgetError,
|
|
15779
15639
|
ConfigError,
|
|
15780
15640
|
ValidationError,
|
|
@@ -15793,7 +15653,7 @@
|
|
|
15793
15653
|
}
|
|
15794
15654
|
}
|
|
15795
15655
|
|
|
15796
|
-
exports.APIError = APIError
|
|
15656
|
+
exports.APIError = APIError;
|
|
15797
15657
|
exports.APIService = APIService;
|
|
15798
15658
|
exports.BaseWidget = BaseWidget;
|
|
15799
15659
|
exports.ButtonWidget = ButtonWidget;
|