@adobe/alloy 2.30.1-beta.2 → 2.30.1-beta.21

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 (203) hide show
  1. package/libEs5/components/Advertising/handlers/onBeforeSendEventHandler.js +8 -2
  2. package/libEs5/components/Advertising/handlers/viewThroughHandler.js +8 -2
  3. package/libEs5/components/Advertising/identities/collectSurferId.js +8 -1
  4. package/libEs5/components/BrandConcierge/constants.js +16 -0
  5. package/libEs5/components/BrandConcierge/createBuildEndpointUrl.js +33 -0
  6. package/libEs5/components/BrandConcierge/createConversationServiceRequest.js +35 -0
  7. package/libEs5/components/BrandConcierge/createSendConversationEvent.js +146 -0
  8. package/libEs5/components/BrandConcierge/createSendConversationServiceRequest.js +85 -0
  9. package/libEs5/components/BrandConcierge/createStreamParser.js +96 -0
  10. package/libEs5/components/BrandConcierge/createTimeoutWrapper.js +52 -0
  11. package/libEs5/components/BrandConcierge/index.js +104 -0
  12. package/libEs5/components/BrandConcierge/utils.js +33 -0
  13. package/libEs5/components/BrandConcierge/validateMessage.js +41 -0
  14. package/libEs5/components/Consent/types.js +12 -0
  15. package/libEs5/components/Context/createComponent.js +1 -2
  16. package/libEs5/components/Context/implementationDetails.js +7 -9
  17. package/libEs5/components/Context/index.js +4 -1
  18. package/libEs5/components/Context/injectDevice.js +2 -2
  19. package/libEs5/components/Context/injectEnvironment.js +2 -2
  20. package/libEs5/components/Context/injectHighEntropyUserAgentHints.js +2 -2
  21. package/libEs5/components/Context/injectOneTimeAnalyticsReferrer.js +49 -0
  22. package/libEs5/components/Context/injectPlaceContext.js +2 -2
  23. package/libEs5/components/Context/injectTimestamp.js +2 -3
  24. package/libEs5/components/Context/injectWeb.js +9 -11
  25. package/libEs5/components/EventMerge/createEventMergeId.js +1 -1
  26. package/libEs5/components/Personalization/createComponent.js +3 -1
  27. package/libEs5/components/Personalization/createFetchDataHandler.js +4 -3
  28. package/libEs5/components/Personalization/createNotificationHandler.js +5 -3
  29. package/libEs5/components/Personalization/createOnDecisionHandler.js +4 -3
  30. package/libEs5/components/Personalization/createPersonalizationDetails.js +1 -1
  31. package/libEs5/components/Personalization/dom-actions/initDomActionsModules.js +1 -1
  32. package/libEs5/components/Personalization/handlers/createProcessInAppMessage.js +2 -1
  33. package/libEs5/components/Personalization/handlers/createProcessRedirect.js +2 -1
  34. package/libEs5/components/Personalization/handlers/injectCreateProposition.js +4 -1
  35. package/libEs5/components/Personalization/in-app-message-actions/actions/displayIframeContent.js +4 -2
  36. package/libEs5/components/Personalization/index.js +2 -2
  37. package/libEs5/components/PushNotifications/request/makeSendServiceWorkerTrackingData.js +1 -1
  38. package/libEs5/components/PushNotifications/types.js +12 -0
  39. package/libEs5/components/RulesEngine/createApplyResponse.js +3 -1
  40. package/libEs5/components/RulesEngine/types.js +12 -0
  41. package/libEs5/constants/libraryVersion.js +1 -1
  42. package/libEs5/constants/surface.js +19 -0
  43. package/libEs5/core/componentCreators.js +8 -1
  44. package/libEs5/core/consent/types.js +12 -0
  45. package/libEs5/core/createEvent.js +3 -0
  46. package/libEs5/core/edgeNetwork/types.js +12 -0
  47. package/libEs5/core/identity/types.js +12 -0
  48. package/libEs5/core/index.js +5 -1
  49. package/libEs5/core/types.js +12 -0
  50. package/libEs5/utils/createCollect.js +4 -2
  51. package/libEs5/utils/deepAssign.js +5 -0
  52. package/libEs5/utils/dom/createGetPageLocation.js +20 -0
  53. package/libEs5/utils/index.js +8 -1
  54. package/libEs5/utils/request/createRequest.js +5 -1
  55. package/libEs5/utils/request/types.js +12 -0
  56. package/libEs5/utils/surfaceUtils.js +82 -0
  57. package/libEs5/utils/types.js +12 -0
  58. package/libEs5/utils/uuid.js +1 -0
  59. package/libEs6/components/Advertising/handlers/onBeforeSendEventHandler.js +8 -2
  60. package/libEs6/components/Advertising/handlers/viewThroughHandler.js +8 -2
  61. package/libEs6/components/Advertising/identities/collectSurferId.js +8 -1
  62. package/libEs6/components/BrandConcierge/constants.js +13 -0
  63. package/libEs6/components/BrandConcierge/createBuildEndpointUrl.js +30 -0
  64. package/libEs6/components/BrandConcierge/createConversationServiceRequest.js +31 -0
  65. package/libEs6/components/BrandConcierge/createSendConversationEvent.js +142 -0
  66. package/libEs6/components/BrandConcierge/createSendConversationServiceRequest.js +81 -0
  67. package/libEs6/components/BrandConcierge/createStreamParser.js +92 -0
  68. package/libEs6/components/BrandConcierge/createTimeoutWrapper.js +49 -0
  69. package/libEs6/components/BrandConcierge/index.js +100 -0
  70. package/libEs6/components/BrandConcierge/utils.js +27 -0
  71. package/libEs6/components/BrandConcierge/validateMessage.js +37 -0
  72. package/libEs6/components/Consent/types.js +12 -0
  73. package/libEs6/components/Context/createComponent.js +1 -2
  74. package/libEs6/components/Context/implementationDetails.js +7 -9
  75. package/libEs6/components/Context/index.js +4 -1
  76. package/libEs6/components/Context/injectDevice.js +3 -3
  77. package/libEs6/components/Context/injectEnvironment.js +3 -3
  78. package/libEs6/components/Context/injectHighEntropyUserAgentHints.js +3 -3
  79. package/libEs6/components/Context/injectOneTimeAnalyticsReferrer.js +46 -0
  80. package/libEs6/components/Context/injectPlaceContext.js +3 -3
  81. package/libEs6/components/Context/injectTimestamp.js +2 -3
  82. package/libEs6/components/Context/injectWeb.js +9 -11
  83. package/libEs6/components/EventMerge/createEventMergeId.js +1 -1
  84. package/libEs6/components/Personalization/createComponent.js +3 -1
  85. package/libEs6/components/Personalization/createFetchDataHandler.js +4 -3
  86. package/libEs6/components/Personalization/createNotificationHandler.js +5 -3
  87. package/libEs6/components/Personalization/createOnDecisionHandler.js +4 -3
  88. package/libEs6/components/Personalization/createPersonalizationDetails.js +1 -1
  89. package/libEs6/components/Personalization/dom-actions/initDomActionsModules.js +1 -1
  90. package/libEs6/components/Personalization/handlers/createProcessInAppMessage.js +2 -1
  91. package/libEs6/components/Personalization/handlers/createProcessRedirect.js +2 -1
  92. package/libEs6/components/Personalization/handlers/injectCreateProposition.js +4 -1
  93. package/libEs6/components/Personalization/in-app-message-actions/actions/displayIframeContent.js +4 -2
  94. package/libEs6/components/Personalization/index.js +2 -2
  95. package/libEs6/components/PushNotifications/request/makeSendServiceWorkerTrackingData.js +1 -1
  96. package/libEs6/components/PushNotifications/types.js +12 -0
  97. package/libEs6/components/RulesEngine/createApplyResponse.js +3 -1
  98. package/libEs6/components/RulesEngine/types.js +12 -0
  99. package/libEs6/constants/libraryVersion.js +1 -1
  100. package/libEs6/constants/surface.js +16 -0
  101. package/libEs6/core/componentCreators.js +2 -1
  102. package/libEs6/core/consent/types.js +12 -0
  103. package/libEs6/core/createEvent.js +3 -0
  104. package/libEs6/core/edgeNetwork/types.js +12 -0
  105. package/libEs6/core/identity/types.js +12 -0
  106. package/libEs6/core/index.js +5 -1
  107. package/libEs6/core/types.js +12 -0
  108. package/libEs6/utils/createCollect.js +4 -2
  109. package/libEs6/utils/deepAssign.js +6 -0
  110. package/libEs6/utils/dom/createGetPageLocation.js +17 -0
  111. package/libEs6/utils/index.js +2 -1
  112. package/libEs6/utils/request/createRequest.js +5 -1
  113. package/libEs6/utils/request/types.js +12 -0
  114. package/libEs6/utils/surfaceUtils.js +76 -0
  115. package/libEs6/utils/types.js +12 -0
  116. package/libEs6/utils/uuid.js +1 -0
  117. package/package.json +44 -48
  118. package/scripts/helpers/path.js +12 -0
  119. package/scripts/helpers/versionBabelPlugin.js +12 -0
  120. package/types/components/Advertising/handlers/onBeforeSendEventHandler.d.ts.map +1 -1
  121. package/types/components/Advertising/handlers/viewThroughHandler.d.ts.map +1 -1
  122. package/types/components/Advertising/identities/collectSurferId.d.ts.map +1 -1
  123. package/types/components/BrandConcierge/constants.d.ts +3 -0
  124. package/types/components/BrandConcierge/constants.d.ts.map +1 -0
  125. package/types/components/BrandConcierge/createBuildEndpointUrl.d.ts +9 -0
  126. package/types/components/BrandConcierge/createBuildEndpointUrl.d.ts.map +1 -0
  127. package/types/components/BrandConcierge/createConversationServiceRequest.d.ts +7 -0
  128. package/types/components/BrandConcierge/createConversationServiceRequest.d.ts.map +1 -0
  129. package/types/components/BrandConcierge/createSendConversationEvent.d.ts +15 -0
  130. package/types/components/BrandConcierge/createSendConversationEvent.d.ts.map +1 -0
  131. package/types/components/BrandConcierge/createSendConversationServiceRequest.d.ts +11 -0
  132. package/types/components/BrandConcierge/createSendConversationServiceRequest.d.ts.map +1 -0
  133. package/types/components/BrandConcierge/createStreamParser.d.ts +3 -0
  134. package/types/components/BrandConcierge/createStreamParser.d.ts.map +1 -0
  135. package/types/components/BrandConcierge/createTimeoutWrapper.d.ts +3 -0
  136. package/types/components/BrandConcierge/createTimeoutWrapper.d.ts.map +1 -0
  137. package/types/components/BrandConcierge/index.d.ts +31 -0
  138. package/types/components/BrandConcierge/index.d.ts.map +1 -0
  139. package/types/components/BrandConcierge/utils.d.ts +6 -0
  140. package/types/components/BrandConcierge/utils.d.ts.map +1 -0
  141. package/types/components/BrandConcierge/validateMessage.d.ts +5 -0
  142. package/types/components/BrandConcierge/validateMessage.d.ts.map +1 -0
  143. package/types/components/Consent/types.d.ts.map +1 -1
  144. package/types/components/Context/createComponent.d.ts +1 -1
  145. package/types/components/Context/createComponent.d.ts.map +1 -1
  146. package/types/components/Context/implementationDetails.d.ts +1 -1
  147. package/types/components/Context/implementationDetails.d.ts.map +1 -1
  148. package/types/components/Context/index.d.ts +1 -1
  149. package/types/components/Context/index.d.ts.map +1 -1
  150. package/types/components/Context/injectDevice.d.ts +1 -1
  151. package/types/components/Context/injectDevice.d.ts.map +1 -1
  152. package/types/components/Context/injectEnvironment.d.ts +1 -1
  153. package/types/components/Context/injectEnvironment.d.ts.map +1 -1
  154. package/types/components/Context/injectHighEntropyUserAgentHints.d.ts +1 -1
  155. package/types/components/Context/injectHighEntropyUserAgentHints.d.ts.map +1 -1
  156. package/types/components/Context/injectOneTimeAnalyticsReferrer.d.ts +3 -0
  157. package/types/components/Context/injectOneTimeAnalyticsReferrer.d.ts.map +1 -0
  158. package/types/components/Context/injectPlaceContext.d.ts +1 -1
  159. package/types/components/Context/injectPlaceContext.d.ts.map +1 -1
  160. package/types/components/Context/injectTimestamp.d.ts +1 -1
  161. package/types/components/Context/injectTimestamp.d.ts.map +1 -1
  162. package/types/components/Context/injectWeb.d.ts +1 -1
  163. package/types/components/Context/injectWeb.d.ts.map +1 -1
  164. package/types/components/Personalization/createComponent.d.ts.map +1 -1
  165. package/types/components/Personalization/createFetchDataHandler.d.ts +2 -1
  166. package/types/components/Personalization/createFetchDataHandler.d.ts.map +1 -1
  167. package/types/components/Personalization/createNotificationHandler.d.ts +1 -1
  168. package/types/components/Personalization/createNotificationHandler.d.ts.map +1 -1
  169. package/types/components/Personalization/createOnDecisionHandler.d.ts +2 -1
  170. package/types/components/Personalization/createOnDecisionHandler.d.ts.map +1 -1
  171. package/types/components/Personalization/createPersonalizationDetails.d.ts.map +1 -1
  172. package/types/components/Personalization/handlers/createProcessInAppMessage.d.ts.map +1 -1
  173. package/types/components/Personalization/handlers/createProcessRedirect.d.ts.map +1 -1
  174. package/types/components/Personalization/handlers/injectCreateProposition.d.ts +2 -1
  175. package/types/components/Personalization/handlers/injectCreateProposition.d.ts.map +1 -1
  176. package/types/components/Personalization/in-app-message-actions/actions/displayIframeContent.d.ts.map +1 -1
  177. package/types/components/Personalization/index.d.ts.map +1 -1
  178. package/types/components/PushNotifications/types.d.ts.map +1 -1
  179. package/types/components/RulesEngine/createApplyResponse.d.ts.map +1 -1
  180. package/types/components/RulesEngine/index.d.ts.map +1 -1
  181. package/types/components/RulesEngine/types.d.ts.map +1 -1
  182. package/types/constants/surface.d.ts +5 -0
  183. package/types/constants/surface.d.ts.map +1 -0
  184. package/types/core/componentCreators.d.ts +1 -0
  185. package/types/core/consent/types.d.ts.map +1 -1
  186. package/types/core/createEvent.d.ts +1 -0
  187. package/types/core/createEvent.d.ts.map +1 -1
  188. package/types/core/edgeNetwork/types.d.ts.map +1 -1
  189. package/types/core/identity/types.d.ts.map +1 -1
  190. package/types/core/index.d.ts.map +1 -1
  191. package/types/core/types.d.ts.map +1 -1
  192. package/types/utils/createCollect.d.ts +2 -1
  193. package/types/utils/createCollect.d.ts.map +1 -1
  194. package/types/utils/deepAssign.d.ts.map +1 -1
  195. package/types/utils/dom/createGetPageLocation.d.ts +5 -0
  196. package/types/utils/dom/createGetPageLocation.d.ts.map +1 -0
  197. package/types/utils/index.d.ts +1 -0
  198. package/types/utils/request/createRequest.d.ts.map +1 -1
  199. package/types/utils/request/types.d.ts.map +1 -1
  200. package/types/utils/surfaceUtils.d.ts +4 -0
  201. package/types/utils/surfaceUtils.d.ts.map +1 -0
  202. package/types/utils/types.d.ts.map +1 -1
  203. package/types/utils/uuid.d.ts.map +1 -1
