@sitecore-content-sdk/analytics-core 2.0.0-canary.12
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/LICENSE.txt +202 -0
- package/README.md +99 -0
- package/dist/cjs/package.json +78 -0
- package/dist/cjs/src/client-id/fetch-client-id-from-edge-proxy.js +41 -0
- package/dist/cjs/src/client-id/get-client-id.js +12 -0
- package/dist/cjs/src/client-id/resolve-get-client-id-url.js +13 -0
- package/dist/cjs/src/consts.js +42 -0
- package/dist/cjs/src/cookie/get-default-cookie-attributes.js +20 -0
- package/dist/cjs/src/correlation-id/generate-correlation-id.js +12 -0
- package/dist/cjs/src/index.js +11 -0
- package/dist/cjs/src/infer/infer.js +28 -0
- package/dist/cjs/src/initialization/browser-adapter.js +42 -0
- package/dist/cjs/src/initialization/const.js +8 -0
- package/dist/cjs/src/initialization/plugin.js +75 -0
- package/dist/cjs/src/initialization/server-adapter.js +91 -0
- package/dist/cjs/src/initialization/types.js +2 -0
- package/dist/cjs/src/interfaces.js +2 -0
- package/dist/cjs/src/internal.js +24 -0
- package/dist/cjs/src/utils/browser/appendScriptWithAttributes.js +15 -0
- package/dist/cjs/src/utils/converters/base-64-converter.js +18 -0
- package/dist/cjs/src/utils/converters/flatten-object.js +35 -0
- package/dist/cjs/src/utils/cookies/consts.js +4 -0
- package/dist/cjs/src/utils/cookies/cookie-exists-in-server-side.js +14 -0
- package/dist/cjs/src/utils/cookies/cookie-exists.js +13 -0
- package/dist/cjs/src/utils/cookies/create-cookie-string.js +20 -0
- package/dist/cjs/src/utils/cookies/delete-cookie.js +11 -0
- package/dist/cjs/src/utils/cookies/get-cookie-server-side.js +14 -0
- package/dist/cjs/src/utils/cookies/get-cookie-value-client-side.js +15 -0
- package/dist/cjs/src/utils/cookies/get-cookie.js +20 -0
- package/dist/cjs/src/utils/cookies/interfaces.js +2 -0
- package/dist/cjs/src/utils/generators/generate-v4-uuid.js +11 -0
- package/dist/cjs/src/utils/interfaces.js +2 -0
- package/dist/cjs/src/utils/validators/is-short-iso-date-string.js +20 -0
- package/dist/cjs/src/utils/validators/is-valid-email.js +16 -0
- package/dist/cjs/src/utils.js +23 -0
- package/dist/esm/package.json +78 -0
- package/dist/esm/src/client-id/fetch-client-id-from-edge-proxy.js +38 -0
- package/dist/esm/src/client-id/get-client-id.js +9 -0
- package/dist/esm/src/client-id/resolve-get-client-id-url.js +10 -0
- package/dist/esm/src/consts.js +36 -0
- package/dist/esm/src/cookie/get-default-cookie-attributes.js +17 -0
- package/dist/esm/src/correlation-id/generate-correlation-id.js +9 -0
- package/dist/esm/src/index.js +4 -0
- package/dist/esm/src/infer/infer.js +24 -0
- package/dist/esm/src/initialization/browser-adapter.js +39 -0
- package/dist/esm/src/initialization/const.js +5 -0
- package/dist/esm/src/initialization/plugin.js +71 -0
- package/dist/esm/src/initialization/server-adapter.js +88 -0
- package/dist/esm/src/initialization/types.js +1 -0
- package/dist/esm/src/interfaces.js +1 -0
- package/dist/esm/src/internal.js +7 -0
- package/dist/esm/src/utils/browser/appendScriptWithAttributes.js +12 -0
- package/dist/esm/src/utils/converters/base-64-converter.js +15 -0
- package/dist/esm/src/utils/converters/flatten-object.js +32 -0
- package/dist/esm/src/utils/cookies/consts.js +1 -0
- package/dist/esm/src/utils/cookies/cookie-exists-in-server-side.js +11 -0
- package/dist/esm/src/utils/cookies/cookie-exists.js +10 -0
- package/dist/esm/src/utils/cookies/create-cookie-string.js +17 -0
- package/dist/esm/src/utils/cookies/delete-cookie.js +8 -0
- package/dist/esm/src/utils/cookies/get-cookie-server-side.js +11 -0
- package/dist/esm/src/utils/cookies/get-cookie-value-client-side.js +12 -0
- package/dist/esm/src/utils/cookies/get-cookie.js +17 -0
- package/dist/esm/src/utils/cookies/interfaces.js +1 -0
- package/dist/esm/src/utils/generators/generate-v4-uuid.js +8 -0
- package/dist/esm/src/utils/interfaces.js +1 -0
- package/dist/esm/src/utils/validators/is-short-iso-date-string.js +17 -0
- package/dist/esm/src/utils/validators/is-valid-email.js +13 -0
- package/dist/esm/src/utils.js +10 -0
- package/internal.d.ts +2 -0
- package/package.json +78 -0
- package/types/src/client-id/fetch-client-id-from-edge-proxy.d.ts +11 -0
- package/types/src/client-id/fetch-client-id-from-edge-proxy.d.ts.map +1 -0
- package/types/src/client-id/get-client-id.d.ts +7 -0
- package/types/src/client-id/get-client-id.d.ts.map +1 -0
- package/types/src/client-id/resolve-get-client-id-url.d.ts +8 -0
- package/types/src/client-id/resolve-get-client-id-url.d.ts.map +1 -0
- package/types/src/consts.d.ts +36 -0
- package/types/src/consts.d.ts.map +1 -0
- package/types/src/cookie/get-default-cookie-attributes.d.ts +10 -0
- package/types/src/cookie/get-default-cookie-attributes.d.ts.map +1 -0
- package/types/src/correlation-id/generate-correlation-id.d.ts +7 -0
- package/types/src/correlation-id/generate-correlation-id.d.ts.map +1 -0
- package/types/src/index.d.ts +9 -0
- package/types/src/index.d.ts.map +1 -0
- package/types/src/infer/infer.d.ts +15 -0
- package/types/src/infer/infer.d.ts.map +1 -0
- package/types/src/initialization/browser-adapter.d.ts +20 -0
- package/types/src/initialization/browser-adapter.d.ts.map +1 -0
- package/types/src/initialization/const.d.ts +6 -0
- package/types/src/initialization/const.d.ts.map +1 -0
- package/types/src/initialization/plugin.d.ts +65 -0
- package/types/src/initialization/plugin.d.ts.map +1 -0
- package/types/src/initialization/server-adapter.d.ts +25 -0
- package/types/src/initialization/server-adapter.d.ts.map +1 -0
- package/types/src/initialization/types.d.ts +92 -0
- package/types/src/initialization/types.d.ts.map +1 -0
- package/types/src/interfaces.d.ts +34 -0
- package/types/src/interfaces.d.ts.map +1 -0
- package/types/src/internal.d.ts +12 -0
- package/types/src/internal.d.ts.map +1 -0
- package/types/src/utils/browser/appendScriptWithAttributes.d.ts +21 -0
- package/types/src/utils/browser/appendScriptWithAttributes.d.ts.map +1 -0
- package/types/src/utils/converters/base-64-converter.d.ts +10 -0
- package/types/src/utils/converters/base-64-converter.d.ts.map +1 -0
- package/types/src/utils/converters/flatten-object.d.ts +41 -0
- package/types/src/utils/converters/flatten-object.d.ts.map +1 -0
- package/types/src/utils/cookies/consts.d.ts +2 -0
- package/types/src/utils/cookies/consts.d.ts.map +1 -0
- package/types/src/utils/cookies/cookie-exists-in-server-side.d.ts +9 -0
- package/types/src/utils/cookies/cookie-exists-in-server-side.d.ts.map +1 -0
- package/types/src/utils/cookies/cookie-exists.d.ts +9 -0
- package/types/src/utils/cookies/cookie-exists.d.ts.map +1 -0
- package/types/src/utils/cookies/create-cookie-string.d.ts +11 -0
- package/types/src/utils/cookies/create-cookie-string.d.ts.map +1 -0
- package/types/src/utils/cookies/delete-cookie.d.ts +7 -0
- package/types/src/utils/cookies/delete-cookie.d.ts.map +1 -0
- package/types/src/utils/cookies/get-cookie-server-side.d.ts +12 -0
- package/types/src/utils/cookies/get-cookie-server-side.d.ts.map +1 -0
- package/types/src/utils/cookies/get-cookie-value-client-side.d.ts +8 -0
- package/types/src/utils/cookies/get-cookie-value-client-side.d.ts.map +1 -0
- package/types/src/utils/cookies/get-cookie.d.ts +12 -0
- package/types/src/utils/cookies/get-cookie.d.ts.map +1 -0
- package/types/src/utils/cookies/interfaces.d.ts +35 -0
- package/types/src/utils/cookies/interfaces.d.ts.map +1 -0
- package/types/src/utils/generators/generate-v4-uuid.d.ts +7 -0
- package/types/src/utils/generators/generate-v4-uuid.d.ts.map +1 -0
- package/types/src/utils/interfaces.d.ts +8 -0
- package/types/src/utils/interfaces.d.ts.map +1 -0
- package/types/src/utils/validators/is-short-iso-date-string.d.ts +8 -0
- package/types/src/utils/validators/is-short-iso-date-string.d.ts.map +1 -0
- package/types/src/utils/validators/is-valid-email.d.ts +8 -0
- package/types/src/utils/validators/is-valid-email.d.ts.map +1 -0
- package/types/src/utils.d.ts +14 -0
- package/types/src/utils.d.ts.map +1 -0
- package/utils.d.ts +1 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import packageJson from '../package.json';
|
|
2
|
+
/**
|
|
3
|
+
* The package version.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export const LIBRARY_VERSION = packageJson.version;
|
|
7
|
+
/**
|
|
8
|
+
* The prefix for cookie names used by the analytics library.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export const COOKIE_NAME_PREFIX = 'sc_';
|
|
12
|
+
/**
|
|
13
|
+
* The name of the client ID cookie.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export const CLIENT_ID_COOKIE_NAME = 'cid';
|
|
17
|
+
/**
|
|
18
|
+
* The default number of days until the client ID cookie expires.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_COOKIE_EXPIRY_DAYS = 730;
|
|
22
|
+
/**
|
|
23
|
+
* The seconds in a day, used for cookie expiration calculations.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export const DAILY_SECONDS = 86400;
|
|
27
|
+
/**
|
|
28
|
+
* The api version of the Edge Proxy.
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export const API_VERSION = 'v1.2';
|
|
32
|
+
/**
|
|
33
|
+
* The header name for the correlation ID used in analytics requests.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export const CORRELATION_ID_HEADER = 'x-sc-correlation-id';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DAILY_SECONDS, DEFAULT_COOKIE_EXPIRY_DAYS } from '../consts';
|
|
2
|
+
/**
|
|
3
|
+
* Gets the default cookie attributes.
|
|
4
|
+
* @param {number} [maxAge] - Sets the cookie "Max-Age" attribute in days.
|
|
5
|
+
* @param {string} [cookieDomain] - Optional domain for the cookie.
|
|
6
|
+
* @returns {CookieProperties} The default configuration settings for the cookie string.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export function getDefaultCookieAttributes(maxAge = DEFAULT_COOKIE_EXPIRY_DAYS, cookieDomain) {
|
|
10
|
+
return {
|
|
11
|
+
domain: cookieDomain,
|
|
12
|
+
maxAge: maxAge * DAILY_SECONDS,
|
|
13
|
+
path: '/',
|
|
14
|
+
sameSite: 'None',
|
|
15
|
+
secure: true,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the uppercase language code of the current web page's root HTML element, using the `lang` attribute.
|
|
3
|
+
* If unavailable or invalid, undefined is returned.
|
|
4
|
+
* @returns The language attribute or undefined.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export function language() {
|
|
8
|
+
return typeof window === 'undefined' || window.document.documentElement.lang.length <= 1
|
|
9
|
+
? undefined
|
|
10
|
+
: new Intl.Locale(window.document.documentElement.lang).language.toLocaleUpperCase();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Returns the name of the current page extracted from the URL's pathname.
|
|
14
|
+
* If it's the home page, it returns `Home Page`.
|
|
15
|
+
* @returns `Home Page` if root, otherwise the pathname segment.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export function pageName() {
|
|
19
|
+
if (typeof window === 'undefined')
|
|
20
|
+
return '';
|
|
21
|
+
return window.location.pathname === '/'
|
|
22
|
+
? 'Home Page'
|
|
23
|
+
: window.location.pathname.split('/').pop();
|
|
24
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { COOKIE_NAME_PREFIX, fetchClientIdFromEdgeProxy, getDefaultCookieAttributes, } from '../internal';
|
|
2
|
+
import { createCookieString, getCookieValueClientSide } from '../utils';
|
|
3
|
+
import { deleteCookie } from '../utils/cookies/delete-cookie';
|
|
4
|
+
import { getAnalyticsPlugin } from './plugin';
|
|
5
|
+
import { getCoreContext } from '@sitecore-content-sdk/core';
|
|
6
|
+
/**
|
|
7
|
+
* Creates a browser-based analytics adapter that reads and writes the visitor ID
|
|
8
|
+
* using cookies and can resolve a new client ID from the Edge proxy when needed.
|
|
9
|
+
* The adapter also provides access to the current URL search parameters.
|
|
10
|
+
* @returns {AnalyticsBrowserAdapter} The analytics browser adapter.
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export function analyticsBrowserAdapter() {
|
|
14
|
+
return {
|
|
15
|
+
type: 'browser',
|
|
16
|
+
getClientId: () => {
|
|
17
|
+
return getCookieValueClientSide(getAnalyticsPlugin().options.cookies.name);
|
|
18
|
+
},
|
|
19
|
+
setClientId: async () => {
|
|
20
|
+
const coreConfig = getCoreContext().config;
|
|
21
|
+
const analyticsOptions = getAnalyticsPlugin().options;
|
|
22
|
+
const cookieAttributes = getDefaultCookieAttributes(analyticsOptions.cookies.expiryDays, analyticsOptions.cookies.domain);
|
|
23
|
+
const legacyCookie = getCookieValueClientSide(`${COOKIE_NAME_PREFIX}${coreConfig.contextId}`);
|
|
24
|
+
if (legacyCookie) {
|
|
25
|
+
document.cookie = createCookieString(analyticsOptions.cookies.name, legacyCookie, cookieAttributes);
|
|
26
|
+
deleteCookie(`${COOKIE_NAME_PREFIX}${coreConfig.contextId}`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const cookieValues = await fetchClientIdFromEdgeProxy(coreConfig.edgeUrl, coreConfig.contextId, analyticsOptions.timeout);
|
|
30
|
+
analyticsOptions.visitorIds = cookieValues;
|
|
31
|
+
document.cookie = createCookieString(analyticsOptions.cookies.name, cookieValues.clientId, cookieAttributes);
|
|
32
|
+
},
|
|
33
|
+
location: {
|
|
34
|
+
getSearchParams: () => {
|
|
35
|
+
return window.location.search;
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { CLIENT_ID_COOKIE_NAME, COOKIE_NAME_PREFIX, DEFAULT_COOKIE_EXPIRY_DAYS, LIBRARY_VERSION, } from '../consts';
|
|
2
|
+
import { ANALYTICS_PLUGIN_NAME } from './const';
|
|
3
|
+
import { getCoreContext, debug, constants } from '@sitecore-content-sdk/core';
|
|
4
|
+
import { getClientId } from '../client-id/get-client-id';
|
|
5
|
+
const debugInit = debug.init;
|
|
6
|
+
const { ERROR_MESSAGES } = constants;
|
|
7
|
+
/**
|
|
8
|
+
* Creates an analytics plugin with the provided options.
|
|
9
|
+
* @param {AnalyticsPluginParams} params - The parameters for the analytics plugin.
|
|
10
|
+
* @returns {AnalyticsPlugin} The analytics plugin instance.
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export function analyticsPlugin(params) {
|
|
14
|
+
var _a;
|
|
15
|
+
const { options, adapter } = params;
|
|
16
|
+
const resolvedOptions = {
|
|
17
|
+
cookies: {
|
|
18
|
+
domain: options === null || options === void 0 ? void 0 : options.cookieDomain,
|
|
19
|
+
enabled: (_a = options === null || options === void 0 ? void 0 : options.enableCookie) !== null && _a !== void 0 ? _a : false,
|
|
20
|
+
expiryDays: (options === null || options === void 0 ? void 0 : options.cookieExpiryDays) || DEFAULT_COOKIE_EXPIRY_DAYS,
|
|
21
|
+
name: `${COOKIE_NAME_PREFIX}${CLIENT_ID_COOKIE_NAME}`,
|
|
22
|
+
path: (options === null || options === void 0 ? void 0 : options.cookiePath) || '/',
|
|
23
|
+
},
|
|
24
|
+
timeout: options === null || options === void 0 ? void 0 : options.timeout,
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
name: ANALYTICS_PLUGIN_NAME,
|
|
28
|
+
init,
|
|
29
|
+
options: resolvedOptions,
|
|
30
|
+
adapter,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Initializes the analytics plugin with the provided options.
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
async function init() {
|
|
38
|
+
debugInit(`Initializing ${ANALYTICS_PLUGIN_NAME}`);
|
|
39
|
+
const coreContext = getCoreContext();
|
|
40
|
+
const analyticsPlugin = getAnalyticsPlugin();
|
|
41
|
+
if (!analyticsPlugin.options.cookies.enabled) {
|
|
42
|
+
debugInit(`Cookies are disabled for ${ANALYTICS_PLUGIN_NAME}. If this was not intentional, set "enableCookie" to "true".`);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const adapter = analyticsPlugin.adapter;
|
|
46
|
+
if (!adapter.getClientId() || analyticsPlugin.adapter.type !== 'browser') {
|
|
47
|
+
await adapter.setClientId();
|
|
48
|
+
debugInit(`Cookie set for ${ANALYTICS_PLUGIN_NAME}`);
|
|
49
|
+
}
|
|
50
|
+
if (analyticsPlugin.adapter.type === 'browser')
|
|
51
|
+
window.scContentSDK = Object.assign(Object.assign({}, window.scContentSDK), { analytics_core: {
|
|
52
|
+
getClientId,
|
|
53
|
+
options: {
|
|
54
|
+
siteName: coreContext.config.siteName,
|
|
55
|
+
contextId: coreContext.config.contextId,
|
|
56
|
+
edgeUrl: coreContext.config.edgeUrl,
|
|
57
|
+
},
|
|
58
|
+
version: LIBRARY_VERSION,
|
|
59
|
+
} });
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Retrieves the analytics plugin instance from the core context.
|
|
63
|
+
* @returns {AnalyticsPlugin} The analytics plugin instance.
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
export function getAnalyticsPlugin() {
|
|
67
|
+
const plugin = getCoreContext().plugins.get(ANALYTICS_PLUGIN_NAME);
|
|
68
|
+
if (!plugin)
|
|
69
|
+
throw new Error(ERROR_MESSAGES.IE_004(ANALYTICS_PLUGIN_NAME));
|
|
70
|
+
return plugin;
|
|
71
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { COOKIE_NAME_PREFIX, fetchClientIdFromEdgeProxy, getDefaultCookieAttributes, } from '../internal';
|
|
2
|
+
import { createCookieString, getCookieServerSide } from '../utils';
|
|
3
|
+
import { getAnalyticsPlugin } from './plugin';
|
|
4
|
+
import { getCoreContext } from '@sitecore-content-sdk/core';
|
|
5
|
+
/**
|
|
6
|
+
* Creates a server-based analytics adapter that reads and writes the visitor ID
|
|
7
|
+
* using cookies and can resolve a new client ID from the Edge proxy when needed.
|
|
8
|
+
* The adapter also provides access to the current URL search parameters.
|
|
9
|
+
* @template Request - The HTTP request type extending `IncomingMessage`.
|
|
10
|
+
* @template Response - The HTTP response type extending `OutgoingMessage`.
|
|
11
|
+
* @param {Request} request - The HTTP request object.
|
|
12
|
+
* @param {Response} response - The HTTP response object.
|
|
13
|
+
* @returns {AnalyticsServerAdapter} The analytics server adapter.
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
export function analyticsServerAdapter(request, response) {
|
|
17
|
+
return {
|
|
18
|
+
type: 'server',
|
|
19
|
+
getClientId: () => {
|
|
20
|
+
return getClientId(request);
|
|
21
|
+
},
|
|
22
|
+
setClientId: async () => {
|
|
23
|
+
var _a;
|
|
24
|
+
const coreConfig = getCoreContext().config;
|
|
25
|
+
const analyticsOptions = getAnalyticsPlugin().options;
|
|
26
|
+
const cookieOptions = analyticsOptions.cookies;
|
|
27
|
+
const clientIdName = cookieOptions.name;
|
|
28
|
+
const legacyClientIdName = `${COOKIE_NAME_PREFIX}${coreConfig.contextId}`;
|
|
29
|
+
const defaultCookieAttributes = getDefaultCookieAttributes(cookieOptions.expiryDays, cookieOptions.domain);
|
|
30
|
+
const legacyClientIdCookie = getCookieServerSide(request.headers.cookie, legacyClientIdName);
|
|
31
|
+
if (legacyClientIdCookie) {
|
|
32
|
+
request.headers.cookie = (_a = request.headers.cookie) === null || _a === void 0 ? void 0 : _a.replace(legacyClientIdCookie.name, clientIdName);
|
|
33
|
+
response.setHeader('Set-Cookie', [
|
|
34
|
+
createCookieString(clientIdName, legacyClientIdCookie.value, defaultCookieAttributes),
|
|
35
|
+
createCookieString(legacyClientIdName, '', Object.assign(Object.assign({}, defaultCookieAttributes), { maxAge: 0 })),
|
|
36
|
+
]);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const clientIdCookie = getClientId(request);
|
|
40
|
+
let clientIdCookieValue;
|
|
41
|
+
if (!clientIdCookie) {
|
|
42
|
+
const cookieValues = await fetchClientIdFromEdgeProxy(coreConfig.edgeUrl, coreConfig.contextId, analyticsOptions.timeout);
|
|
43
|
+
clientIdCookieValue = cookieValues.clientId;
|
|
44
|
+
analyticsOptions.visitorIds = cookieValues;
|
|
45
|
+
}
|
|
46
|
+
else
|
|
47
|
+
clientIdCookieValue = clientIdCookie;
|
|
48
|
+
const clientIdCookieString = createCookieString(clientIdName, clientIdCookieValue, defaultCookieAttributes);
|
|
49
|
+
if (!clientIdCookie) {
|
|
50
|
+
request.headers.cookie = request.headers.cookie
|
|
51
|
+
? request.headers.cookie + '; ' + clientIdCookieString
|
|
52
|
+
: clientIdCookieString;
|
|
53
|
+
}
|
|
54
|
+
let cookieHeader;
|
|
55
|
+
const currentSetCookieHeader = response.getHeader('Set-Cookie');
|
|
56
|
+
if (currentSetCookieHeader) {
|
|
57
|
+
if (Array.isArray(currentSetCookieHeader)) {
|
|
58
|
+
cookieHeader = [...currentSetCookieHeader, clientIdCookieString];
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
cookieHeader = `${currentSetCookieHeader}; ${clientIdCookieString}`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
cookieHeader = clientIdCookieString;
|
|
66
|
+
}
|
|
67
|
+
response.setHeader('Set-Cookie', cookieHeader);
|
|
68
|
+
},
|
|
69
|
+
location: {
|
|
70
|
+
getSearchParams: () => {
|
|
71
|
+
// Host is irrelevant but necessary to support relative URL
|
|
72
|
+
const requestUrl = new URL(request.url, `https://localhost`);
|
|
73
|
+
return requestUrl.search;
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Retrieves the client ID from the request cookies.
|
|
80
|
+
* @template Request - The HTTP request type extending `IncomingMessage`.
|
|
81
|
+
* @param {Request} request
|
|
82
|
+
* @returns {string | null} The client ID or null if not found.
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
function getClientId(request) {
|
|
86
|
+
var _a, _b;
|
|
87
|
+
return ((_b = (_a = getCookieServerSide(request.headers.cookie, getAnalyticsPlugin().options.cookies.name)) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null);
|
|
88
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { getDefaultCookieAttributes } from './cookie/get-default-cookie-attributes';
|
|
2
|
+
export { language, pageName } from './infer/infer';
|
|
3
|
+
export { generateCorrelationId } from './correlation-id/generate-correlation-id';
|
|
4
|
+
export { API_VERSION, COOKIE_NAME_PREFIX, DAILY_SECONDS, DEFAULT_COOKIE_EXPIRY_DAYS, LIBRARY_VERSION, CORRELATION_ID_HEADER, CLIENT_ID_COOKIE_NAME, } from './consts';
|
|
5
|
+
export { fetchClientIdFromEdgeProxy } from './client-id/fetch-client-id-from-edge-proxy';
|
|
6
|
+
export { getAnalyticsPlugin } from './initialization/plugin';
|
|
7
|
+
export { ANALYTICS_PLUGIN_NAME } from './initialization/const';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Appends a script element to the document head with the specified attributes.
|
|
3
|
+
* @param {ScriptAttributes} attributes - The attributes to set on the script element.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export function appendScriptWithAttributes(attributes) {
|
|
7
|
+
const sdkScriptElement = document.createElement('script');
|
|
8
|
+
sdkScriptElement.type = 'text/javascript';
|
|
9
|
+
sdkScriptElement.src = attributes.src;
|
|
10
|
+
sdkScriptElement.async = attributes.async;
|
|
11
|
+
document.head.appendChild(sdkScriptElement);
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a string or plain object to a base64 string representation.
|
|
3
|
+
* @param {string | Record<string, unknown>} input The value to convert.
|
|
4
|
+
* @returns {string} The base64-encoded string.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export function convertToBase64(input) {
|
|
8
|
+
const data = typeof input === 'string' ? input : JSON.stringify(input);
|
|
9
|
+
const stringFormat = 'base64';
|
|
10
|
+
if (typeof Buffer === 'function')
|
|
11
|
+
return Buffer.from(data).toString(stringFormat);
|
|
12
|
+
if (typeof (window === null || window === void 0 ? void 0 : window.btoa) === 'function')
|
|
13
|
+
return window.btoa(data);
|
|
14
|
+
return data;
|
|
15
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flattens a nested object by concatenating keys with an underscore.
|
|
3
|
+
* @param {FlattenObjectDataParameters} data Parameters describing the flatten operation.
|
|
4
|
+
* @returns {FlattenedObject} A new flattened object.
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* const object = { order: { amount: 1, delivered: false } };
|
|
8
|
+
* const flattenedObject = flattenObject(object);
|
|
9
|
+
* // flattenedObject is { order_amount: 1, order_delivered: false }
|
|
10
|
+
* ```
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export function flattenObject(data) {
|
|
14
|
+
var _a;
|
|
15
|
+
const { currentKey, object } = data;
|
|
16
|
+
const newObject = (_a = data.newObject) !== null && _a !== void 0 ? _a : {};
|
|
17
|
+
// eslint-disable-next-line guard-for-in
|
|
18
|
+
for (const key in object) {
|
|
19
|
+
const value = object[key];
|
|
20
|
+
if (value === undefined)
|
|
21
|
+
continue;
|
|
22
|
+
if (typeof value === 'object' && !Array.isArray(value))
|
|
23
|
+
flattenObject({
|
|
24
|
+
currentKey: `${currentKey ? `${currentKey}_${key}` : key}`,
|
|
25
|
+
newObject,
|
|
26
|
+
object: value,
|
|
27
|
+
});
|
|
28
|
+
else
|
|
29
|
+
newObject[currentKey ? `${currentKey}_${key}` : key] = value;
|
|
30
|
+
}
|
|
31
|
+
return newObject;
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DAILY_SECONDS = 86400;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getCookieServerSide } from './get-cookie-server-side';
|
|
2
|
+
/**
|
|
3
|
+
* Checks whether a cookie exists in a server-side request header string.
|
|
4
|
+
* @param {string} cookiesHeader Raw `cookie` header contents.
|
|
5
|
+
* @param {string} cookieName The cookie name to search for.
|
|
6
|
+
* @returns {boolean} True when the cookie is present.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export function cookieExistsInServerSide(cookiesHeader, cookieName) {
|
|
10
|
+
return getCookieServerSide(cookiesHeader, cookieName) !== undefined;
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks whether the cookie exists within a cookie string.
|
|
3
|
+
* @param {string} cookieStr Cookie string containing individual cookies.
|
|
4
|
+
* @param {string} cookieName The cookie name to search for.
|
|
5
|
+
* @returns {boolean} True when the cookie exists in the string.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export function cookieExists(cookieStr, cookieName) {
|
|
9
|
+
return cookieStr.split('; ').some((cookie) => cookie.split('=')[0] === cookieName);
|
|
10
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a cookie string with the provided attributes.
|
|
3
|
+
* @param {string} name Cookie name.
|
|
4
|
+
* @param {string} value Cookie value.
|
|
5
|
+
* @param {CookieProperties} attributes Supported cookie attributes.
|
|
6
|
+
* @returns {string} Serialized cookie ready to be assigned to `document.cookie`.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export function createCookieString(name, value, attributes) {
|
|
10
|
+
let cookieString = `${name}=${value};`;
|
|
11
|
+
cookieString += ` Max-Age=${attributes.maxAge}; SameSite=${attributes.sameSite};`;
|
|
12
|
+
cookieString += attributes.secure ? ' Secure;' : '';
|
|
13
|
+
cookieString += attributes.path ? ` Path=${attributes.path};` : '';
|
|
14
|
+
cookieString += attributes.domain ? ` Domain=${attributes.domain};` : '';
|
|
15
|
+
cookieString = cookieString.substring(0, cookieString.length - 1);
|
|
16
|
+
return cookieString;
|
|
17
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deletes a cookie from the document (client-side only).
|
|
3
|
+
* @param {string} cookieName The cookie to be deleted.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export function deleteCookie(cookieName) {
|
|
7
|
+
document.cookie = cookieName + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
|
8
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getCookie } from './get-cookie';
|
|
2
|
+
/**
|
|
3
|
+
* Retrieves a cookie from the server-side request header string.
|
|
4
|
+
* @param {string | undefined} cookiesHeader Raw `cookie` header contents.
|
|
5
|
+
* @param {string} cookieName The cookie name to look up.
|
|
6
|
+
* @returns {{ name: string; value: string } | undefined} The resolved cookie information when found.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export function getCookieServerSide(cookiesHeader, cookieName) {
|
|
10
|
+
return getCookie(cookiesHeader, cookieName);
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getCookie } from './get-cookie';
|
|
2
|
+
/**
|
|
3
|
+
* Retrieves the value of a cookie in the browser context.
|
|
4
|
+
* @param {string} cookieName The name of the cookie to read.
|
|
5
|
+
* @returns {string} The cookie value or an empty string when not found.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export function getCookieValueClientSide(cookieName) {
|
|
9
|
+
var _a;
|
|
10
|
+
const cookie = getCookie(document.cookie, cookieName);
|
|
11
|
+
return (_a = cookie === null || cookie === void 0 ? void 0 : cookie.value) !== null && _a !== void 0 ? _a : '';
|
|
12
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieves a cookie by name from a cookie string.
|
|
3
|
+
* @param {string | undefined} cookieStr Cookie string containing serialized cookies.
|
|
4
|
+
* @param {string} cookieName The cookie name to locate.
|
|
5
|
+
* @returns {{ name: string; value: string } | undefined} The cookie name/value pair when found.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export function getCookie(cookieStr, cookieName) {
|
|
9
|
+
if (!cookieStr)
|
|
10
|
+
return undefined;
|
|
11
|
+
const found = cookieStr.split('; ').find((cookie) => {
|
|
12
|
+
return cookie.indexOf('=') > 0 && cookie.split('=')[0] === cookieName;
|
|
13
|
+
});
|
|
14
|
+
return found !== undefined
|
|
15
|
+
? { name: found.split('=')[0], value: found.split('=')[1] }
|
|
16
|
+
: undefined;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if the provided string matches the shortened ISO 8601 format (`YYYY-MM-DDThh:mm`).
|
|
3
|
+
* @param {string} date The date string to validate.
|
|
4
|
+
* @returns {boolean} True when the value conforms to the shortened ISO format.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export function isShortISODateString(date) {
|
|
8
|
+
try {
|
|
9
|
+
const dateString = date + 'Z';
|
|
10
|
+
const convertedDate = new Date(dateString).toISOString().substring(0, 16);
|
|
11
|
+
return convertedDate === date;
|
|
12
|
+
// eslint-disable-next-line no-unused-vars
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates whether the provided value matches a basic email pattern.
|
|
3
|
+
* @param {string} email The email address to validate.
|
|
4
|
+
* @returns {boolean} True when the email matches the allowed pattern.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export function isValidEmail(email) {
|
|
8
|
+
const regx = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
|
|
9
|
+
if (!email || email.length > 320) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
return regx.test(email);
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { createCookieString } from './utils/cookies/create-cookie-string';
|
|
2
|
+
export { getCookieValueClientSide } from './utils/cookies/get-cookie-value-client-side';
|
|
3
|
+
export { getCookie } from './utils/cookies/get-cookie';
|
|
4
|
+
export { getCookieServerSide } from './utils/cookies/get-cookie-server-side';
|
|
5
|
+
export { cookieExists } from './utils/cookies/cookie-exists';
|
|
6
|
+
export { flattenObject } from './utils/converters/flatten-object';
|
|
7
|
+
export { isShortISODateString } from './utils/validators/is-short-iso-date-string';
|
|
8
|
+
export { isValidEmail } from './utils/validators/is-valid-email';
|
|
9
|
+
export { generateV4UUID } from './utils/generators/generate-v4-uuid';
|
|
10
|
+
export { appendScriptWithAttributes, } from './utils/browser/appendScriptWithAttributes';
|
package/internal.d.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": {
|
|
3
|
+
"name": "Sitecore Corporation",
|
|
4
|
+
"url": "https://doc.sitecore.com/xmc/en/developers/content-sdk/index.html"
|
|
5
|
+
},
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/sitecore/content-sdk/issues"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@sitecore-content-sdk/core": "2.0.0-canary.12",
|
|
11
|
+
"debug": "^4.4.3"
|
|
12
|
+
},
|
|
13
|
+
"description": "Provides shared logic and runtime initialization. Required for the Content SDK 'events' and 'personalize' packages to function.",
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@jest/types": "^29.6.3",
|
|
16
|
+
"@stylistic/eslint-plugin": "^5.2.2",
|
|
17
|
+
"@types/debug": "^4.1.12",
|
|
18
|
+
"@types/jest": "^29.5.12",
|
|
19
|
+
"@typescript-eslint/eslint-plugin": "8.39.0",
|
|
20
|
+
"@typescript-eslint/parser": "8.39.0",
|
|
21
|
+
"del-cli": "^6.0.0",
|
|
22
|
+
"eslint": "^9.32.0",
|
|
23
|
+
"eslint-config-prettier": "^10.1.8",
|
|
24
|
+
"eslint-plugin-import": "2.32.0",
|
|
25
|
+
"eslint-plugin-jsdoc": "52.0.3",
|
|
26
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
27
|
+
"jest": "^29.7.0",
|
|
28
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
29
|
+
"jest-environment-node": "^29.7.0",
|
|
30
|
+
"ts-jest": "^29.1.0",
|
|
31
|
+
"ts-node": "^10.9.2"
|
|
32
|
+
},
|
|
33
|
+
"main": "dist/cjs/index.js",
|
|
34
|
+
"module": "dist/esm/index.js",
|
|
35
|
+
"types": "types/src/index.d.ts",
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"import": "./dist/esm/src/index.js",
|
|
39
|
+
"require": "./dist/cjs/src/index.js",
|
|
40
|
+
"types": "./types/src/index.d.ts"
|
|
41
|
+
},
|
|
42
|
+
"./internal": {
|
|
43
|
+
"import": "./dist/esm/src/internal.js",
|
|
44
|
+
"require": "./dist/cjs/src/internal.js",
|
|
45
|
+
"types": "./types/src/internal.d.ts"
|
|
46
|
+
},
|
|
47
|
+
"./utils": {
|
|
48
|
+
"import": "./dist/esm/src/utils.js",
|
|
49
|
+
"require": "./dist/cjs/src/utils.js",
|
|
50
|
+
"types": "./types/src/utils.d.ts"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"files": [
|
|
54
|
+
"dist",
|
|
55
|
+
"types",
|
|
56
|
+
"/*.d.ts"
|
|
57
|
+
],
|
|
58
|
+
"homepage": "https://doc.sitecore.com/xmc/en/developers/content-sdk/index.html",
|
|
59
|
+
"license": "Apache-2.0",
|
|
60
|
+
"name": "@sitecore-content-sdk/analytics-core",
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public",
|
|
63
|
+
"registry": "https://registry.npmjs.org/"
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"build": "npm run clean && tsc -p tsconfig.json && tsc -p tsconfig-esm.json",
|
|
67
|
+
"clean": "del-cli dist types",
|
|
68
|
+
"coverage": "jest --config jest.config.ts --coverage",
|
|
69
|
+
"generate-docs": "npx typedoc --plugin typedoc-plugin-markdown --outputFileStrategy Members --parametersFormat table --readme none --out ../../ref-docs/analytics-core --entryPoints src/index.ts --entryPoints src/internal.ts --entryPoints src/utils.ts --githubPages false",
|
|
70
|
+
"lint": "eslint \"./src/**/*.ts\"",
|
|
71
|
+
"prepublishOnly": "npm run build",
|
|
72
|
+
"test": "jest --config jest.config.ts",
|
|
73
|
+
"api-extractor": "npm run build && api-extractor run --local --verbose",
|
|
74
|
+
"api-extractor:verify": "api-extractor run"
|
|
75
|
+
},
|
|
76
|
+
"version": "2.0.0-canary.12",
|
|
77
|
+
"gitHead": "4a26005860f4931f25d8c63d765a030e04a5b1f4"
|
|
78
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { VisitorIds } from '../interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* Gets the client ID and client key from Sitecore Edge proxy.
|
|
4
|
+
* @param {string} edgeUrl - The base URL for the Edge proxy API.
|
|
5
|
+
* @param {string} contextId - The Sitecore context ID parameter for the Edge proxy API.
|
|
6
|
+
* @param {number} [timeout] - The timeout in milliseconds for the call to the proxy.
|
|
7
|
+
* @returns {Promise<VisitorIds>} The client ID and profile ID from the proxy.
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export declare function fetchClientIdFromEdgeProxy(edgeUrl: string, contextId: string, timeout?: number): Promise<VisitorIds>;
|
|
11
|
+
//# sourceMappingURL=fetch-client-id-from-edge-proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-client-id-from-edge-proxy.d.ts","sourceRoot":"","sources":["../../../src/client-id/fetch-client-id-from-edge-proxy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,eAAe,CAAC;AAM5D;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CA+BrB"}
|