@microsoft/omnichannel-chat-widget 1.2.3-main.000f886 → 1.2.3-main.2ce131d

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.
Files changed (23) hide show
  1. package/lib/cjs/common/Constants.js +5 -1
  2. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +2 -1
  3. package/lib/cjs/components/livechatwidget/common/reconnectChatHelper.js +12 -7
  4. package/lib/cjs/components/livechatwidget/common/startChat.js +6 -5
  5. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +16 -15
  6. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware.js +5 -0
  7. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.js +65 -0
  8. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.spec.js +342 -0
  9. package/lib/cjs/plugins/createChatTranscript.js +28 -4
  10. package/lib/esm/common/Constants.js +5 -1
  11. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +2 -1
  12. package/lib/esm/components/livechatwidget/common/reconnectChatHelper.js +12 -7
  13. package/lib/esm/components/livechatwidget/common/startChat.js +6 -5
  14. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +16 -15
  15. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware.js +5 -0
  16. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.js +58 -0
  17. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.spec.js +338 -0
  18. package/lib/esm/plugins/createChatTranscript.js +28 -4
  19. package/lib/types/common/Constants.d.ts +4 -0
  20. package/lib/types/components/livechatwidget/common/reconnectChatHelper.d.ts +1 -1
  21. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.d.ts +5 -0
  22. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.spec.d.ts +1 -0
  23. package/package.json +2 -2
@@ -58,7 +58,8 @@ _defineProperty(Constants, "prefixTimestampTag", "ServerMessageTimestamp_");
58
58
  _defineProperty(Constants, "acsChannel", "ACS_CHANNEL");
59
59
  _defineProperty(Constants, "publicMessageTag", "public");
60
60
  //attachmentMiddleware
61
- _defineProperty(Constants, "supportedAdaptiveCardContentTypes", ["application/vnd.microsoft.card.adaptive", "application/vnd.microsoft.card.audio", "application/vnd.microsoft.card.hero", "application/vnd.microsoft.card.receipt", "application/vnd.microsoft.card.thumbnail", "application/vnd.microsoft.card.signin", "application/vnd.microsoft.card.oauth"]);
61
+ _defineProperty(Constants, "supportedAdaptiveCardContentTypes", ["application/vnd.microsoft.card.adaptive", "application/vnd.microsoft.card.audio", "application/vnd.microsoft.card.hero", "application/vnd.microsoft.card.receipt", "application/vnd.microsoft.card.thumbnail", "application/vnd.microsoft.card.signin", "application/vnd.microsoft.card.oauth", "application/vnd.microsoft.card.video"]);
62
+ _defineProperty(Constants, "adaptiveCardContentTypePrefix", "application/vnd.microsoft.card");
62
63
  _defineProperty(Constants, "maxUploadFileSize", "500000");
63
64
  _defineProperty(Constants, "imageRegex", /(\.)(jpeg|jpg|jiff|png|gif|bmp|webp)$/i);
64
65
  _defineProperty(Constants, "audioMediaRegex", /(\.)(aac|aiff|alac|amr|flac|mp2|mp3|pcm|wav|wma)$/i);
@@ -116,6 +117,9 @@ _defineProperty(Constants, "LWICheckOnVisibilityTimeout", 3 * 60 * 1000);
116
117
  // Popup mode custom context response event message name
117
118
  _defineProperty(Constants, "InitContextParamsRequest", "initContextParamsRequest");
118
119
  _defineProperty(Constants, "InitContextParamsResponse", "initContextParamsResponse");
120
+ _defineProperty(Constants, "OCOriginalMessageId", "OriginalMessageId");
121
+ _defineProperty(Constants, "WebchatSequenceIdAttribute", "webchat:sequence-id");
122
+ _defineProperty(Constants, "MessageSequenceIdOverride", "MessageSequenceIdOverride");
119
123
  const Regex = (_class = class Regex {}, _defineProperty(_class, "EmailRegex", "(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"), _class);