@@ -0,0 +1,81 @@
1
+ /*
2
+ Copyright 2025 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ import { stackError } from "../../utils/index.js";
13
+ export default ({
14
+ logger,
15
+ fetch
16
+ }) => {
17
+ return async ({
18
+ requestId,
19
+ url,
20
+ request,
21
+ streamingEnabled = true
22
+ }) => {
23
+ const payload = request.getPayload();
24
+ const stringifiedPayload = JSON.stringify(payload);
25
+ const parsedPayload = JSON.parse(stringifiedPayload);
26
+ const headers = {
27
+ "Content-Type": "text/plain"
28
+ };
29
+ if (streamingEnabled) {
30
+ headers.Accept = "text/event-stream";
31
+ } else {
32
+ headers.Accept = "text/plain";
33
+ }
34
+ logger.logOnBeforeNetworkRequest({
35
+ url,
36
+ requestId,
37
+ payload: parsedPayload
38
+ });
39
+ const fetchWithRetries = async (attemptNumber = 1) => {
40
+ const maxAttempts = 4;
41
+ const retryDelays = [2000, 3000, 5000];
42
+ try {
43
+ const response = await fetch(url, {
44
+ method: "POST",
45
+ headers: headers,
46
+ body: stringifiedPayload
47
+ });
48
+ if (!response.ok) {
49
+ throw new Error(`Request failed with status ${response.status}`);
50
+ }
51
+ return response;
52
+ } catch (error) {
53
+ if (attemptNumber < maxAttempts) {
54
+ const delay = retryDelays[attemptNumber - 1];
55
+ logger.logOnNetworkError({
56
+ requestId,
57
+ url,
58
+ payload: parsedPayload,
59
+ error: new Error(`Attempt ${attemptNumber} failed, retrying in ${delay}ms: ${error.message}`)
60
+ });
61
+ await new Promise(resolve => setTimeout(resolve, delay));
62
+ return fetchWithRetries(attemptNumber + 1);
63
+ }
64
+ logger.logOnNetworkError({
65
+ requestId,
66
+ url,
67
+ payload: parsedPayload,
68
+ error
69
+ });
70
+ throw stackError({
71
+ error,
72
+ message: "Network request failed after all retries."
73
+ });
74
+ }
75
+ };
76
+ const executeRequest = async () => {
77
+ return fetchWithRetries();
78
+ };
79
+ return executeRequest();
80
+ };
81
+ };
@@ -0,0 +1,92 @@
1
+ /*
2
+ Copyright 2024 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ export default () => {
13
+ // SSE streams are always UTF-8 encoded per specification
14
+ const ENCODING = "utf-8";
15
+ // SSE spec allows three line ending styles: CRLF (\r\n), LF (\n), or CR (\r)
16
+ const LINE_ENDING_REGEX = /\r\n|\r|\n/;
17
+ // Events are separated by blank lines (double line endings)
18
+ const EVENT_SEPARATOR_REGEX = /\r\n\r\n|\n\n|\r\r/;
19
+
20
+ /**
21
+ * Parse a single SSE event from raw event data.
22
+ * Follows the Server-Sent Events specification (https://html.spec.whatwg.org/multipage/server-sent-events.html)
23
+ *
24
+ * @param {string} eventData - Raw event data (multi-line string containing SSE fields)
25
+ * @returns {Object|null} - Parsed SSE event with structure { type, data, id } or null if invalid
26
+ */
27
+ const parseEventFromBuffer = eventData => {
28
+ const lines = eventData.split(LINE_ENDING_REGEX);
29
+ const parsedEvent = {};
30
+ for (const line of lines) {
31
+ const trimmedLine = line.trim();
32
+ if (!trimmedLine) {
33
+ continue;
34
+ }
35
+ const colonIndex = trimmedLine.indexOf(":");
36
+ if (colonIndex === -1) {
37
+ continue;
38
+ }
39
+ const field = trimmedLine.substring(0, colonIndex).trim();
40
+ const value = trimmedLine.substring(colonIndex + 1).trim();
41
+ if (field === "data") {
42
+ parsedEvent.data = (parsedEvent.data || "") + value;
43
+ } else if (field === "event") {
44
+ parsedEvent.type = value;
45
+ } else if (field === "id") {
46
+ parsedEvent.id = value;
47
+ }
48
+ }
49
+ return parsedEvent.data ? parsedEvent : null;
50
+ };
51
+
52
+ /**
53
+ * Parse SSE stream using callbacks.
54
+ * Uses modern async iteration (for await...of) for clean, performant stream processing.
55
+ *
56
+ * @param {ReadableStream} stream - The readable stream from fetch response
57
+ * @param {Function} onEvent - Callback function called for each parsed event
58
+ */
59
+ return async (stream, onEvent) => {
60
+ const decoder = new TextDecoder(ENCODING);
61
+ let buffer = "";
62
+ try {
63
+ for await (const chunk of stream) {
64
+ buffer += decoder.decode(chunk, {
65
+ stream: true
66
+ });
67
+ const events = buffer.split(EVENT_SEPARATOR_REGEX);
68
+ buffer = events.pop() || "";
69
+ for (const eventData of events) {
70
+ const trimmedEvent = eventData.trim();
71
+ if (trimmedEvent) {
72
+ const event = parseEventFromBuffer(trimmedEvent);
73
+ if (event !== null) {
74
+ onEvent(event);
75
+ }
76
+ }
77
+ }
78
+ }
79
+ const trimmedBuffer = buffer.trim();
80
+ if (trimmedBuffer) {
81
+ const event = parseEventFromBuffer(trimmedBuffer);
82
+ if (event !== null) {
83
+ onEvent(event);
84
+ }
85
+ }
86
+ } catch (error) {
87
+ onEvent({
88
+ error
89
+ });
90
+ }
91
+ };
92
+ };
@@ -0,0 +1,49 @@
1
+ /*
2
+ Copyright 2025 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ import { STREAM_START_TIMEOUT_MS } from "./constants.js";
13
+
14
+ /**
15
+ * Creates a wrapper around a callback that implements a timeout for the first call.
16
+ * If the callback is not invoked within the specified timeout, an error is passed to it.
17
+ * After timeout fires, all subsequent calls are ignored.
18
+ *
19
+ * @param {Function} callback - The callback function to wrap
20
+ * @returns {Function} Wrapped callback function
21
+ */
22
+ export default ({
23
+ onStreamResponseCallback
24
+ }) => {
25
+ const timeoutMs = STREAM_START_TIMEOUT_MS;
26
+ let firstCallMade = false;
27
+ let timedOut = false;
28
+ const timeoutId = setTimeout(() => {
29
+ // Double-check firstCallMade right before firing
30
+ if (!firstCallMade) {
31
+ timedOut = true;
32
+ onStreamResponseCallback({
33
+ error: {
34
+ message: "Stream timeout: No data received within 10 seconds"
35
+ }
36
+ });
37
+ }
38
+ }, timeoutMs);
39
+ return event => {
40
+ if (timedOut) {
41
+ return;
42
+ }
43
+ if (!firstCallMade) {
44
+ firstCallMade = true;
45
+ clearTimeout(timeoutId);
46
+ }
47
+ onStreamResponseCallback(event);
48
+ };
49
+ };
@@ -0,0 +1,100 @@
1
+ /*
2
+ Copyright 2024 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ import validateMessage from "./validateMessage.js";
13
+ import createSendConversationEvent from "./createSendConversationEvent.js";
14
+ import createBuildEndpointUrl from "./createBuildEndpointUrl.js";
15
+ import queryString from "@adobe/reactor-query-string";
16
+ import { getNamespacedCookieName } from "../../utils/index.js";
17
+ import { BC_SESSION_COOKIE_NAME } from "./constants.js";
18
+ import { boolean, objectOf } from "../../utils/validation/index.js";
19
+ import createGetEcidFromCookie from "../../utils/createDecodeKndctrCookie.js";
20
+ import createSendConversationServiceRequest from "./createSendConversationServiceRequest.js";
21
+ const createConciergeComponent = ({
22
+ loggingCookieJar,
23
+ logger,
24
+ eventManager,
25
+ consent,
26
+ instanceName,
27
+ sendEdgeNetworkRequest,
28
+ config,
29
+ lifecycle,
30
+ cookieTransfer,
31
+ createResponse,
32
+ apexDomain
33
+ }) => {
34
+ const {
35
+ fetch
36
+ } = window;
37
+ if (!config.stickyConversationSession) {
38
+ loggingCookieJar.remove(getNamespacedCookieName(config.orgId, BC_SESSION_COOKIE_NAME), {
39
+ domain: apexDomain
40
+ });
41
+ }
42
+ const buildEndpointUrl = createBuildEndpointUrl({
43
+ queryString
44
+ });
45
+ const sendConversationServiceRequest = createSendConversationServiceRequest({
46
+ logger,
47
+ fetch,
48
+ config
49
+ });
50
+ const decodeKndctrCookie = createGetEcidFromCookie({
51
+ orgId: config.orgId,
52
+ cookieJar: loggingCookieJar,
53
+ logger
54
+ });
55
+ const sendConversationEvent = createSendConversationEvent({
56
+ loggingCookieJar,
57
+ logger,
58
+ eventManager,
59
+ consent,
60
+ instanceName,
61
+ sendEdgeNetworkRequest,
62
+ config,
63
+ buildEndpointUrl,
64
+ lifecycle,
65
+ cookieTransfer,
66
+ createResponse,
67
+ sendConversationServiceRequest,
68
+ decodeKndctrCookie
69
+ });
70
+ return {
71
+ lifecycle: {
72
+ onBeforeEvent({
73
+ event
74
+ }) {
75
+ const parsedParams = queryString.parse(window.location.search);
76
+ if (parsedParams.source) {
77
+ const source = parsedParams.source;
78
+ event.mergeXdm({
79
+ channel: {
80
+ referringSource: source
81
+ }
82
+ });
83
+ }
84
+ }
85
+ },
86
+ commands: {
87
+ sendConversationEvent: {
88
+ optionsValidator: options => validateMessage({
89
+ options
90
+ }),
91
+ run: sendConversationEvent
92
+ }
93
+ }
94
+ };
95
+ };
96
+ createConciergeComponent.namespace = "BrandConcierge";
97
+ createConciergeComponent.configValidators = objectOf({
98
+ stickyConversationSession: boolean().default(false)
99
+ });
100
+ export default createConciergeComponent;
@@ -0,0 +1,27 @@
1
+ /*
2
+ Copyright 2025 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ import { getNamespacedCookieName, createGetPageLocation } from "../../utils/index.js";
13
+ import { buildPageSurface } from "../../utils/surfaceUtils.js";
14
+ import { BC_SESSION_COOKIE_NAME } from "./constants.js";
15
+ export const getPageSurface = () => {
16
+ const pageLocation = createGetPageLocation({
17
+ window: window
18
+ });
19
+ return buildPageSurface(pageLocation);
20
+ };
21
+ export const getConciergeSessionCookie = ({
22
+ loggingCookieJar,
23
+ config
24
+ }) => {
25
+ const cookieName = getNamespacedCookieName(config.orgId, BC_SESSION_COOKIE_NAME);
26
+ return loggingCookieJar.get(cookieName);
27
+ };
@@ -0,0 +1,37 @@
1
+ /*
2
+ Copyright 2025 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ import { anyOf, arrayOf, objectOf, string } from "../../utils/validation/index.js";
13
+ export default ({
14
+ options
15
+ }) => {
16
+ const brandConciergeEventValidator = anyOf([objectOf({
17
+ message: string().required()
18
+ }), objectOf({
19
+ xdm: objectOf({
20
+ interactionId: string(),
21
+ conversationId: string(),
22
+ conversation: objectOf({
23
+ feedback: objectOf({
24
+ classification: string(),
25
+ comment: string(),
26
+ reasons: arrayOf(string())
27
+ })
28
+ })
29
+ })
30
+ }).required(), objectOf({
31
+ data: objectOf({
32
+ type: string().required(),
33
+ payload: objectOf({})
34
+ }).required()
35
+ })]);
36
+ return brandConciergeEventValidator(options);
37
+ };
@@ -1,3 +1,15 @@
1
+ /*
2
+ Copyright 2025 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+
1
13
  /**
2
14
  * Request payload object with methods for merging different types of data.
3
15
  *
@@ -24,8 +24,7 @@ export default (config, logger, optionalContexts, requiredContexts) => {
24
24
  onBeforeEvent({
25
25
  event
26
26
  }) {
27
- const xdm = {};
28
- return Promise.all(contexts.map(context => Promise.resolve(context(xdm, logger)))).then(() => event.mergeXdm(xdm));
27
+ return Promise.all(contexts.map(context => Promise.resolve(context(event, logger))));
29
28
  }
30
29
  }
31
30
  };
@@ -9,16 +9,14 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
9
9
  OF ANY KIND, either express or implied. See the License for the specific language
10
10
  governing permissions and limitations under the License.
11
11
  */
