@adobe/alloy 2.35.1-beta.0 → 2.35.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/alloy.js +193 -46
- package/dist/alloy.min.js +2 -2
- package/dist/types/core/src/components/BrandConcierge/createSendConversationEvent.d.ts +2 -1
- package/dist/types/core/src/components/BrandConcierge/index.d.ts +16 -1
- package/dist/types/core/src/constants/legacyCookies.d.ts +1 -0
- package/dist/types/core/src/core/createCookieTransfer.d.ts +1 -1
- package/package.json +2 -2
- package/src/components/Personalization/dom-actions/scripts.js +147 -23
package/dist/alloy.js
CHANGED
|
@@ -5828,6 +5828,8 @@
|
|
|
5828
5828
|
OF ANY KIND, either express or implied. See the License for the specific language
|
|
5829
5829
|
governing permissions and limitations under the License.
|
|
5830
5830
|
*/
|
|
5831
|
+
|
|
5832
|
+
|
|
5831
5833
|
const STATE_STORE_HANDLE_TYPE = "state:store";
|
|
5832
5834
|
|
|
5833
5835
|
var createCookieTransfer = ({
|
|
@@ -5842,7 +5844,7 @@
|
|
|
5842
5844
|
* access first-party cookies, therefore we transfer cookies into
|
|
5843
5845
|
* the request body so they can be read by the server.
|
|
5844
5846
|
*/
|
|
5845
|
-
cookiesToPayload(payload, endpointDomain) {
|
|
5847
|
+
cookiesToPayload(payload, endpointDomain, extraCookieNames = []) {
|
|
5846
5848
|
// localhost is a special case where the apexDomain is ""
|
|
5847
5849
|
// We want to treat localhost as a third-party domain.
|
|
5848
5850
|
const isEndpointFirstParty =
|
|
@@ -5855,20 +5857,22 @@
|
|
|
5855
5857
|
// If the endpoint is first-party, there's no need to transfer cookies
|
|
5856
5858
|
// to the payload since they'll be automatically passed through cookie
|
|
5857
5859
|
// headers.
|
|
5858
|
-
if (!isEndpointFirstParty) {
|
|
5860
|
+
if (!isEndpointFirstParty || isNonEmptyArray(extraCookieNames)) {
|
|
5859
5861
|
const cookies = cookieJar.getAll();
|
|
5860
|
-
|
|
5861
|
-
const
|
|
5862
|
-
.
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5862
|
+
const entriesByKey = new Map();
|
|
5863
|
+
const addEntry = (key) => {
|
|
5864
|
+
if (cookies[key] !== undefined && !entriesByKey.has(key)) {
|
|
5865
|
+
entriesByKey.set(key, { key, value: cookies[key] });
|
|
5866
|
+
}
|
|
5867
|
+
};
|
|
5868
|
+
if (!isEndpointFirstParty) {
|
|
5869
|
+
Object.keys(cookies).filter(shouldTransferCookie).forEach(addEntry);
|
|
5870
|
+
}
|
|
5871
|
+
if (isNonEmptyArray(extraCookieNames)) {
|
|
5872
|
+
extraCookieNames.forEach(addEntry);
|
|
5873
|
+
}
|
|
5874
|
+
if (entriesByKey.size) {
|
|
5875
|
+
state.entries = [...entriesByKey.values()];
|
|
5872
5876
|
}
|
|
5873
5877
|
}
|
|
5874
5878
|
|
|
@@ -5926,6 +5930,9 @@
|
|
|
5926
5930
|
const MBOX_EDGE_CLUSTER = "mboxEdgeCluster";
|
|
5927
5931
|
const AT_QA_MODE = "at_qa_mode";
|
|
5928
5932
|
const MBOX = "mbox";
|
|
5933
|
+
// The cookie that Marketo (Munchkin) JS sets. It must be forwarded so the
|
|
5934
|
+
// server can resolve the visitor's Marketo identity for Marketo integrations.
|
|
5935
|
+
const MUNCHKIN = "_mkto_trk";
|
|
5929
5936
|
|
|
5930
5937
|
/*
|
|
5931
5938
|
Copyright 2022 Adobe. All rights reserved.
|
|
@@ -5946,10 +5953,13 @@
|
|
|
5946
5953
|
// all cookies whose names are namespaced according to the
|
|
5947
5954
|
// logic in isNamespacedCookieName as well as any legacy
|
|
5948
5955
|
// cookie names (so that the server can handle migrating
|
|
5949
|
-
// identities on websites previously using Visitor.js)
|
|
5956
|
+
// identities on websites previously using Visitor.js). The
|
|
5957
|
+
// Marketo Munchkin cookie is always forwarded so the server
|
|
5958
|
+
// can resolve the visitor's Marketo identity.
|
|
5950
5959
|
return (
|
|
5951
5960
|
isNamespacedCookieName(orgId, name) ||
|
|
5952
5961
|
name === AT_QA_MODE ||
|
|
5962
|
+
name === MUNCHKIN ||
|
|
5953
5963
|
(targetMigrationEnabled && name === MBOX)
|
|
5954
5964
|
);
|
|
5955
5965
|
};
|
|
@@ -7746,10 +7756,10 @@
|
|
|
7746
7756
|
governing permissions and limitations under the License.
|
|
7747
7757
|
*/
|
|
7748
7758
|
|
|
7749
|
-
// The 2.35.1-beta.
|
|
7759
|
+
// The 2.35.1-beta.1 keyword will be replace at alloy build time with the package.json version.
|
|
7750
7760
|
// see babel-plugin-version
|
|
7751
7761
|
|
|
7752
|
-
var libraryVersion = "2.35.1-beta.
|
|
7762
|
+
var libraryVersion = "2.35.1-beta.1";
|
|
7753
7763
|
|
|
7754
7764
|
/*
|
|
7755
7765
|
Copyright 2019 Adobe. All rights reserved.
|
|
@@ -10216,8 +10226,8 @@
|
|
|
10216
10226
|
const ID = "id";
|
|
10217
10227
|
const IAM_EVENT_TYPE = "iam.eventType";
|
|
10218
10228
|
const EVENT_TYPE = "eventType";
|
|
10219
|
-
const TYPE = "type";
|
|
10220
|
-
const VALID_EVENT_TYPES = [IAM_EVENT_TYPE, EVENT_TYPE, TYPE];
|
|
10229
|
+
const TYPE$1 = "type";
|
|
10230
|
+
const VALID_EVENT_TYPES = [IAM_EVENT_TYPE, EVENT_TYPE, TYPE$1];
|
|
10221
10231
|
const VALID_EVENT_IDS = [IAM_ID, ID];
|
|
10222
10232
|
const checkForHistoricalMatcher = (eventCount, matcherKey, value) => {
|
|
10223
10233
|
switch (matcherKey) {
|
|
@@ -12898,6 +12908,7 @@
|
|
|
12898
12908
|
sendConversationServiceRequest,
|
|
12899
12909
|
buildEndpointUrl,
|
|
12900
12910
|
cookieTransfer,
|
|
12911
|
+
alwaysTransferCookies = [],
|
|
12901
12912
|
createResponse,
|
|
12902
12913
|
decodeKndctrCookie,
|
|
12903
12914
|
lifecycle,
|
|
@@ -12978,9 +12989,11 @@
|
|
|
12978
12989
|
}
|
|
12979
12990
|
|
|
12980
12991
|
payload.addEvent(event);
|
|
12981
|
-
|
|
12982
|
-
|
|
12983
|
-
|
|
12992
|
+
cookieTransfer.cookiesToPayload(
|
|
12993
|
+
payload,
|
|
12994
|
+
edgeDomain,
|
|
12995
|
+
alwaysTransferCookies,
|
|
12996
|
+
);
|
|
12984
12997
|
return sendConversationServiceRequest({
|
|
12985
12998
|
requestId: v4(),
|
|
12986
12999
|
url,
|
|
@@ -13151,10 +13164,14 @@
|
|
|
13151
13164
|
.default(STREAM_START_TIMEOUT_MS),
|
|
13152
13165
|
collectSources: boundBoolean().default(false),
|
|
13153
13166
|
region: boundString().matches(/^[a-z]{2,4}[0-9]{1,2}$/i),
|
|
13167
|
+
// Additional first-party cookie names to always transfer into the
|
|
13168
|
+
// request meta.state object (on top of the ones transferred by default).
|
|
13169
|
+
transferCookies: boundArrayOf(boundString()).default([]),
|
|
13154
13170
|
}).default({
|
|
13155
13171
|
stickyConversationSession: false,
|
|
13156
13172
|
streamTimeout: STREAM_START_TIMEOUT_MS,
|
|
13157
13173
|
collectSources: false,
|
|
13174
|
+
transferCookies: [],
|
|
13158
13175
|
}),
|
|
13159
13176
|
});
|
|
13160
13177
|
|
|
@@ -13182,6 +13199,8 @@
|
|
|
13182
13199
|
cookieTransfer,
|
|
13183
13200
|
createResponse,
|
|
13184
13201
|
platformServices,
|
|
13202
|
+
createSendConversationEvent:
|
|
13203
|
+
createSendConversationEventFactory = createSendConversationEvent,
|
|
13185
13204
|
}) => {
|
|
13186
13205
|
const session = {
|
|
13187
13206
|
id: getConciergeSessionCookie({ loggingCookieJar, config }),
|
|
@@ -13199,14 +13218,18 @@
|
|
|
13199
13218
|
cookieJar: loggingCookieJar,
|
|
13200
13219
|
logger,
|
|
13201
13220
|
});
|
|
13202
|
-
const sendConversationEvent =
|
|
13221
|
+
const sendConversationEvent = createSendConversationEventFactory({
|
|
13222
|
+
loggingCookieJar,
|
|
13203
13223
|
logger,
|
|
13204
13224
|
eventManager,
|
|
13205
13225
|
consent,
|
|
13226
|
+
instanceName,
|
|
13227
|
+
sendEdgeNetworkRequest,
|
|
13206
13228
|
config,
|
|
13207
13229
|
buildEndpointUrl,
|
|
13208
13230
|
lifecycle,
|
|
13209
13231
|
cookieTransfer,
|
|
13232
|
+
alwaysTransferCookies: config.conversation.transferCookies || [],
|
|
13210
13233
|
createResponse,
|
|
13211
13234
|
sendConversationServiceRequest,
|
|
13212
13235
|
decodeKndctrCookie,
|
|
@@ -17229,6 +17252,55 @@
|
|
|
17229
17252
|
governing permissions and limitations under the License.
|
|
17230
17253
|
*/
|
|
17231
17254
|
|
|
17255
|
+
const TYPE = "type";
|
|
17256
|
+
const MODULE = "module";
|
|
17257
|
+
const NONCE = "nonce";
|
|
17258
|
+
const NOMODULE = "nomodule";
|
|
17259
|
+
|
|
17260
|
+
// Per the HTML spec, a <script> only ever executes if its type is absent/
|
|
17261
|
+
// empty, "module", or one of these recognized JavaScript MIME type essences
|
|
17262
|
+
// (https://mimesniff.spec.whatwg.org/#javascript-mime-type). Any other type
|
|
17263
|
+
// (e.g. "importmap", "application/json", a templating library's custom type)
|
|
17264
|
+
// makes the element a data block: the browser never executes it, regardless
|
|
17265
|
+
// of whether it's parsed from HTML, inserted via innerHTML, or appended with
|
|
17266
|
+
// appendChild. Such elements are left untouched by this module — extracting
|
|
17267
|
+
// and re-inserting them would be pointless at best, and at worst (if `type`
|
|
17268
|
+
// were dropped along the way) would turn inert data into code that runs.
|
|
17269
|
+
const JAVASCRIPT_MIME_TYPES = new Set([
|
|
17270
|
+
"application/ecmascript",
|
|
17271
|
+
"application/javascript",
|
|
17272
|
+
"application/x-ecmascript",
|
|
17273
|
+
"application/x-javascript",
|
|
17274
|
+
"text/ecmascript",
|
|
17275
|
+
"text/javascript",
|
|
17276
|
+
"text/javascript1.0",
|
|
17277
|
+
"text/javascript1.1",
|
|
17278
|
+
"text/javascript1.2",
|
|
17279
|
+
"text/javascript1.3",
|
|
17280
|
+
"text/javascript1.4",
|
|
17281
|
+
"text/javascript1.5",
|
|
17282
|
+
"text/jscript",
|
|
17283
|
+
"text/livescript",
|
|
17284
|
+
"text/x-ecmascript",
|
|
17285
|
+
"text/x-javascript",
|
|
17286
|
+
]);
|
|
17287
|
+
|
|
17288
|
+
// Attributes that affect how the script executes/fetches (as opposed to
|
|
17289
|
+
// identity/presentation attributes like id, class, and data-*, which are
|
|
17290
|
+
// intentionally not copied — see loadScript below). `src` is handled
|
|
17291
|
+
// separately since it needs different treatment for inline vs. remote
|
|
17292
|
+
// scripts, and `nonce` is copied here as a fallback but then overridden
|
|
17293
|
+
// below with the page's current CSP nonce when one is found.
|
|
17294
|
+
const COPIED_ATTRIBUTES = [
|
|
17295
|
+
TYPE,
|
|
17296
|
+
NONCE,
|
|
17297
|
+
"crossorigin",
|
|
17298
|
+
"integrity",
|
|
17299
|
+
"referrerpolicy",
|
|
17300
|
+
"fetchpriority",
|
|
17301
|
+
"nomodule",
|
|
17302
|
+
];
|
|
17303
|
+
|
|
17232
17304
|
const getPromise = (url, script) => {
|
|
17233
17305
|
return new Promise((resolve, reject) => {
|
|
17234
17306
|
script.onload = () => {
|
|
@@ -17239,24 +17311,45 @@
|
|
|
17239
17311
|
};
|
|
17240
17312
|
});
|
|
17241
17313
|
};
|
|
17314
|
+
|
|
17315
|
+
// Re-creates a script in <head> so the browser executes it (scripts inserted via
|
|
17316
|
+
// innerHTML never run). Handles both remote scripts (with a src) and inline
|
|
17317
|
+
// module scripts: an inline `type="module"` executes asynchronously and belongs
|
|
17318
|
+
// with the head-loaded scripts rather than the synchronously-run inline path.
|
|
17242
17319
|
const loadScript = (source) => {
|
|
17243
17320
|
const url = getAttribute(source, SRC);
|
|
17244
17321
|
const script = document.createElement("script");
|
|
17245
|
-
//
|
|
17246
|
-
//
|
|
17247
|
-
|
|
17248
|
-
|
|
17249
|
-
|
|
17250
|
-
|
|
17251
|
-
|
|
17252
|
-
|
|
17322
|
+
// Only carry the attributes required to execute the script correctly:
|
|
17323
|
+
// `src` (below) and COPIED_ATTRIBUTES. Author attributes such as `id`,
|
|
17324
|
+
// `class`, and `data-*` are intentionally NOT copied: the original offer
|
|
17325
|
+
// <script> is left in the page (inert), so copying its id/class onto this
|
|
17326
|
+
// executed element would create duplicate matches for
|
|
17327
|
+
// document.getElementById / querySelector.
|
|
17328
|
+
COPIED_ATTRIBUTES.forEach((name) => {
|
|
17329
|
+
const value = getAttribute(source, name);
|
|
17330
|
+
if (value !== null) {
|
|
17331
|
+
script.setAttribute(name, value);
|
|
17332
|
+
}
|
|
17333
|
+
});
|
|
17334
|
+
// The page's current CSP nonce takes priority over whatever nonce (if any)
|
|
17335
|
+
// was written into the source markup, since that's the one the browser
|
|
17336
|
+
// will actually check against the CSP header for this page load.
|
|
17253
17337
|
const nonce = getNonce();
|
|
17254
17338
|
if (nonce) {
|
|
17255
|
-
script.setAttribute(
|
|
17339
|
+
script.setAttribute(NONCE, nonce);
|
|
17256
17340
|
}
|
|
17341
|
+
|
|
17342
|
+
if (!url) {
|
|
17343
|
+
// Inline module script: carry the code across and let it execute in <head>.
|
|
17344
|
+
// Inline scripts emit no load event, so completion cannot be tracked; we
|
|
17345
|
+
// resolve immediately and rely on the browser's deferred module execution.
|
|
17346
|
+
script.textContent = source.textContent;
|
|
17347
|
+
document.head.appendChild(script);
|
|
17348
|
+
return Promise.resolve(script);
|
|
17349
|
+
}
|
|
17350
|
+
|
|
17351
|
+
script.src = url;
|
|
17257
17352
|
script.async = true;
|
|
17258
|
-
// Assign load handlers after copying attributes so a copied inline
|
|
17259
|
-
// onload/onerror attribute can't break load-completion tracking.
|
|
17260
17353
|
const promise = getPromise(url, script);
|
|
17261
17354
|
document.head.appendChild(script);
|
|
17262
17355
|
return promise;
|
|
@@ -17265,11 +17358,59 @@
|
|
|
17265
17358
|
const is = (element, tagName) =>
|
|
17266
17359
|
!!element && element.tagName === tagName;
|
|
17267
17360
|
|
|
17268
|
-
|
|
17269
|
-
|
|
17361
|
+
// Normalizes away casing/whitespace/parameters (e.g. "TEXT/JAVASCRIPT ;
|
|
17362
|
+
// charset=utf-8") so it can be compared against MODULE/JAVASCRIPT_MIME_TYPES.
|
|
17363
|
+
const getNormalizedType = (element) => {
|
|
17364
|
+
const type = getAttribute(element, TYPE);
|
|
17365
|
+
return type ? type.split(";")[0].trim().toLowerCase() : "";
|
|
17366
|
+
};
|
|
17367
|
+
|
|
17368
|
+
const isModule = (element) => getNormalizedType(element) === MODULE;
|
|
17369
|
+
|
|
17370
|
+
// An empty src (`<script src="">`) is treated as "no src" — it points nowhere,
|
|
17371
|
+
// so the script is handled on the inline path rather than fetched.
|
|
17372
|
+
const hasSrc = (element) => !!getAttribute(element, SRC);
|
|
17270
17373
|
|
|
17271
|
-
|
|
17272
|
-
|
|
17374
|
+
// A <script> the browser would actually execute: a classic script (type is
|
|
17375
|
+
// absent/empty or a recognized JavaScript MIME type) or an ES module. Any other
|
|
17376
|
+
// type is a data block (e.g. "importmap", "application/json", a templating
|
|
17377
|
+
// library's custom type) that never runs — see JAVASCRIPT_MIME_TYPES above.
|
|
17378
|
+
// Only executable scripts are extracted and re-inserted; the rest are left
|
|
17379
|
+
// untouched, since forcing them to run was never the intent.
|
|
17380
|
+
const isExecutableScript = (element) => {
|
|
17381
|
+
if (!is(element, SCRIPT)) {
|
|
17382
|
+
return false;
|
|
17383
|
+
}
|
|
17384
|
+
const type = getNormalizedType(element);
|
|
17385
|
+
return type === "" || type === MODULE || JAVASCRIPT_MIME_TYPES.has(type);
|
|
17386
|
+
};
|
|
17387
|
+
|
|
17388
|
+
// How a given <script> must be re-created for the browser to run it:
|
|
17389
|
+
// HEAD_SCRIPT – re-created in <head>: any remote script (with a src), plus
|
|
17390
|
+
// inline ES modules. An inline `type="module"` executes
|
|
17391
|
+
// asynchronously, so it belongs with the head scripts rather
|
|
17392
|
+
// than the synchronous inline path.
|
|
17393
|
+
// INLINE_SCRIPT – classic inline script: re-created and run synchronously in
|
|
17394
|
+
// the offer container.
|
|
17395
|
+
const HEAD_SCRIPT = "head";
|
|
17396
|
+
const INLINE_SCRIPT = "inline";
|
|
17397
|
+
|
|
17398
|
+
// Classifies a <script>, or returns null when there's nothing to run: either a
|
|
17399
|
+
// data block the browser would never execute (left untouched), or an inline
|
|
17400
|
+
// script with no code. `src`-less inline scripts need code to be worth running;
|
|
17401
|
+
// a remote script's code lives at its `src`, so it always qualifies.
|
|
17402
|
+
const classifyScript = (element) => {
|
|
17403
|
+
if (!isExecutableScript(element)) {
|
|
17404
|
+
return null;
|
|
17405
|
+
}
|
|
17406
|
+
if (hasSrc(element)) {
|
|
17407
|
+
return HEAD_SCRIPT;
|
|
17408
|
+
}
|
|
17409
|
+
if (!element.textContent) {
|
|
17410
|
+
return null;
|
|
17411
|
+
}
|
|
17412
|
+
return isModule(element) ? HEAD_SCRIPT : INLINE_SCRIPT;
|
|
17413
|
+
};
|
|
17273
17414
|
|
|
17274
17415
|
const getInlineScripts = (fragment) => {
|
|
17275
17416
|
const scripts = selectNodes(SCRIPT, fragment);
|
|
@@ -17283,17 +17424,24 @@
|
|
|
17283
17424
|
for (let i = 0; i < length; i += 1) {
|
|
17284
17425
|
const element = scripts[i];
|
|
17285
17426
|
|
|
17286
|
-
if (
|
|
17427
|
+
if (classifyScript(element) !== INLINE_SCRIPT) {
|
|
17287
17428
|
continue;
|
|
17288
17429
|
}
|
|
17289
17430
|
|
|
17290
17431
|
const { textContent } = element;
|
|
17291
17432
|
|
|
17292
|
-
|
|
17293
|
-
|
|
17294
|
-
|
|
17295
|
-
|
|
17296
|
-
|
|
17433
|
+
// `nomodule` is preserved even though this element is force-executed via
|
|
17434
|
+
// appendChild: without it, a classic script the author intended as a
|
|
17435
|
+
// legacy fallback (skipped in module-supporting browsers) would run
|
|
17436
|
+
// where it otherwise wouldn't have.
|
|
17437
|
+
const nomodule = getAttribute(element, NOMODULE);
|
|
17438
|
+
result.push(
|
|
17439
|
+
createNode(
|
|
17440
|
+
SCRIPT,
|
|
17441
|
+
{ ...attributes, ...(nomodule !== null && { nomodule }) },
|
|
17442
|
+
{ textContent },
|
|
17443
|
+
),
|
|
17444
|
+
);
|
|
17297
17445
|
}
|
|
17298
17446
|
|
|
17299
17447
|
return result;
|
|
@@ -17307,8 +17455,7 @@
|
|
|
17307
17455
|
for (let i = 0; i < length; i += 1) {
|
|
17308
17456
|
const element = scripts[i];
|
|
17309
17457
|
|
|
17310
|
-
|
|
17311
|
-
if (!isRemoteScript(element)) {
|
|
17458
|
+
if (classifyScript(element) !== HEAD_SCRIPT) {
|
|
17312
17459
|
continue;
|
|
17313
17460
|
}
|
|
17314
17461
|
|