120
124
  exports.Regex = Regex;
121
125
  class HtmlIdNames {}
@@ -35,6 +35,7 @@ var _htmlTextMiddleware = _interopRequireDefault(require("../../webchatcontainer
35
35
  var _preProcessingMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware"));
36
36
  var _sanitizationMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware"));
37
37
  var _dompurify = _interopRequireDefault(require("dompurify"));
38
+ var _messageSequenceIdOverrideMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware"));
38
39
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
39
40
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
41
  const initWebChatComposer = (props, state, dispatch, chatSDK) => {
@@ -74,7 +75,7 @@ const initWebChatComposer = (props, state, dispatch, chatSDK) => {
74
75
  };
75
76
  webChatStore = (0, _botframeworkWebchat.createStore)({},
76
77
  //initial state
77
- _preProcessingMiddleware.default, _attachmentProcessingMiddleware.default, (0, _attachmentUploadValidatorMiddleware.default)((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), _channelDataMiddleware.default, (0, _conversationEndMiddleware.default)(conversationEndCallback), (0, _dataMaskingMiddleware.default)((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), _messageTimestampMiddleware.default, _gifUploadMiddleware.default, _htmlPlayerMiddleware.default, _htmlTextMiddleware.default, (0, _maxMessageSizeValidator.default)(localizedTexts), _sanitizationMiddleware.default,
78
+ _preProcessingMiddleware.default, _attachmentProcessingMiddleware.default, (0, _attachmentUploadValidatorMiddleware.default)((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), _channelDataMiddleware.default, (0, _conversationEndMiddleware.default)(conversationEndCallback), (0, _dataMaskingMiddleware.default)((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), _messageTimestampMiddleware.default, _messageSequenceIdOverrideMiddleware.default, _gifUploadMiddleware.default, _htmlPlayerMiddleware.default, _htmlTextMiddleware.default, (0, _maxMessageSizeValidator.default)(localizedTexts), _sanitizationMiddleware.default,
78
79
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
79
80
  ...(((_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.storeMiddlewares) ?? []));
80
81
  _WebChatStoreLoader.WebChatStoreLoader.store = webChatStore;
@@ -13,10 +13,11 @@ var _Constants = require("../../../common/Constants");
13
13
  var _ConversationState = require("../../../contexts/common/ConversationState");
14
14
  var _LiveChatWidgetActionType = require("../../../contexts/common/LiveChatWidgetActionType");
15
15
  var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
16
+ // Return value: should start normal chat flow when reconnect is enabled
16
17
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
18
  const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initStartChat, state) => {
18
19
  var _props$chatConfig, _props$chatConfig$Liv;
19
- if (!isReconnectEnabled(props.chatConfig) || isPersistentEnabled(props.chatConfig)) return;
20
+ if (!isReconnectEnabled(props.chatConfig) || isPersistentEnabled(props.chatConfig)) return false;
20
21
 
21
22
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
23
  const isAuthenticatedChat = (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
@@ -28,14 +29,14 @@ const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initSta
28
29
  if (reconnectChatContext !== null && reconnectChatContext !== void 0 && reconnectChatContext.redirectURL) {
29
30
  var _props$reconnectChatP;
30
31
  redirectPage(reconnectChatContext.redirectURL, (_props$reconnectChatP = props.reconnectChatPaneProps) === null || _props$reconnectChatP === void 0 ? void 0 : _props$reconnectChatP.redirectInSameWindow);
31
- return;
32
+ return false;
32
33
  }
33
34
  if (hasReconnectId(reconnectChatContext)) {
34
35
  var _props$reconnectChatP2, _props$reconnectChatP3;
35
36
  //if reconnect id is provided in props, don't show reconnect pane
36
37
  if ((_props$reconnectChatP2 = props.reconnectChatPaneProps) !== null && _props$reconnectChatP2 !== void 0 && _props$reconnectChatP2.reconnectId && !(0, _utils.isNullOrEmptyString)((_props$reconnectChatP3 = props.reconnectChatPaneProps) === null || _props$reconnectChatP3 === void 0 ? void 0 : _props$reconnectChatP3.reconnectId)) {
37
- await setReconnectIdAndStartChat(isAuthenticatedChat, chatSDK, props, dispatch, setAdapter, reconnectChatContext.reconnectId ?? "", initStartChat);
38
- return;
38
+ await setReconnectIdAndStartChat(isAuthenticatedChat, chatSDK, state, props, dispatch, setAdapter, reconnectChatContext.reconnectId ?? "", initStartChat);
39
+ return false;
39
40
  }
40
41
 
41
42
  //show reconnect pane
@@ -48,8 +49,12 @@ const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initSta
48
49
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
49
50
  payload: _ConversationState.ConversationState.ReconnectChat
50
51
  });
51
- return;
52
+ return false;
52
53
  }
54
+
55
+ // If we have reached this point, it means there is no valid reconnect id or redirectUrl
56
+ // This is a unauth reconnect refresh scenario - returns true so that we can start normal hydration process
57
+ return true;
53
58
  };
54
59
 
55
60
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -88,7 +93,7 @@ const getChatReconnectContext = async (chatSDK, chatConfig, props, isAuthenticat
88
93
 
89
94
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
95
  exports.getChatReconnectContext = getChatReconnectContext;
91
- const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, props, dispatch, setAdapter, reconnectId, initStartChat) => {
96
+ const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, state, props, dispatch, setAdapter, reconnectId, initStartChat) => {
92
97
  if (!isAuthenticatedChat) {
93
98
  const startUnauthenticatedReconnectChat = {
94
99
  eventName: _TelemetryConstants.BroadcastEvent.StartUnauthenticatedReconnectChat
@@ -106,7 +111,7 @@ const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, props, d
106
111
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
107
112
  payload: _ConversationState.ConversationState.Loading
108
113
  });
109
- await initStartChat(chatSDK, dispatch, setAdapter, props, optionalParams);
114
+ await initStartChat(chatSDK, dispatch, setAdapter, state, props, optionalParams);
110
115
  };
111
116
  const redirectPage = (redirectURL, redirectInSameWindow) => {
112
117
  const redirectPageRequest = {
@@ -303,16 +303,17 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
303
303
 
304
304
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
305
305
  const setCustomContextParams = async (state, props) => {
306
- var _props$chatConfig, _props$chatConfig$Liv, _persistedState$domai8;
306
+ var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates, _persistedState$domai8;
307
307
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
308
308
  const isAuthenticatedChat = props !== null && props !== void 0 && (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
309
309
  //Should not set custom context for auth chat
310
310
  if (isAuthenticatedChat) {
311
311
  return;
312
312
  }
313
- if (state !== null && state !== void 0 && state.domainStates.customContext) {
313
+ if (state !== null && state !== void 0 && (_state$domainStates = state.domainStates) !== null && _state$domainStates !== void 0 && _state$domainStates.customContext) {
314
+ var _state$domainStates2;
314
315
  optionalParams = Object.assign({}, optionalParams, {
315
- customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : state.domainStates.customContext))
316
+ customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.customContext))
316
317
  });
317
318
  return;
318
319
  }
@@ -360,8 +361,8 @@ const canStartPopoutChat = async props => {
360
361
 
361
362
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
362
363
  const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
363
- var _state$domainStates, _state$domainStates$l;
364
- const requestIdFromCache = (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$l = _state$domainStates.liveChatContext) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.requestId;
364
+ var _state$domainStates3, _state$domainStates3$;
365
+ const requestIdFromCache = (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.liveChatContext) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.requestId;
365
366
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
366
367
  let conversationDetails = undefined;
367
368
 
@@ -116,6 +116,16 @@ const LiveChatWidgetStateful = props => {
116
116
 
117
117
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
118
  const startChat = async (props, localState) => {
119
+ const isReconnectTriggered = async () => {
120
+ if ((0, _reconnectChatHelper.isReconnectEnabled)(props.chatConfig) === true && !(0, _reconnectChatHelper.isPersistentEnabled)(props.chatConfig)) {
121
+ const noValidReconnectId = await (0, _reconnectChatHelper.handleChatReconnect)(chatSDK, props, dispatch, setAdapter, _startChat.initStartChat, state);
122
+ // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
123
+ if (!noValidReconnectId && (state.appStates.conversationState === _ConversationState.ConversationState.Active || state.appStates.conversationState === _ConversationState.ConversationState.ReconnectChat)) {
124
+ return true;
125
+ }
126
+ }
127
+ return false;
128
+ };
119
129
  let isChatValid = false;
120
130
  //Start a chat from cache/reconnectid
121
131
  if (activeCachedChatExist === true) {
@@ -130,29 +140,20 @@ const LiveChatWidgetStateful = props => {
130
140
  //Check if conversation state is not in wrapup or closed state
131
141
  isChatValid = await (0, _startChat.checkIfConversationStillValid)(chatSDK, dispatch, state);
132
142
  if (isChatValid === true) {
133
- //Check if reconnect enabled
134
- if ((0, _reconnectChatHelper.isReconnectEnabled)(props.chatConfig) === true && !(0, _reconnectChatHelper.isPersistentEnabled)(props.chatConfig)) {
135
- await (0, _reconnectChatHelper.handleChatReconnect)(chatSDK, props, dispatch, setAdapter, _startChat.initStartChat, state);
136
- // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
137
- if (state.appStates.conversationState === _ConversationState.ConversationState.Active || state.appStates.conversationState === _ConversationState.ConversationState.ReconnectChat) {
138
- return;
139
- }
143
+ const reconnectTriggered = await isReconnectTriggered();
144
+ if (!reconnectTriggered) {
145
+ await (0, _startChat.initStartChat)(chatSDK, dispatch, setAdapter, state, props, optionalParams);
140
146
  }
141
- await (0, _startChat.initStartChat)(chatSDK, dispatch, setAdapter, state, props, optionalParams);
142
147
  return;
143
148
  }
144
149
  }
145
150
  if (isChatValid === false) {
146
151
  if (localState) {
147
152
  // adding the reconnect logic for the case when customer tries to reconnect from a new browser or InPrivate browser
148
- if ((0, _reconnectChatHelper.isReconnectEnabled)(props.chatConfig) === true && !(0, _reconnectChatHelper.isPersistentEnabled)(props.chatConfig)) {
149
- await (0, _reconnectChatHelper.handleChatReconnect)(chatSDK, props, dispatch, setAdapter, _startChat.initStartChat, state);
150
- // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
151
- if (state.appStates.conversationState === _ConversationState.ConversationState.Active || state.appStates.conversationState === _ConversationState.ConversationState.ReconnectChat) {
152
- return;
153
- }
153
+ const reconnectTriggered = await isReconnectTriggered();
154
+ if (!reconnectTriggered) {
155
+ await (0, _startChat.setPreChatAndInitiateChat)(chatSDK, dispatch, setAdapter, undefined, undefined, localState, props);
154
156
  }
155
- await (0, _startChat.setPreChatAndInitiateChat)(chatSDK, dispatch, setAdapter, undefined, undefined, localState, props);
156
157
  return;
157
158
  } else {
158
159
  var _state$appStates4;
@@ -209,12 +209,17 @@ const createAttachmentMiddleware = enableInlinePlaying => {
209
209
  id: attachmentId,
210
210
  style: atttachmentAdaptiveCardStyles
211
211
  }, next(...args));
212
+ } else if (contentType.startsWith(_Constants.Constants.adaptiveCardContentTypePrefix)) {
213
+ console.warn(`${contentType} adaptive card type is currently not supported.`);
212
214
  }
213
215
  if ((_card$activity$channe = card.activity.channelData) !== null && _card$activity$channe !== void 0 && _card$activity$channe.middlewareData) {
214
216
  attachment.contentUrl = card.activity.channelData.middlewareData[attachment.name];
215
217
  } else if (attachment !== null && attachment !== void 0 && attachment.tempContentUrl) {
216
218
  attachment.contentUrl = attachment.tempContentUrl;
217
219
  }
220
+ if (!attachment.name) {
221
+ return next(...args);
222
+ }
218
223
  const fileExtension = attachment.name.substring(attachment.name.lastIndexOf(".") + 1, attachment.name.length) || attachment.name;
219
224
  const imageExtension = _Constants.Constants.imageRegex.test(attachment.name);
220
225
  const audioExtension = _Constants.Constants.audioMediaRegex.test(attachment.name);
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _WebChatActionType = require("../../enums/WebChatActionType");
8
+ var _Constants = require("../../../../../common/Constants");
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
10
+ const createMessageSequenceIdOverrideMiddleware = _ref => {
11
+ let {
12
+ dispatch
13
+ } = _ref;
14
+ return next => action => {
15
+ if (isApplicable(action)) {
16
+ return next(overrideSequenceIdWithOriginalMessageId(action));
17
+ }
18
+ return next(action);
19
+ };
20
+ };
21
+ const isApplicable = action => {
22
+ return action.type === _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY && isValidChannel(action) && isWebSequenceIdPresent(action) && lookupOriginalMessageId(action) !== undefined;
23
+ };
24
+ const isValidChannel = action => {
25
+ var _action$payload, _action$payload$activ;
26
+ return (action === null || action === void 0 ? void 0 : (_action$payload = action.payload) === null || _action$payload === void 0 ? void 0 : (_action$payload$activ = _action$payload.activity) === null || _action$payload$activ === void 0 ? void 0 : _action$payload$activ.channelId) === _Constants.Constants.acsChannel;
27
+ };
28
+ const isChannelDataPresent = action => {
29
+ var _action$payload2, _action$payload2$acti, _action$payload3, _action$payload3$acti;
30
+ return (action === null || action === void 0 ? void 0 : (_action$payload2 = action.payload) === null || _action$payload2 === void 0 ? void 0 : (_action$payload2$acti = _action$payload2.activity) === null || _action$payload2$acti === void 0 ? void 0 : _action$payload2$acti.channelData) !== undefined && (action === null || action === void 0 ? void 0 : (_action$payload3 = action.payload) === null || _action$payload3 === void 0 ? void 0 : (_action$payload3$acti = _action$payload3.activity) === null || _action$payload3$acti === void 0 ? void 0 : _action$payload3$acti.channelData) !== null;
31
+ };
32
+ const isWebSequenceIdPresent = action => {
33
+ if (!isChannelDataPresent(action)) return false;
34
+ const channelData = action.payload.activity.channelData;
35
+ return Object.keys(channelData).some(key => {
36
+ return key === _Constants.Constants.WebchatSequenceIdAttribute;
37
+ });
38
+ };
39
+ const overrideSequenceIdWithOriginalMessageId = action => {
40
+ const originalMessageId = extractOriginalMessageId(action);
41
+ const channelData = action.payload.activity.channelData;
42
+ if (originalMessageId === undefined) return action;
43
+ Object.keys(channelData).forEach(function (key) {
44
+ if (key === _Constants.Constants.WebchatSequenceIdAttribute && action.payload.activity.channelData[key] !== originalMessageId) {
45
+ action.payload.activity.channelData[key] = originalMessageId;
46
+ }
47
+ });
48
+ return action;
49
+ };
50
+
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
52
+ const extractOriginalMessageId = action => {
53
+ const originalMessageId = lookupOriginalMessageId(action);
54
+ if (typeof originalMessageId !== "string" || originalMessageId === "") {
55
+ return undefined;
56
+ }
57
+ const originalMessageIdResult = parseInt(originalMessageId);
58
+ return isNaN(originalMessageIdResult) ? undefined : originalMessageIdResult;
59
+ };
60
+ const lookupOriginalMessageId = action => {
61
+ var _action$payload4, _action$payload4$acti, _action$payload4$acti2, _action$payload4$acti3;
62
+ return action === null || action === void 0 ? void 0 : (_action$payload4 = action.payload) === null || _action$payload4 === void 0 ? void 0 : (_action$payload4$acti = _action$payload4.activity) === null || _action$payload4$acti === void 0 ? void 0 : (_action$payload4$acti2 = _action$payload4$acti.channelData) === null || _action$payload4$acti2 === void 0 ? void 0 : (_action$payload4$acti3 = _action$payload4$acti2.metadata) === null || _action$payload4$acti3 === void 0 ? void 0 : _action$payload4$acti3.OriginalMessageId;
63
+ };
64
+ var _default = createMessageSequenceIdOverrideMiddleware;
65
+ exports.default = _default;
@@ -0,0 +1,342 @@
1
+ "use strict";
2
+
3
+ var _Constants = require("../../../../../common/Constants");
4
+ var _WebChatActionType = require("../../enums/WebChatActionType");
5
+ var _messageSequenceIdOverrideMiddleware = _interopRequireDefault(require("./messageSequenceIdOverrideMiddleware"));
6
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
7
+ /* eslint-disable @typescript-eslint/no-explicit-any */
8
+
9
+ describe("messageSequenceIdOverrideMiddleware", () => {
10
+ it("sequenceId is overrided", () => {
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ const next = args => args;
13
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
+ const dispatch = () => {
15
+ return 1;
16
+ };
17
+ const action = {
18
+ type: _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY,
19
+ payload: {
20
+ text: "test-text",
21
+ activity: {
22
+ channelId: "ACS_CHANNEL",
23
+ from: {
24
+ role: "user"
25
+ },
26
+ channelData: {
27
+ metadata: {
28
+ "OriginalMessageId": "1683742135918"
29
+ },
30
+ "webchat:sequence-id": 12345
31
+ }
32
+ }
33
+ }
34
+ };
35
+ const middleware = (0, _messageSequenceIdOverrideMiddleware.default)(dispatch)(next)(action);
36
+ let resultValue;
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
38
+ const channelData = middleware.payload.activity.channelData;
39
+ Object.keys(channelData).forEach(function (key) {
40
+ if (key === _Constants.Constants.WebchatSequenceIdAttribute) {
41
+ resultValue = channelData[key];
42
+ }
43
+ });
44
+ expect(resultValue).toEqual(1683742135918);
45
+ });
46
+ it("sequenceId is not overrided due to empty string for originalID", () => {
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
+ const next = args => args;
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
+ const dispatch = () => {
51
+ return 1;
52
+ };
53
+ const action = {
54
+ type: _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY,
55
+ payload: {
56
+ text: "test-text",
57
+ activity: {
58
+ channelId: "ACS_CHANNEL",
59
+ from: {
60
+ role: "user"
61
+ },
62
+ channelData: {
63
+ metadata: {
64
+ "OriginalMessageId": ""
65
+ },
66
+ "webchat:sequence-id": 12345
67
+ }
68
+ }
69
+ }
70
+ };
71
+ const middleware = (0, _messageSequenceIdOverrideMiddleware.default)(dispatch)(next)(action);
72
+ let resultValue;
73
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
74
+ const channelData = middleware.payload.activity.channelData;
75
+ Object.keys(channelData).forEach(function (key) {
76
+ if (key === _Constants.Constants.WebchatSequenceIdAttribute) {
77
+ resultValue = channelData[key];
78
+ }
79
+ });
80
+ expect(resultValue).toEqual(12345);
81
+ });
82
+ it("sequenceId is not overrided, due to OriginalMessageId being not a string of numbers ", () => {
83
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
+ const next = args => args;
85
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
+ const dispatch = () => {
87
+ return 1;
88
+ };
89
+ const action = {
90
+ type: _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY,
91
+ payload: {
92
+ text: "test-text",
93
+ activity: {
94
+ channelId: "ACS_CHANNEL",
95
+ from: {
96
+ role: "user"
97
+ },
98
+ channelData: {
99
+ metadata: {
100
+ "OriginalMessageId": "abcdf"
101
+ },
102
+ "webchat:sequence-id": 12345
103
+ }
104
+ }
105
+ }
106
+ };
107
+ const middleware = (0, _messageSequenceIdOverrideMiddleware.default)(dispatch)(next)(action);
108
+ let resultValue;
109
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
110
+ const channelData = middleware.payload.activity.channelData;
111
+ Object.keys(channelData).forEach(function (key) {
112
+ if (key === _Constants.Constants.WebchatSequenceIdAttribute) {
113
+ resultValue = channelData[key];
114
+ }
115
+ });
116
+ expect(resultValue).toEqual(12345);
117
+ });
118
+ it("no changes since webchat id is not present", () => {
119
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
+ const next = args => args;
121
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
+ const dispatch = () => {
123
+ return 1;
124
+ };
125
+ const payloadExpected = {
126
+ payload: {
127
+ text: "test-text",
128
+ activity: {
129
+ channelId: "ACS_CHANNEL",
130
+ from: {
131
+ role: "user"
132
+ },
133
+ channelData: {
134
+ metadata: {
135
+ "OriginalMessageId": "123456789"
136
+ }
137
+ }
138
+ }
139
+ }
140
+ };
141
+ const action = {
142
+ type: _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY,
143
+ payload: {
144
+ text: "test-text",
145
+ activity: {
146
+ channelId: "ACS_CHANNEL",
147
+ from: {
148
+ role: "user"
149
+ },
150
+ channelData: {
151
+ metadata: {
152
+ "OriginalMessageId": "123456789"
153
+ }
154
+ }
155
+ }
156
+ }
157
+ };
158
+ const middleware = (0, _messageSequenceIdOverrideMiddleware.default)(dispatch)(next)(action);
159
+ expect(middleware.payload).toEqual(payloadExpected.payload);
160
+ });
161
+ it("no changes since OriginalMessageId is not present", () => {
162
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
163
+ const next = args => args;
164
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
165
+ const dispatch = () => {
166
+ return 1;
167
+ };
168
+ const payloadExpected = {
169
+ payload: {
170
+ text: "test-text",
171
+ activity: {
172
+ channelId: "ACS_CHANNEL",
173
+ from: {
174
+ role: "user"
175
+ },
176
+ channelData: {
177
+ metadata: {},
178
+ "webchat:sequence-id": 12345
179
+ }
180
+ }
181
+ }
182
+ };
183
+ const action = {
184
+ type: _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY,
185
+ payload: {
186
+ text: "test-text",
187
+ activity: {
188
+ channelId: "ACS_CHANNEL",
189
+ from: {
190
+ role: "user"
191
+ },
192
+ channelData: {
193
+ metadata: {},
194
+ "webchat:sequence-id": 12345
195
+ }
196
+ }
197
+ }
198
+ };
199
+ const middleware = (0, _messageSequenceIdOverrideMiddleware.default)(dispatch)(next)(action);
200
+ expect(middleware.payload).toEqual(payloadExpected.payload);
201
+ });
202
+ it("no override, since the type of message is not incoming activity", () => {
203
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
204
+ const next = args => args;
205
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
206
+ const dispatch = () => {
207
+ return 1;
208
+ };
209
+ const action = {
210
+ type: "something else",
211
+ payload: {
212
+ text: "test-text",
213
+ activity: {
214
+ channelId: "ACS_CHANNEL",
215
+ from: {
216
+ role: "user"
217
+ },
218
+ channelData: {
219
+ metadata: {
220
+ "OriginalMessageId": "1683742135918"
221
+ },
222
+ "webchat:sequence-id": 12345
223
+ }
224
+ }
225
+ }
226
+ };
227
+ const middleware = (0, _messageSequenceIdOverrideMiddleware.default)(dispatch)(next)(action);
228
+ let resultValue;
229
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
230
+ const channelData = middleware.payload.activity.channelData;
231
+ Object.keys(channelData).forEach(function (key) {
232
+ if (key === _Constants.Constants.WebchatSequenceIdAttribute) {
233
+ resultValue = channelData[key];
234
+ }
235
+ });
236
+ expect(resultValue).toEqual(12345);
237
+ });
238
+ it("no override, since the channel is not ACS", () => {
239
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
240
+ const next = args => args;
241
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
242
+ const dispatch = () => {
243
+ return 1;
244
+ };
245
+ const action = {
246
+ type: _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY,
247
+ payload: {
248
+ text: "test-text",
249
+ activity: {
250
+ channelId: "something_else",
251
+ from: {
252
+ role: "user"
253
+ },
254
+ channelData: {
255
+ metadata: {
256
+ "OriginalMessageId": "1683742135918"
257
+ },
258
+ "webchat:sequence-id": 12345
259
+ }
260
+ }
261
+ }
262
+ };
263
+ const middleware = (0, _messageSequenceIdOverrideMiddleware.default)(dispatch)(next)(action);
264
+ let resultValue;
265
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
266
+ const channelData = middleware.payload.activity.channelData;
267
+ Object.keys(channelData).forEach(function (key) {
268
+ if (key === _Constants.Constants.WebchatSequenceIdAttribute) {
269
+ resultValue = channelData[key];
270
+ }
271
+ });
272
+ expect(resultValue).toEqual(12345);
273
+ });
274
+ it("no override, since the channel channelData is not present", () => {
275
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
276
+ const next = args => args;
277
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
278
+ const dispatch = () => {
279
+ return 1;
280
+ };
281
+ const action = {
282
+ type: _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY,
283
+ payload: {
284
+ text: "test-text channel data is not present",
285
+ activity: {
286
+ channelId: "ACS_CHANNEL",
287
+ from: {
288
+ role: "user"
289
+ }
290
+ }
291
+ }
292
+ };
293
+ const middleware = (0, _messageSequenceIdOverrideMiddleware.default)(dispatch)(next)(action);
294
+ expect(middleware.payload).toEqual(action.payload);
295
+ });
296
+ it("no override, since channelData is empty object", () => {
297
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
298
+ const next = args => args;
299
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
300
+ const dispatch = () => {
301
+ return 1;
302
+ };
303
+ const action = {
304
+ type: _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY,
305
+ payload: {
306
+ text: "test-text channel data empty",
307
+ activity: {
308
+ channelId: "ACS_CHANNEL",
309
+ from: {
310
+ role: "user"
311
+ },
312
+ channelData: {}
313
+ }
314
+ }
315
+ };
316
+ const middleware = (0, _messageSequenceIdOverrideMiddleware.default)(dispatch)(next)(action);
317
+ expect(middleware.payload).toEqual(action.payload);
318
+ });
319
+ it("no override, since channelData null", () => {
320
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
321
+ const next = args => args;
322
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
323
+ const dispatch = () => {
324
+ return 1;
325
+ };
326
+ const action = {
327
+ type: _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY,
328
+ payload: {
329
+ text: "test-channel Data null",
330
+ activity: {
331
+ channelId: "ACS_CHANNEL",
332
+ from: {
333
+ role: "user"
334
+ },
335
+ channelData: null
336
+ }
337
+ }
338
+ };
339
+ const middleware = (0, _messageSequenceIdOverrideMiddleware.default)(dispatch)(next)(action);
340
+ expect(middleware.payload).toEqual(action.payload);
341
+ });
342
+ });