@sitecore-content-sdk/core 0.1.0-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/LICENSE.txt +202 -0
- package/README.md +11 -0
- package/dist/cjs/cache-client.js +54 -0
- package/dist/cjs/constants.js +13 -0
- package/dist/cjs/data-fetcher.js +33 -0
- package/dist/cjs/debug.js +43 -0
- package/dist/cjs/editing/component-library.js +104 -0
- package/dist/cjs/editing/graphql-editing-service.js +186 -0
- package/dist/cjs/editing/index.js +23 -0
- package/dist/cjs/editing/models.js +23 -0
- package/dist/cjs/editing/rest-component-layout-service.js +76 -0
- package/dist/cjs/editing/utils.js +86 -0
- package/dist/cjs/graphql/app-root-query.js +73 -0
- package/dist/cjs/graphql/graphql-edge-proxy.js +21 -0
- package/dist/cjs/graphql/index.js +13 -0
- package/dist/cjs/graphql/search-service.js +61 -0
- package/dist/cjs/graphql-request-client.js +152 -0
- package/dist/cjs/i18n/dictionary-service.js +45 -0
- package/dist/cjs/i18n/graphql-dictionary-service.js +136 -0
- package/dist/cjs/i18n/index.js +7 -0
- package/dist/cjs/index.js +55 -0
- package/dist/cjs/layout/content-styles.js +70 -0
- package/dist/cjs/layout/graphql-layout-service.js +86 -0
- package/dist/cjs/layout/index.js +24 -0
- package/dist/cjs/layout/layout-service.js +9 -0
- package/dist/cjs/layout/models.js +35 -0
- package/dist/cjs/layout/themes.js +74 -0
- package/dist/cjs/layout/utils.js +110 -0
- package/dist/cjs/media/index.js +38 -0
- package/dist/cjs/media/media-api.js +96 -0
- package/dist/cjs/models.js +2 -0
- package/dist/cjs/native-fetcher.js +200 -0
- package/dist/cjs/personalize/graphql-personalize-service.js +114 -0
- package/dist/cjs/personalize/index.js +14 -0
- package/dist/cjs/personalize/layout-personalizer.js +97 -0
- package/dist/cjs/personalize/utils.js +136 -0
- package/dist/cjs/site/graphql-error-pages-service.js +89 -0
- package/dist/cjs/site/graphql-redirects-service.js +105 -0
- package/dist/cjs/site/graphql-robots-service.js +83 -0
- package/dist/cjs/site/graphql-siteinfo-service.js +107 -0
- package/dist/cjs/site/graphql-sitemap-service.js +93 -0
- package/dist/cjs/site/index.js +22 -0
- package/dist/cjs/site/site-resolver.js +79 -0
- package/dist/cjs/site/utils.js +43 -0
- package/dist/cjs/utils/env.js +26 -0
- package/dist/cjs/utils/index.js +20 -0
- package/dist/cjs/utils/is-server.js +10 -0
- package/dist/cjs/utils/timeout-promise.js +31 -0
- package/dist/cjs/utils/utils.js +222 -0
- package/dist/esm/cache-client.js +50 -0
- package/dist/esm/constants.js +10 -0
- package/dist/esm/data-fetcher.js +28 -0
- package/dist/esm/debug.js +36 -0
- package/dist/esm/editing/component-library.js +98 -0
- package/dist/esm/editing/graphql-editing-service.js +179 -0
- package/dist/esm/editing/index.js +5 -0
- package/dist/esm/editing/models.js +20 -0
- package/dist/esm/editing/rest-component-layout-service.js +72 -0
- package/dist/esm/editing/utils.js +76 -0
- package/dist/esm/graphql/app-root-query.js +69 -0
- package/dist/esm/graphql/graphql-edge-proxy.js +16 -0
- package/dist/esm/graphql/index.js +4 -0
- package/dist/esm/graphql/search-service.js +57 -0
- package/dist/esm/graphql-request-client.js +144 -0
- package/dist/esm/i18n/dictionary-service.js +41 -0
- package/dist/esm/i18n/graphql-dictionary-service.js +129 -0
- package/dist/esm/i18n/index.js +2 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/layout/content-styles.js +62 -0
- package/dist/esm/layout/graphql-layout-service.js +79 -0
- package/dist/esm/layout/index.js +6 -0
- package/dist/esm/layout/layout-service.js +5 -0
- package/dist/esm/layout/models.js +32 -0
- package/dist/esm/layout/themes.js +69 -0
- package/dist/esm/layout/utils.js +102 -0
- package/dist/esm/media/index.js +2 -0
- package/dist/esm/media/media-api.js +86 -0
- package/dist/esm/models.js +1 -0
- package/dist/esm/native-fetcher.js +193 -0
- package/dist/esm/personalize/graphql-personalize-service.js +107 -0
- package/dist/esm/personalize/index.js +3 -0
- package/dist/esm/personalize/layout-personalizer.js +92 -0
- package/dist/esm/personalize/utils.js +128 -0
- package/dist/esm/site/graphql-error-pages-service.js +82 -0
- package/dist/esm/site/graphql-redirects-service.js +98 -0
- package/dist/esm/site/graphql-robots-service.js +76 -0
- package/dist/esm/site/graphql-siteinfo-service.js +100 -0
- package/dist/esm/site/graphql-sitemap-service.js +86 -0
- package/dist/esm/site/index.js +7 -0
- package/dist/esm/site/site-resolver.js +75 -0
- package/dist/esm/site/utils.js +37 -0
- package/dist/esm/utils/env.js +22 -0
- package/dist/esm/utils/index.js +3 -0
- package/dist/esm/utils/is-server.js +8 -0
- package/dist/esm/utils/timeout-promise.js +28 -0
- package/dist/esm/utils/utils.js +207 -0
- package/editing.d.ts +1 -0
- package/editing.js +1 -0
- package/graphql.d.ts +1 -0
- package/graphql.js +1 -0
- package/i18n.d.ts +1 -0
- package/i18n.js +1 -0
- package/layout.d.ts +1 -0
- package/layout.js +1 -0
- package/media.d.ts +1 -0
- package/media.js +1 -0
- package/package.json +76 -0
- package/personalize.d.ts +1 -0
- package/personalize.js +1 -0
- package/site.d.ts +1 -0
- package/site.js +1 -0
- package/types/cache-client.d.ts +64 -0
- package/types/constants.d.ts +7 -0
- package/types/data-fetcher.d.ts +34 -0
- package/types/debug.d.ts +26 -0
- package/types/editing/component-library.d.ts +48 -0
- package/types/editing/graphql-editing-service.d.ts +90 -0
- package/types/editing/index.d.ts +6 -0
- package/types/editing/models.d.ts +52 -0
- package/types/editing/rest-component-layout-service.d.ts +100 -0
- package/types/editing/utils.d.ts +70 -0
- package/types/graphql/app-root-query.d.ts +32 -0
- package/types/graphql/graphql-edge-proxy.d.ts +15 -0
- package/types/graphql/index.d.ts +4 -0
- package/types/graphql/search-service.d.ts +95 -0
- package/types/graphql-request-client.d.ts +159 -0
- package/types/i18n/dictionary-service.d.ts +56 -0
- package/types/i18n/graphql-dictionary-service.d.ts +94 -0
- package/types/i18n/index.d.ts +2 -0
- package/types/index.d.ts +8 -0
- package/types/layout/content-styles.d.ts +18 -0
- package/types/layout/graphql-layout-service.d.ts +58 -0
- package/types/layout/index.d.ts +6 -0
- package/types/layout/layout-service.d.ts +19 -0
- package/types/layout/models.d.ts +145 -0
- package/types/layout/themes.d.ts +11 -0
- package/types/layout/utils.d.ts +40 -0
- package/types/media/index.d.ts +2 -0
- package/types/media/media-api.d.ts +55 -0
- package/types/models.d.ts +6 -0
- package/types/native-fetcher.d.ts +121 -0
- package/types/personalize/graphql-personalize-service.d.ts +80 -0
- package/types/personalize/index.d.ts +3 -0
- package/types/personalize/layout-personalizer.d.ts +27 -0
- package/types/personalize/utils.d.ts +69 -0
- package/types/site/graphql-error-pages-service.d.ts +57 -0
- package/types/site/graphql-redirects-service.d.ts +68 -0
- package/types/site/graphql-robots-service.d.ts +49 -0
- package/types/site/graphql-siteinfo-service.d.ts +70 -0
- package/types/site/graphql-sitemap-service.d.ts +55 -0
- package/types/site/index.d.ts +7 -0
- package/types/site/site-resolver.d.ts +27 -0
- package/types/site/utils.d.ts +24 -0
- package/types/utils/env.d.ts +7 -0
- package/types/utils/index.d.ts +3 -0
- package/types/utils/is-server.d.ts +6 -0
- package/types/utils/timeout-promise.d.ts +17 -0
- package/types/utils/utils.d.ts +71 -0
- package/utils.d.ts +1 -0
- package/utils.js +1 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getSrcSet = exports.updateImageUrl = exports.replaceMediaUrlPrefix = exports.getRequiredParams = void 0;
|
|
7
|
+
const url_parse_1 = __importDefault(require("url-parse"));
|
|
8
|
+
// finds the Sitecore media URL prefix
|
|
9
|
+
const mediaUrlPrefixRegex = /\/([-~]{1})\/media\//i;
|
|
10
|
+
/**
|
|
11
|
+
* Get required query string params which should be merged with user params
|
|
12
|
+
* @param {object} qs layout service parsed query string
|
|
13
|
+
* @returns {object} requiredParams
|
|
14
|
+
*/
|
|
15
|
+
const getRequiredParams = (qs) => {
|
|
16
|
+
const { rev, db, la, vs, ts } = qs;
|
|
17
|
+
return { rev, db, la, vs, ts };
|
|
18
|
+
};
|
|
19
|
+
exports.getRequiredParams = getRequiredParams;
|
|
20
|
+
/**
|
|
21
|
+
* Replace `/~/media` or `/-/media` with `/~/jssmedia` or `/-/jssmedia`, respectively.
|
|
22
|
+
* Can use `mediaUrlPrefix` in order to use a custom prefix.
|
|
23
|
+
* @param {string} url The URL to replace the media URL prefix in
|
|
24
|
+
* @param {RegExp} [mediaUrlPrefix] The regex to match the media URL prefix
|
|
25
|
+
* @returns {string} The URL with the media URL prefix replaced
|
|
26
|
+
*/
|
|
27
|
+
const replaceMediaUrlPrefix = (url, mediaUrlPrefix = mediaUrlPrefixRegex) => {
|
|
28
|
+
const parsed = (0, url_parse_1.default)(url, {}, true);
|
|
29
|
+
const match = mediaUrlPrefix.exec(parsed.pathname);
|
|
30
|
+
if (match && match.length > 1) {
|
|
31
|
+
// regex will provide us with /-/ or /~/ type
|
|
32
|
+
parsed.set('pathname', parsed.pathname.replace(mediaUrlPrefix, `/${match[1]}/jssmedia/`));
|
|
33
|
+
}
|
|
34
|
+
return parsed.toString();
|
|
35
|
+
};
|
|
36
|
+
exports.replaceMediaUrlPrefix = replaceMediaUrlPrefix;
|
|
37
|
+
/**
|
|
38
|
+
* Prepares a Sitecore media URL with `params` for use by the JSS media handler.
|
|
39
|
+
* This is done by replacing `/~/media` or `/-/media` with `/~/jssmedia` or `/-/jssmedia`, respectively.
|
|
40
|
+
* Provided `params` are used as the querystring parameters for the media URL.
|
|
41
|
+
* Can use `mediaUrlPrefix` in order to use a custom prefix.
|
|
42
|
+
* If no `params` are sent, the original media URL is returned.
|
|
43
|
+
* @param {string} url The URL to prepare
|
|
44
|
+
* @param {object} [params] The querystring parameters to use
|
|
45
|
+
* @param {RegExp} [mediaUrlPrefix] The regex to match the media URL prefix
|
|
46
|
+
* @returns {string} The prepared URL
|
|
47
|
+
*/
|
|
48
|
+
const updateImageUrl = (url, params, mediaUrlPrefix = mediaUrlPrefixRegex) => {
|
|
49
|
+
if (!params || Object.keys(params).length === 0) {
|
|
50
|
+
// if params aren't supplied, no need to run it through JSS media handler
|
|
51
|
+
return url;
|
|
52
|
+
}
|
|
53
|
+
// polyfill node `global` in browser to workaround https://github.com/unshiftio/url-parse/issues/150
|
|
54
|
+
if (typeof window !== 'undefined' && !window.global) {
|
|
55
|
+
window.global = {};
|
|
56
|
+
}
|
|
57
|
+
const parsed = (0, url_parse_1.default)((0, exports.replaceMediaUrlPrefix)(url, mediaUrlPrefix), {}, true);
|
|
58
|
+
const requiredParams = (0, exports.getRequiredParams)(parsed.query);
|
|
59
|
+
const query = Object.assign({}, params);
|
|
60
|
+
Object.entries(requiredParams).forEach(([key, param]) => {
|
|
61
|
+
if (param) {
|
|
62
|
+
query[key] = param;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
parsed.set('query', query);
|
|
66
|
+
return parsed.toString();
|
|
67
|
+
};
|
|
68
|
+
exports.updateImageUrl = updateImageUrl;
|
|
69
|
+
/**
|
|
70
|
+
* Receives an array of `srcSet` parameters that are iterated and used as parameters to generate
|
|
71
|
+
* a corresponding set of updated Sitecore media URLs via @see updateImageUrl. The result is a comma-delimited
|
|
72
|
+
* list of media URLs with respective dimension parameters.
|
|
73
|
+
* @example
|
|
74
|
+
* // returns '/ipsum.jpg?h=1000&w=1000 1000w, /ipsum.jpg?mh=250&mw=250 250w'
|
|
75
|
+
* getSrcSet('/ipsum.jpg', [{ h: 1000, w: 1000 }, { mh: 250, mw: 250 } ])
|
|
76
|
+
* More information about `srcSet`: {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img}
|
|
77
|
+
* @param {string} url The URL to prepare
|
|
78
|
+
* @param {Array} srcSet The array of parameters to use
|
|
79
|
+
* @param {object} [imageParams] The querystring parameters to use
|
|
80
|
+
* @param {RegExp} [mediaUrlPrefix] The regex to match the media URL prefix
|
|
81
|
+
* @returns {string} The prepared URL
|
|
82
|
+
*/
|
|
83
|
+
const getSrcSet = (url, srcSet, imageParams, mediaUrlPrefix) => {
|
|
84
|
+
return srcSet
|
|
85
|
+
.map((params) => {
|
|
86
|
+
const newParams = Object.assign(Object.assign({}, imageParams), params);
|
|
87
|
+
const imageWidth = newParams.w || newParams.mw;
|
|
88
|
+
if (!imageWidth) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return `${(0, exports.updateImageUrl)(url, newParams, mediaUrlPrefix)} ${imageWidth}w`;
|
|
92
|
+
})
|
|
93
|
+
.filter((value) => value)
|
|
94
|
+
.join(', ');
|
|
95
|
+
};
|
|
96
|
+
exports.getSrcSet = getSrcSet;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.NativeDataFetcher = void 0;
|
|
27
|
+
const debug_1 = __importDefault(require("./debug"));
|
|
28
|
+
const timeout_promise_1 = __importDefault(require("./utils/timeout-promise"));
|
|
29
|
+
class NativeDataFetcher {
|
|
30
|
+
constructor(config = {}) {
|
|
31
|
+
this.config = config;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Implements a data fetcher.
|
|
35
|
+
* @param {string} url The URL to request (may include query string)
|
|
36
|
+
* @param {RequestInit} [options] Optional fetch options
|
|
37
|
+
* @returns {Promise<NativeDataFetcherResponse<T>>} response
|
|
38
|
+
*/
|
|
39
|
+
fetch(url_1) {
|
|
40
|
+
return __awaiter(this, arguments, void 0, function* (url, options = {}) {
|
|
41
|
+
var _a;
|
|
42
|
+
const _b = this.config, { debugger: debugOverride, fetch: fetchOverride } = _b, init = __rest(_b, ["debugger", "fetch"]);
|
|
43
|
+
const startTimestamp = Date.now();
|
|
44
|
+
const fetchImpl = fetchOverride || fetch;
|
|
45
|
+
const debug = debugOverride || debug_1.default.http;
|
|
46
|
+
const requestInit = this.getRequestInit(Object.assign(Object.assign({}, init), options));
|
|
47
|
+
const fetchWithOptionalTimeout = [fetchImpl(url, requestInit)];
|
|
48
|
+
if (init.timeout) {
|
|
49
|
+
this.abortTimeout = new timeout_promise_1.default(init.timeout);
|
|
50
|
+
fetchWithOptionalTimeout.push(this.abortTimeout.start);
|
|
51
|
+
}
|
|
52
|
+
debug('Request initiated: %o', Object.assign({ url, headers: this.extractDebugHeaders(requestInit.headers) }, requestInit));
|
|
53
|
+
try {
|
|
54
|
+
const response = yield Promise.race(fetchWithOptionalTimeout).then((res) => {
|
|
55
|
+
var _a;
|
|
56
|
+
(_a = this.abortTimeout) === null || _a === void 0 ? void 0 : _a.clear();
|
|
57
|
+
return res;
|
|
58
|
+
});
|
|
59
|
+
const respData = yield this.parseResponse(response, debug);
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
const error = this.createError(response, respData);
|
|
62
|
+
debug('Response error: %o', error.response);
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
debug('Response in %dms: %o', Date.now() - startTimestamp, {
|
|
66
|
+
status: response.status,
|
|
67
|
+
statusText: response.statusText,
|
|
68
|
+
headers: this.extractDebugHeaders(response.headers),
|
|
69
|
+
url: response.url,
|
|
70
|
+
data: respData,
|
|
71
|
+
});
|
|
72
|
+
return Object.assign(Object.assign({}, response), { data: respData });
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
(_a = this.abortTimeout) === null || _a === void 0 ? void 0 : _a.clear();
|
|
76
|
+
debug('Request failed: %o', error);
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Perform a GET request
|
|
83
|
+
* @param {string} url The URL to request (may include query string)
|
|
84
|
+
* @param {RequestInit} [options] Fetch options
|
|
85
|
+
* @returns {Promise<NativeDataFetcherResponse<T>>} response
|
|
86
|
+
*/
|
|
87
|
+
get(url_1) {
|
|
88
|
+
return __awaiter(this, arguments, void 0, function* (url, options = {}) {
|
|
89
|
+
return this.fetch(url, Object.assign({ method: 'GET' }, options));
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Perform a POST request
|
|
94
|
+
* @param {string} url The URL to request (may include query string)
|
|
95
|
+
* @param {unknown} body The data to send with the request
|
|
96
|
+
* @param {RequestInit} [options] Fetch options
|
|
97
|
+
* @returns {Promise<NativeDataFetcherResponse<T>>} response
|
|
98
|
+
*/
|
|
99
|
+
post(url_1, body_1) {
|
|
100
|
+
return __awaiter(this, arguments, void 0, function* (url, body, options = {}) {
|
|
101
|
+
return this.fetch(url, Object.assign({ method: 'POST', body: JSON.stringify(body) }, options));
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Perform a DELETE request
|
|
106
|
+
* @param {string} url The URL to request (may include query string)
|
|
107
|
+
* @param {RequestInit} [options] Fetch options
|
|
108
|
+
* @returns {Promise<NativeDataFetcherResponse<T>>} response
|
|
109
|
+
*/
|
|
110
|
+
delete(url_1) {
|
|
111
|
+
return __awaiter(this, arguments, void 0, function* (url, options = {}) {
|
|
112
|
+
return this.fetch(url, Object.assign({ method: 'DELETE' }, options));
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Perform a PUT request
|
|
117
|
+
* @param {string} url The URL to request (may include query string)
|
|
118
|
+
* @param {unknown} body The data to send with the request
|
|
119
|
+
* @param {RequestInit} [options] Fetch options
|
|
120
|
+
* @returns {Promise<NativeDataFetcherResponse<T>>} response
|
|
121
|
+
*/
|
|
122
|
+
put(url_1, body_1) {
|
|
123
|
+
return __awaiter(this, arguments, void 0, function* (url, body, options = {}) {
|
|
124
|
+
return this.fetch(url, Object.assign({ method: 'PUT', body: JSON.stringify(body) }, options));
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Perform a HEAD request
|
|
129
|
+
* @param {string} url The URL to request (may include query string)
|
|
130
|
+
* @param {RequestInit} [options] Fetch options
|
|
131
|
+
* @returns {Promise<NativeDataFetcherResponse<T>>} response
|
|
132
|
+
*/
|
|
133
|
+
head(url, options = {}) {
|
|
134
|
+
return this.fetch(url, Object.assign({ method: 'HEAD' }, options));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Determines settings for the request
|
|
138
|
+
* @param {RequestInit} init Custom settings for request
|
|
139
|
+
* @returns {RequestInit} The final request settings
|
|
140
|
+
*/
|
|
141
|
+
getRequestInit(init = {}) {
|
|
142
|
+
const headers = new Headers(init.headers);
|
|
143
|
+
if (!init.method) {
|
|
144
|
+
init.method = init.body ? 'POST' : 'GET';
|
|
145
|
+
}
|
|
146
|
+
headers.set('Content-Type', 'application/json');
|
|
147
|
+
init.headers = headers;
|
|
148
|
+
return init;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Safely extract all headers for debug logging
|
|
152
|
+
* @param {HeadersInit} incomingHeaders Incoming headers
|
|
153
|
+
* @returns Object with headers as key/value pairs
|
|
154
|
+
*/
|
|
155
|
+
extractDebugHeaders(incomingHeaders = {}) {
|
|
156
|
+
const headers = {};
|
|
157
|
+
if (typeof (incomingHeaders === null || incomingHeaders === void 0 ? void 0 : incomingHeaders.forEach) !== 'string' && incomingHeaders.forEach) {
|
|
158
|
+
incomingHeaders === null || incomingHeaders === void 0 ? void 0 : incomingHeaders.forEach((value, key) => {
|
|
159
|
+
headers[key] = value;
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return headers;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Parses the response data.
|
|
166
|
+
* @param {Response} response - The fetch response object.
|
|
167
|
+
* @param {Function} debug - The debug logger function.
|
|
168
|
+
* @returns {Promise<unknown>} - The parsed response data.
|
|
169
|
+
*/
|
|
170
|
+
parseResponse(response, debug) {
|
|
171
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
172
|
+
const contentType = response.headers.get('Content-Type') || '';
|
|
173
|
+
try {
|
|
174
|
+
if (contentType.includes('application/json')) {
|
|
175
|
+
return yield response.json();
|
|
176
|
+
}
|
|
177
|
+
return yield response.text();
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
debug('Response parsing error: %o', error);
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Creates a custom error for fetch failures.
|
|
187
|
+
* @param {Response} response - The fetch response object.
|
|
188
|
+
* @param {unknown} data - The parsed response data.
|
|
189
|
+
* @returns {NativeDataFetcherError} - The constructed error object.
|
|
190
|
+
*/
|
|
191
|
+
createError(response, data) {
|
|
192
|
+
return Object.assign(Object.assign({}, new Error(`HTTP ${response.status} ${response.statusText}`)), { response: {
|
|
193
|
+
status: response.status,
|
|
194
|
+
statusText: response.statusText,
|
|
195
|
+
headers: this.extractDebugHeaders(response.headers),
|
|
196
|
+
data,
|
|
197
|
+
} });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
exports.NativeDataFetcher = NativeDataFetcher;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GraphQLPersonalizeService = void 0;
|
|
16
|
+
const debug_1 = __importDefault(require("../debug"));
|
|
17
|
+
const utils_1 = require("../utils");
|
|
18
|
+
const cache_client_1 = require("../cache-client");
|
|
19
|
+
class GraphQLPersonalizeService {
|
|
20
|
+
/**
|
|
21
|
+
* Fetch personalize data using the Sitecore GraphQL endpoint.
|
|
22
|
+
* @param {GraphQLPersonalizeServiceConfig} config
|
|
23
|
+
*/
|
|
24
|
+
constructor(config) {
|
|
25
|
+
this.config = config;
|
|
26
|
+
this.config.timeout = config.timeout || 400;
|
|
27
|
+
this.graphQLClient = this.getGraphQLClient();
|
|
28
|
+
this.cache = this.getCacheClient();
|
|
29
|
+
}
|
|
30
|
+
get query() {
|
|
31
|
+
return /* GraphQL */ `
|
|
32
|
+
query($siteName: String!, $language: String!, $itemPath: String!) {
|
|
33
|
+
layout(site: $siteName, routePath: $itemPath, language: $language) {
|
|
34
|
+
item {
|
|
35
|
+
id
|
|
36
|
+
version
|
|
37
|
+
personalization {
|
|
38
|
+
variantIds
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get personalize information for a route
|
|
47
|
+
* @param {string} itemPath page route
|
|
48
|
+
* @param {string} language language
|
|
49
|
+
* @param {string} siteName site name
|
|
50
|
+
* @returns {Promise<PersonalizeInfo | undefined>} the personalize information or undefined (if itemPath / language not found)
|
|
51
|
+
*/
|
|
52
|
+
getPersonalizeInfo(itemPath, language, siteName) {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
var _a;
|
|
55
|
+
debug_1.default.personalize('fetching personalize info for %s %s %s', siteName, itemPath, language);
|
|
56
|
+
const cacheKey = this.getCacheKey(itemPath, language, siteName);
|
|
57
|
+
let data = this.cache.getCacheValue(cacheKey);
|
|
58
|
+
if (!data) {
|
|
59
|
+
try {
|
|
60
|
+
data = yield this.graphQLClient.request(this.query, {
|
|
61
|
+
siteName,
|
|
62
|
+
itemPath,
|
|
63
|
+
language,
|
|
64
|
+
});
|
|
65
|
+
this.cache.setCacheValue(cacheKey, data);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if ((0, utils_1.isTimeoutError)(error)) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return ((_a = data === null || data === void 0 ? void 0 : data.layout) === null || _a === void 0 ? void 0 : _a.item)
|
|
75
|
+
? {
|
|
76
|
+
pageId: data.layout.item.id,
|
|
77
|
+
variantIds: data.layout.item.personalization.variantIds,
|
|
78
|
+
}
|
|
79
|
+
: undefined;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Gets cache client implementation
|
|
84
|
+
* Override this method if custom cache needs to be used
|
|
85
|
+
* @returns CacheClient instance
|
|
86
|
+
*/
|
|
87
|
+
getCacheClient() {
|
|
88
|
+
var _a, _b;
|
|
89
|
+
return new cache_client_1.MemoryCacheClient({
|
|
90
|
+
cacheEnabled: (_a = this.config.cacheEnabled) !== null && _a !== void 0 ? _a : true,
|
|
91
|
+
cacheTimeout: (_b = this.config.cacheTimeout) !== null && _b !== void 0 ? _b : 10,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
getCacheKey(itemPath, language, siteName) {
|
|
95
|
+
return `${siteName}-${itemPath}-${language}`;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Gets a GraphQL client that can make requests to the API. Uses graphql-request as the default
|
|
99
|
+
* library for fetching graphql data (@see GraphQLRequestClient). Override this method if you
|
|
100
|
+
* want to use something else.
|
|
101
|
+
* @returns {GraphQLClient} implementation
|
|
102
|
+
*/
|
|
103
|
+
getGraphQLClient() {
|
|
104
|
+
if (!this.config.clientFactory) {
|
|
105
|
+
throw new Error('clientFactory needs to be provided when initializing GraphQL client.');
|
|
106
|
+
}
|
|
107
|
+
return this.config.clientFactory({
|
|
108
|
+
debugger: debug_1.default.personalize,
|
|
109
|
+
fetch: this.config.fetch,
|
|
110
|
+
timeout: this.config.timeout,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.GraphQLPersonalizeService = GraphQLPersonalizeService;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_VARIANT = exports.CdpHelper = exports.normalizePersonalizedRewrite = exports.getGroomedVariantIds = exports.getPersonalizedRewriteData = exports.getPersonalizedRewrite = exports.GraphQLPersonalizeService = exports.personalizeLayout = void 0;
|
|
4
|
+
var layout_personalizer_1 = require("./layout-personalizer");
|
|
5
|
+
Object.defineProperty(exports, "personalizeLayout", { enumerable: true, get: function () { return layout_personalizer_1.personalizeLayout; } });
|
|
6
|
+
var graphql_personalize_service_1 = require("./graphql-personalize-service");
|
|
7
|
+
Object.defineProperty(exports, "GraphQLPersonalizeService", { enumerable: true, get: function () { return graphql_personalize_service_1.GraphQLPersonalizeService; } });
|
|
8
|
+
var utils_1 = require("./utils");
|
|
9
|
+
Object.defineProperty(exports, "getPersonalizedRewrite", { enumerable: true, get: function () { return utils_1.getPersonalizedRewrite; } });
|
|
10
|
+
Object.defineProperty(exports, "getPersonalizedRewriteData", { enumerable: true, get: function () { return utils_1.getPersonalizedRewriteData; } });
|
|
11
|
+
Object.defineProperty(exports, "getGroomedVariantIds", { enumerable: true, get: function () { return utils_1.getGroomedVariantIds; } });
|
|
12
|
+
Object.defineProperty(exports, "normalizePersonalizedRewrite", { enumerable: true, get: function () { return utils_1.normalizePersonalizedRewrite; } });
|
|
13
|
+
Object.defineProperty(exports, "CdpHelper", { enumerable: true, get: function () { return utils_1.CdpHelper; } });
|
|
14
|
+
Object.defineProperty(exports, "DEFAULT_VARIANT", { enumerable: true, get: function () { return utils_1.DEFAULT_VARIANT; } });
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.personalizeLayout = personalizeLayout;
|
|
4
|
+
exports.personalizePlaceholder = personalizePlaceholder;
|
|
5
|
+
exports.personalizeComponent = personalizeComponent;
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
const transformToHiddenRenderingVariant = (component) => (Object.assign(Object.assign({}, component), { componentName: constants_1.HIDDEN_RENDERING_NAME, experiences: {} }));
|
|
8
|
+
/**
|
|
9
|
+
* Apply personalization to layout data. This will recursively go through all placeholders/components, check experiences nodes and replace default with object from specific experience.
|
|
10
|
+
* @param {LayoutServiceData} layout Layout data
|
|
11
|
+
* @param {string} variantId variant id
|
|
12
|
+
* @param {string[]} [componentVariantIds] component variant ids
|
|
13
|
+
*/
|
|
14
|
+
function personalizeLayout(layout, variantId, componentVariantIds) {
|
|
15
|
+
var _a;
|
|
16
|
+
// Add (page-level) variantId to Sitecore context so that it is accessible here
|
|
17
|
+
layout.sitecore.context.variantId = variantId;
|
|
18
|
+
const placeholders = ((_a = layout.sitecore.route) === null || _a === void 0 ? void 0 : _a.placeholders) || {};
|
|
19
|
+
if (Object.keys(placeholders).length === 0) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const isEditing = layout.sitecore.context.pageEditing;
|
|
23
|
+
if (placeholders) {
|
|
24
|
+
Object.keys(placeholders).forEach((placeholder) => {
|
|
25
|
+
placeholders[placeholder] = personalizePlaceholder(placeholders[placeholder], [variantId, ...(componentVariantIds || [])], isEditing);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return placeholders;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* @param {Array} components components within placeholder
|
|
32
|
+
* @param {string[]} variantIds variant ids
|
|
33
|
+
* @param {boolean} isEditing indicates if page is rendered in metadata edit mode
|
|
34
|
+
* @returns {ComponentRendering[]} components with personalization applied
|
|
35
|
+
*/
|
|
36
|
+
function personalizePlaceholder(components, variantIds, isEditing) {
|
|
37
|
+
return components
|
|
38
|
+
.map((component) => {
|
|
39
|
+
const rendering = component;
|
|
40
|
+
if (rendering.experiences !== undefined) {
|
|
41
|
+
return personalizeComponent(rendering, variantIds, isEditing);
|
|
42
|
+
}
|
|
43
|
+
else if (rendering.placeholders) {
|
|
44
|
+
const placeholders = rendering.placeholders;
|
|
45
|
+
Object.keys(placeholders).forEach((placeholder) => {
|
|
46
|
+
placeholders[placeholder] = personalizePlaceholder(placeholders[placeholder], variantIds, isEditing);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return component;
|
|
50
|
+
})
|
|
51
|
+
.filter(Boolean);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* @param {ComponentRenderingWithExperiences} component component with experiences
|
|
55
|
+
* @param {string[]} variantIds variant ids
|
|
56
|
+
* @param {boolean} isEditing indicates if page is rendered in metadata edit mode
|
|
57
|
+
* @returns {ComponentRendering | null} component with personalization applied or null if hidden
|
|
58
|
+
*/
|
|
59
|
+
function personalizeComponent(component, variantIds, isEditing) {
|
|
60
|
+
// Check if we have a page/component experience matching any of the variants (there should be at most 1)
|
|
61
|
+
const match = Object.keys(component.experiences).find((variantId) => variantIds.includes(variantId));
|
|
62
|
+
const variant = match && component.experiences[match];
|
|
63
|
+
// variant and componentName can be undefined or null
|
|
64
|
+
if (!variant && !component.componentName) {
|
|
65
|
+
// DEFAULT IS HIDDEN
|
|
66
|
+
if (isEditing) {
|
|
67
|
+
component = transformToHiddenRenderingVariant(component);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (variant && variant.componentName === null && variant.dataSource === null) {
|
|
74
|
+
// VARIANT IS HIDDEN
|
|
75
|
+
if (isEditing) {
|
|
76
|
+
component = transformToHiddenRenderingVariant(component);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else if (variant) {
|
|
83
|
+
component = variant;
|
|
84
|
+
}
|
|
85
|
+
// remove unused experiences from layout data
|
|
86
|
+
if (component.experiences) {
|
|
87
|
+
component.experiences = {};
|
|
88
|
+
}
|
|
89
|
+
if (!component.placeholders)
|
|
90
|
+
return component;
|
|
91
|
+
Object.keys(component === null || component === void 0 ? void 0 : component.placeholders).forEach((placeholder) => {
|
|
92
|
+
if (component.placeholders) {
|
|
93
|
+
component.placeholders[placeholder] = personalizePlaceholder(component.placeholders[placeholder], variantIds);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return component;
|
|
97
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CdpHelper = exports.VARIANT_PREFIX = exports.DEFAULT_VARIANT = void 0;
|
|
4
|
+
exports.getPersonalizedRewrite = getPersonalizedRewrite;
|
|
5
|
+
exports.getPersonalizedRewriteData = getPersonalizedRewriteData;
|
|
6
|
+
exports.getGroomedVariantIds = getGroomedVariantIds;
|
|
7
|
+
exports.normalizePersonalizedRewrite = normalizePersonalizedRewrite;
|
|
8
|
+
exports.DEFAULT_VARIANT = '_default';
|
|
9
|
+
exports.VARIANT_PREFIX = '_variantId_';
|
|
10
|
+
/**
|
|
11
|
+
* Get a personalized rewrite path for given pathname
|
|
12
|
+
* @param {string} pathname the pathname
|
|
13
|
+
* @param {string[]} variantIds the variantIds to include in the rewrite
|
|
14
|
+
* @returns {string} the rewrite path
|
|
15
|
+
*/
|
|
16
|
+
function getPersonalizedRewrite(pathname, variantIds) {
|
|
17
|
+
const path = pathname.startsWith('/') ? pathname : '/' + pathname;
|
|
18
|
+
return `${variantIds.map((variantId) => `/${exports.VARIANT_PREFIX}${variantId}`).join('')}${path}`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get personalize data from the rewrite path
|
|
22
|
+
* @param {string} pathname the pathname
|
|
23
|
+
* @returns {PersonalizedRewriteData} the personalize data from the rewrite
|
|
24
|
+
*/
|
|
25
|
+
function getPersonalizedRewriteData(pathname) {
|
|
26
|
+
const segments = pathname.split('/');
|
|
27
|
+
const variantIds = [];
|
|
28
|
+
segments.forEach((segment) => {
|
|
29
|
+
const result = segment.match(`${exports.VARIANT_PREFIX}(.*$)`);
|
|
30
|
+
if (result) {
|
|
31
|
+
variantIds.push(result[1]);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return getGroomedVariantIds(variantIds);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parses a list of variantIds and divides into layout and component variants
|
|
38
|
+
* @param {string[]} variantIds the list of variant IDs for a page
|
|
39
|
+
* @returns {PersonalizedRewriteData} object with variant IDs sorted
|
|
40
|
+
*/
|
|
41
|
+
function getGroomedVariantIds(variantIds) {
|
|
42
|
+
const data = {
|
|
43
|
+
variantId: exports.DEFAULT_VARIANT,
|
|
44
|
+
componentVariantIds: [],
|
|
45
|
+
};
|
|
46
|
+
variantIds.forEach((variantId) => {
|
|
47
|
+
var _a;
|
|
48
|
+
if (variantId.includes('_')) {
|
|
49
|
+
// Component-level personalization in format "<ComponentID>_<VariantID>"
|
|
50
|
+
// There can be multiple
|
|
51
|
+
(_a = data.componentVariantIds) === null || _a === void 0 ? void 0 : _a.push(variantId);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Embedded (page-level) personalization in format "<VariantID>"
|
|
55
|
+
// There should be only one
|
|
56
|
+
data.variantId = variantId;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return data;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Normalize a personalized rewrite path (remove personalize data)
|
|
63
|
+
* @param {string} pathname the pathname
|
|
64
|
+
* @returns {string} the pathname with personalize data removed
|
|
65
|
+
*/
|
|
66
|
+
function normalizePersonalizedRewrite(pathname) {
|
|
67
|
+
if (!pathname.includes(exports.VARIANT_PREFIX)) {
|
|
68
|
+
return pathname;
|
|
69
|
+
}
|
|
70
|
+
let segments = pathname.split('/');
|
|
71
|
+
segments = segments.filter((segment) => !segment.includes(exports.VARIANT_PREFIX));
|
|
72
|
+
const result = segments.join('/');
|
|
73
|
+
// return root path if all segments were personalize data
|
|
74
|
+
return result ? result : '/';
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Static utility class for Sitecore CDP
|
|
78
|
+
*/
|
|
79
|
+
class CdpHelper {
|
|
80
|
+
/**
|
|
81
|
+
* Gets the page variant id for CDP in the required format
|
|
82
|
+
* @param {string} pageId the page id
|
|
83
|
+
* @param {string} language the language
|
|
84
|
+
* @param {string} variantId the variant id
|
|
85
|
+
* @param {string} [scope] the scope value
|
|
86
|
+
* @returns {string} the formatted page variant id
|
|
87
|
+
*/
|
|
88
|
+
static getPageVariantId(pageId, language, variantId, scope) {
|
|
89
|
+
const formattedPageId = pageId.replace(/[{}-]/g, '');
|
|
90
|
+
const formattedLanguage = language.replace('-', '_');
|
|
91
|
+
const scopeId = scope ? `${this.normalizeScope(scope)}_` : '';
|
|
92
|
+
let formattedVariantId = variantId;
|
|
93
|
+
if (!variantId || variantId === exports.DEFAULT_VARIANT) {
|
|
94
|
+
formattedVariantId = 'default';
|
|
95
|
+
}
|
|
96
|
+
return `${scopeId}${formattedPageId}_${formattedLanguage}_${formattedVariantId}`.toLowerCase();
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Gets the friendly id for (page-level) Embedded Personalization in the required format `embedded_[<scope>_]<id>_<lang>`
|
|
100
|
+
* @param {string} pageId the page id
|
|
101
|
+
* @param {string} language the language
|
|
102
|
+
* @param {string} [scope] the scope value
|
|
103
|
+
* @returns {string} the friendly id
|
|
104
|
+
*/
|
|
105
|
+
static getPageFriendlyId(pageId, language, scope) {
|
|
106
|
+
const formattedPageId = pageId.replace(/[{}-]/g, '');
|
|
107
|
+
const formattedLanguage = language.replace('-', '_');
|
|
108
|
+
const scopeId = scope ? `${this.normalizeScope(scope)}_` : '';
|
|
109
|
+
return `embedded_${scopeId}${formattedPageId}_${formattedLanguage}`.toLowerCase();
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Gets the friendly id for Component A/B Testing in the required format `component_[<scope>_]<pageId>_<componentId>_<language>*`
|
|
113
|
+
* @param {string} pageId the page id
|
|
114
|
+
* @param {string} componentId the component id
|
|
115
|
+
* @param {string} language the language
|
|
116
|
+
* @param {string} [scope] the scope value
|
|
117
|
+
* @returns {string} the friendly id
|
|
118
|
+
*/
|
|
119
|
+
static getComponentFriendlyId(pageId, componentId, language, scope) {
|
|
120
|
+
const formattedPageId = pageId.replace(/[{}-]/g, '');
|
|
121
|
+
const formattedComponentId = componentId.replace(/[{}-]/g, '');
|
|
122
|
+
const formattedLanguage = language.replace('-', '_');
|
|
123
|
+
const scopeId = scope ? `${this.normalizeScope(scope)}_` : '';
|
|
124
|
+
return `component_${scopeId}${formattedPageId}_${formattedComponentId}_${formattedLanguage}*`.toLowerCase();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Normalizes the scope from the given string value
|
|
128
|
+
* Removes all non-alphanumeric characters
|
|
129
|
+
* @param {string} [scope] the scope value
|
|
130
|
+
* @returns {string} normalized scope value
|
|
131
|
+
*/
|
|
132
|
+
static normalizeScope(scope) {
|
|
133
|
+
return (scope === null || scope === void 0 ? void 0 : scope.replace(/[^a-zA-Z0-9]+/g, '')) || '';
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.CdpHelper = CdpHelper;
|