12
- import { deepAssign } from "../../utils/index.js";
13
12
  import libraryName from "../../constants/libraryName.js";
14
13
  import libraryVersion from "../../constants/libraryVersion.js";
15
- export default xdm => {
16
- const implementationDetails = {
17
- name: libraryName,
18
- version: libraryVersion,
19
- environment: "browser"
20
- };
21
- deepAssign(xdm, {
22
- implementationDetails
14
+ export default event => {
15
+ event.mergeXdm({
16
+ implementationDetails: {
17
+ name: libraryName,
18
+ version: libraryVersion,
19
+ environment: "browser"
20
+ }
23
21
  });
24
22
  };
@@ -18,6 +18,7 @@ import injectTimestamp from "./injectTimestamp.js";
18
18
  import implementationDetails from "./implementationDetails.js";
19
19
  import createComponent from "./createComponent.js";
20
20
  import injectHighEntropyUserAgentHints from "./injectHighEntropyUserAgentHints.js";
21
+ import injectOneTimeAnalyticsReferrer from "./injectOneTimeAnalyticsReferrer.js";
21
22
  import { arrayOf, objectOf, string } from "../../utils/validation/index.js";
22
23
  const web = injectWeb(window);
23
24
  const device = injectDevice(window);
@@ -25,6 +26,7 @@ const environment = injectEnvironment(window);
25
26
  const placeContext = injectPlaceContext(() => new Date());
26
27
  const timestamp = injectTimestamp(() => new Date());
27
28
  const highEntropyUserAgentHints = injectHighEntropyUserAgentHints(navigator);
29
+ const oneTimeAnalyticsReferrer = injectOneTimeAnalyticsReferrer(window);
28
30
  const defaultEnabledContexts = {
29
31
  web,
30
32
  device,
@@ -32,7 +34,8 @@ const defaultEnabledContexts = {
32
34
  placeContext
33
35
  };
34
36
  const defaultDisabledContexts = {
35
- highEntropyUserAgentHints
37
+ highEntropyUserAgentHints,
38
+ oneTimeAnalyticsReferrer
36
39
  };
37
40
  const optionalContexts = {
38
41
  ...defaultEnabledContexts,
@@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag
10
10
  governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import { deepAssign, isFunction, toInteger } from "../../utils/index.js";
13
+ import { isFunction, toInteger } from "../../utils/index.js";
14
14
  const getScreenOrientationViaProperty = window => {
15
15
  const {
16
16
  screen: {
@@ -41,7 +41,7 @@ const getScreenOrientationViaMediaQuery = window => {
41
41
  return null;
42
42
  };
43
43
  export default window => {
44
- return xdm => {
44
+ return event => {
45
45
  const {
46
46
  screen: {
47
47
  width,
@@ -62,7 +62,7 @@ export default window => {
62
62
  device.screenOrientation = orientation;
63
63
  }
64
64
  if (Object.keys(device).length > 0) {
65
- deepAssign(xdm, {
65
+ event.mergeXdm({
66
66
  device
67
67
  });
68
68
  }
@@ -10,9 +10,9 @@ OF ANY KIND, either express or implied. See the License for the specific languag
10
10
  governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import { deepAssign, toInteger } from "../../utils/index.js";
13
+ import { toInteger } from "../../utils/index.js";
14
14
  export default window => {
15
- return xdm => {
15
+ return event => {
16
16
  const {
17
17
  document: {
18
18
  documentElement: {
@@ -35,7 +35,7 @@ export default window => {
35
35
  environment.browserDetails = environment.browserDetails || {};
36
36
  environment.browserDetails.viewportHeight = viewportHeight;
37
37
  }
38
- deepAssign(xdm, {
38
+ event.mergeXdm({
39
39
  environment
40
40
  });
41
41
  };
@@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag
10
10
  governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import { deepAssign, noop } from "../../utils/index.js";
13
+ import { noop } from "../../utils/index.js";
14
14
  import highEntropyUserAgentHints from "../../constants/highEntropyUserAgentClientHints.js";
15
15
  const browserSupportsUserAgentClientHints = navigator => {
16
16
  return "userAgentData" in navigator;
@@ -19,7 +19,7 @@ export default navigator => {
19
19
  if (!browserSupportsUserAgentClientHints(navigator)) {
20
20
  return noop;
21
21
  }
22
- return (xdm, logger) => {
22
+ return (event, logger) => {
23
23
  try {
24
24
  // eslint-disable-next-line compat/compat -- userAgentData support is checked before calling
25
25
  return navigator.userAgentData.getHighEntropyValues(highEntropyUserAgentHints.map(hint => hint[0])).then(hints => {
@@ -30,7 +30,7 @@ export default navigator => {
30
30
  userAgentClientHints[hintName] = hints[hintName];
31
31
  }
32
32
  });
33
- deepAssign(xdm, {
33
+ event.mergeXdm({
34
34
  environment: {
35
35
  browserDetails: {
36
36
  userAgentClientHints
@@ -0,0 +1,46 @@
1
+ /*
2
+ Copyright 2025 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+
13
+ export default window => {
14
+ let lastReferrerSent = null;
15
+ return event => {
16
+ const content = event.getContent();
17
+ const eventType = content.xdm?.eventType;
18
+ if (eventType === "decisioning.propositionFetch") {
19
+ return;
20
+ }
21
+
22
+ // Allow customers to explicitly set the referrer (for SPA view changes)
23
+ // Otherwise, use document.referrer
24
+ // eslint-disable-next-line no-underscore-dangle
25
+ const explicitReferrer = content.data?.__adobe?.analytics?.referrer;
26
+ const currentReferrer = explicitReferrer !== undefined ? explicitReferrer : window.document.referrer;
27
+ if (currentReferrer === lastReferrerSent) {
28
+ event.mergeData({
29
+ __adobe: {
30
+ analytics: {
31
+ referrer: ""
32
+ }
33
+ }
34
+ });
35
+ return;
36
+ }
37
+ event.mergeData({
38
+ __adobe: {
39
+ analytics: {
40
+ referrer: currentReferrer
41
+ }
42
+ }
43
+ });
44
+ lastReferrerSent = currentReferrer;
45
+ };
46
+ };
@@ -9,9 +9,9 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
9
9
  OF ANY KIND, either express or implied. See the License for the specific language
10
10
  governing permissions and limitations under the License.
11
11
  */
12
- import { deepAssign, toISOStringLocal, toInteger } from "../../utils/index.js";
12
+ import { toISOStringLocal, toInteger } from "../../utils/index.js";
13
13
  export default dateProvider => {
14
- return xdm => {
14
+ return event => {
15
15
  const date = dateProvider();
16
16
  const placeContext = {};
17
17
  const localTimezoneOffset = toInteger(date.getTimezoneOffset());
@@ -22,7 +22,7 @@ export default dateProvider => {
22
22
  if (localTimezoneOffset === undefined || Math.abs(localTimezoneOffset) < 6000) {
23
23
  placeContext.localTime = toISOStringLocal(date);
24
24
  }
25
- deepAssign(xdm, {
25
+ event.mergeXdm({
26
26
  placeContext
27
27
  });
28
28
  };
@@ -10,11 +10,10 @@ OF ANY KIND, either express or implied. See the License for the specific languag
10
10
  governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import { deepAssign } from "../../utils/index.js";
14
13
  export default dateProvider => {
15
- return xdm => {
14
+ return event => {
16
15
  const timestamp = dateProvider().toISOString();
17
- deepAssign(xdm, {
16
+ event.mergeXdm({
18
17
  timestamp
19
18
  });
20
19
  };
@@ -10,19 +10,17 @@ OF ANY KIND, either express or implied. See the License for the specific languag
10
10
  governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import { deepAssign } from "../../utils/index.js";
14
13
  export default window => {
15
- return xdm => {
16
- const web = {
17
- webPageDetails: {
18
- URL: window.location.href || window.location
19
- },
20
- webReferrer: {
21
- URL: window.document.referrer
14
+ return event => {
15
+ event.mergeXdm({
16
+ web: {
17
+ webPageDetails: {
18
+ URL: window.location.href || window.location
19
+ },
20
+ webReferrer: {
21
+ URL: window.document.referrer
22
+ }
22
23
  }
23
- };
24
- deepAssign(xdm, {
25
- web
26
24
  });
27
25
  };
28
26
  };
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 20219 Adobe. All rights reserved.
2
+ Copyright 2025 Adobe. All rights reserved.
3
3
  This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License. You may obtain a copy
5
5
  of the License at http://www.apache.org/licenses/LICENSE-2.0