@sitecore-content-sdk/nextjs 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.
Files changed (112) hide show
  1. package/LICENSE.txt +202 -0
  2. package/README.md +10 -0
  3. package/dist/cjs/ComponentBuilder.js +63 -0
  4. package/dist/cjs/components/BYOCWrapper.js +41 -0
  5. package/dist/cjs/components/ComponentPropsContext.js +57 -0
  6. package/dist/cjs/components/FEaaSWrapper.js +43 -0
  7. package/dist/cjs/components/Link.js +87 -0
  8. package/dist/cjs/components/NextImage.js +82 -0
  9. package/dist/cjs/components/Placeholder.js +49 -0
  10. package/dist/cjs/components/RichText.js +95 -0
  11. package/dist/cjs/editing/constants.js +10 -0
  12. package/dist/cjs/editing/editing-config-middleware.js +62 -0
  13. package/dist/cjs/editing/editing-render-middleware.js +182 -0
  14. package/dist/cjs/editing/feaas-render-middleware.js +101 -0
  15. package/dist/cjs/editing/index.js +16 -0
  16. package/dist/cjs/editing/render-middleware.js +43 -0
  17. package/dist/cjs/graphql/index.js +7 -0
  18. package/dist/cjs/index.js +119 -0
  19. package/dist/cjs/middleware/index.js +13 -0
  20. package/dist/cjs/middleware/middleware.js +97 -0
  21. package/dist/cjs/middleware/multisite-middleware.js +93 -0
  22. package/dist/cjs/middleware/personalize-middleware.js +231 -0
  23. package/dist/cjs/middleware/redirects-middleware.js +264 -0
  24. package/dist/cjs/monitoring/healthcheck-middleware.js +30 -0
  25. package/dist/cjs/monitoring/index.js +5 -0
  26. package/dist/cjs/services/base-graphql-sitemap-service.js +206 -0
  27. package/dist/cjs/services/component-props-service.js +167 -0
  28. package/dist/cjs/services/graphql-sitemap-service.js +64 -0
  29. package/dist/cjs/services/mutisite-graphql-sitemap-service.js +81 -0
  30. package/dist/cjs/sharedTypes/component-props.js +2 -0
  31. package/dist/cjs/sharedTypes/module-factory.js +2 -0
  32. package/dist/cjs/site/index.js +5 -0
  33. package/dist/cjs/utils/index.js +11 -0
  34. package/dist/cjs/utils/utils.js +42 -0
  35. package/dist/esm/ComponentBuilder.js +59 -0
  36. package/dist/esm/components/BYOCWrapper.js +36 -0
  37. package/dist/esm/components/ComponentPropsContext.js +19 -0
  38. package/dist/esm/components/FEaaSWrapper.js +38 -0
  39. package/dist/esm/components/Link.js +48 -0
  40. package/dist/esm/components/NextImage.js +76 -0
  41. package/dist/esm/components/Placeholder.js +12 -0
  42. package/dist/esm/components/RichText.js +55 -0
  43. package/dist/esm/editing/constants.js +7 -0
  44. package/dist/esm/editing/editing-config-middleware.js +58 -0
  45. package/dist/esm/editing/editing-render-middleware.js +177 -0
  46. package/dist/esm/editing/feaas-render-middleware.js +97 -0
  47. package/dist/esm/editing/index.js +5 -0
  48. package/dist/esm/editing/render-middleware.js +39 -0
  49. package/dist/esm/graphql/index.js +1 -0
  50. package/dist/esm/index.js +23 -0
  51. package/dist/esm/middleware/index.js +5 -0
  52. package/dist/esm/middleware/middleware.js +93 -0
  53. package/dist/esm/middleware/multisite-middleware.js +89 -0
  54. package/dist/esm/middleware/personalize-middleware.js +227 -0
  55. package/dist/esm/middleware/redirects-middleware.js +257 -0
  56. package/dist/esm/monitoring/healthcheck-middleware.js +26 -0
  57. package/dist/esm/monitoring/index.js +1 -0
  58. package/dist/esm/services/base-graphql-sitemap-service.js +201 -0
  59. package/dist/esm/services/component-props-service.js +160 -0
  60. package/dist/esm/services/graphql-sitemap-service.js +59 -0
  61. package/dist/esm/services/mutisite-graphql-sitemap-service.js +77 -0
  62. package/dist/esm/sharedTypes/component-props.js +1 -0
  63. package/dist/esm/sharedTypes/module-factory.js +1 -0
  64. package/dist/esm/site/index.js +1 -0
  65. package/dist/esm/utils/index.js +3 -0
  66. package/dist/esm/utils/utils.js +37 -0
  67. package/editing.d.ts +1 -0
  68. package/editing.js +1 -0
  69. package/global.d.ts +21 -0
  70. package/graphql.d.ts +1 -0
  71. package/graphql.js +1 -0
  72. package/middleware.d.ts +1 -0
  73. package/middleware.js +1 -0
  74. package/monitoring.d.ts +1 -0
  75. package/monitoring.js +1 -0
  76. package/package.json +92 -0
  77. package/site.d.ts +1 -0
  78. package/site.js +1 -0
  79. package/types/ComponentBuilder.d.ts +59 -0
  80. package/types/components/BYOCWrapper.d.ts +20 -0
  81. package/types/components/ComponentPropsContext.d.ts +18 -0
  82. package/types/components/FEaaSWrapper.d.ts +22 -0
  83. package/types/components/Link.d.ts +10 -0
  84. package/types/components/NextImage.d.ts +6 -0
  85. package/types/components/Placeholder.d.ts +8 -0
  86. package/types/components/RichText.d.ts +32 -0
  87. package/types/editing/constants.d.ts +7 -0
  88. package/types/editing/editing-config-middleware.d.ts +29 -0
  89. package/types/editing/editing-render-middleware.d.ts +79 -0
  90. package/types/editing/feaas-render-middleware.d.ts +32 -0
  91. package/types/editing/index.d.ts +5 -0
  92. package/types/editing/render-middleware.d.ts +24 -0
  93. package/types/graphql/index.d.ts +1 -0
  94. package/types/index.d.ts +24 -0
  95. package/types/middleware/index.d.ts +5 -0
  96. package/types/middleware/middleware.d.ts +82 -0
  97. package/types/middleware/multisite-middleware.d.ts +39 -0
  98. package/types/middleware/personalize-middleware.d.ts +102 -0
  99. package/types/middleware/redirects-middleware.d.ts +57 -0
  100. package/types/monitoring/healthcheck-middleware.d.ts +12 -0
  101. package/types/monitoring/index.d.ts +1 -0
  102. package/types/services/base-graphql-sitemap-service.d.ts +148 -0
  103. package/types/services/component-props-service.d.ts +81 -0
  104. package/types/services/graphql-sitemap-service.d.ts +51 -0
  105. package/types/services/mutisite-graphql-sitemap-service.d.ts +42 -0
  106. package/types/sharedTypes/component-props.d.ts +26 -0
  107. package/types/sharedTypes/module-factory.d.ts +32 -0
  108. package/types/site/index.d.ts +1 -0
  109. package/types/utils/index.d.ts +3 -0
  110. package/types/utils/utils.d.ts +8 -0
  111. package/utils.d.ts +1 -0
  112. package/utils.js +1 -0
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MultisiteMiddleware = exports.PersonalizeMiddleware = exports.RedirectsMiddleware = exports.MiddlewareBase = exports.debug = void 0;
4
+ var core_1 = require("@sitecore-content-sdk/core");
5
+ Object.defineProperty(exports, "debug", { enumerable: true, get: function () { return core_1.debug; } });
6
+ var middleware_1 = require("./middleware");
7
+ Object.defineProperty(exports, "MiddlewareBase", { enumerable: true, get: function () { return middleware_1.MiddlewareBase; } });
8
+ var redirects_middleware_1 = require("./redirects-middleware");
9
+ Object.defineProperty(exports, "RedirectsMiddleware", { enumerable: true, get: function () { return redirects_middleware_1.RedirectsMiddleware; } });
10
+ var personalize_middleware_1 = require("./personalize-middleware");
11
+ Object.defineProperty(exports, "PersonalizeMiddleware", { enumerable: true, get: function () { return personalize_middleware_1.PersonalizeMiddleware; } });
12
+ var multisite_middleware_1 = require("./multisite-middleware");
13
+ Object.defineProperty(exports, "MultisiteMiddleware", { enumerable: true, get: function () { return multisite_middleware_1.MultisiteMiddleware; } });
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MiddlewareBase = void 0;
4
+ const server_1 = require("next/server");
5
+ class MiddlewareBase {
6
+ constructor(config) {
7
+ this.config = config;
8
+ this.SITE_SYMBOL = 'sc_site';
9
+ this.REWRITE_HEADER_NAME = 'x-sc-rewrite';
10
+ this.defaultHostname = config.defaultHostname || 'localhost';
11
+ }
12
+ /**
13
+ * Determines if mode is preview
14
+ * @param {NextRequest} req request
15
+ * @returns {boolean} is preview
16
+ */
17
+ isPreview(req) {
18
+ var _a, _b;
19
+ return !!(((_a = req.cookies.get('__prerender_bypass')) === null || _a === void 0 ? void 0 : _a.value) || ((_b = req.cookies.get('__next_preview_data')) === null || _b === void 0 ? void 0 : _b.value));
20
+ }
21
+ /**
22
+ * Determines if the request is a Next.js (next/link) prefetch request
23
+ * @param {NextRequest} req request
24
+ * @returns {boolean} is prefetch
25
+ */
26
+ isPrefetch(req) {
27
+ return (
28
+ // eslint-disable-next-line prettier/prettier
29
+ req.headers.get('purpose') === 'prefetch' || req.headers.get('Next-Router-Prefetch') === '1' // Pages Router // App Router
30
+ );
31
+ }
32
+ excludeRoute(pathname) {
33
+ var _a, _b;
34
+ return (pathname.startsWith('/api/') || // Ignore Next.js API calls
35
+ pathname.startsWith('/sitecore/') || // Ignore Sitecore API calls
36
+ pathname.startsWith('/_next') || // Ignore next service calls
37
+ (((_a = this.config) === null || _a === void 0 ? void 0 : _a.excludeRoute) && ((_b = this.config) === null || _b === void 0 ? void 0 : _b.excludeRoute(pathname))));
38
+ }
39
+ /**
40
+ * Safely extract all headers for debug logging
41
+ * Necessary to avoid middleware issue https://github.com/vercel/next.js/issues/39765
42
+ * @param {Headers} incomingHeaders Incoming headers
43
+ * @returns Object with headers as key/value pairs
44
+ */
45
+ extractDebugHeaders(incomingHeaders) {
46
+ const headers = {};
47
+ incomingHeaders.forEach((value, key) => (headers[key] = value));
48
+ return headers;
49
+ }
50
+ /**
51
+ * Provides used language
52
+ * @param {NextRequest} req request
53
+ * @returns {string} language
54
+ */
55
+ getLanguage(req) {
56
+ return req.nextUrl.locale || req.nextUrl.defaultLocale || 'en';
57
+ }
58
+ /**
59
+ * Extract 'host' header
60
+ * @param {NextRequest} req request
61
+ */
62
+ getHostHeader(req) {
63
+ var _a;
64
+ return (_a = req.headers.get('host')) === null || _a === void 0 ? void 0 : _a.split(':')[0];
65
+ }
66
+ /**
67
+ * Get site information.
68
+ * Can not be used in **Preview** mode, since site will not be resolved
69
+ * @param {NextRequest} req request
70
+ * @param {NextResponse} [res] response
71
+ * @returns {SiteInfo} site information
72
+ */
73
+ getSite(req, res) {
74
+ var _a;
75
+ const siteNameCookie = (_a = res === null || res === void 0 ? void 0 : res.cookies.get(this.SITE_SYMBOL)) === null || _a === void 0 ? void 0 : _a.value;
76
+ if (siteNameCookie)
77
+ return this.config.siteResolver.getByName(siteNameCookie);
78
+ const hostname = this.getHostHeader(req) || this.defaultHostname;
79
+ return this.config.siteResolver.getByHost(hostname);
80
+ }
81
+ /**
82
+ * Create a rewrite response
83
+ * @param {string} rewritePath the destionation path
84
+ * @param {NextRequest} req the current request
85
+ * @param {NextResponse} res the current response
86
+ */
87
+ rewrite(rewritePath, req, res) {
88
+ // Note an absolute URL is required: https://nextjs.org/docs/messages/middleware-relative-urls
89
+ const rewriteUrl = req.nextUrl.clone();
90
+ rewriteUrl.pathname = rewritePath;
91
+ const response = server_1.NextResponse.rewrite(rewriteUrl, res);
92
+ // Share rewrite path with following executed middlewares
93
+ response.headers.set(this.REWRITE_HEADER_NAME, rewritePath);
94
+ return response;
95
+ }
96
+ }
97
+ exports.MiddlewareBase = MiddlewareBase;
@@ -0,0 +1,93 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MultisiteMiddleware = void 0;
13
+ const server_1 = require("next/server");
14
+ const site_1 = require("@sitecore-content-sdk/core/site");
15
+ const core_1 = require("@sitecore-content-sdk/core");
16
+ const middleware_1 = require("./middleware");
17
+ /**
18
+ * Middleware / handler for multisite support
19
+ */
20
+ class MultisiteMiddleware extends middleware_1.MiddlewareBase {
21
+ /**
22
+ * @param {MultisiteMiddlewareConfig} [config] Multisite middleware config
23
+ */
24
+ constructor(config) {
25
+ super(config);
26
+ this.config = config;
27
+ this.handler = (req, res) => __awaiter(this, void 0, void 0, function* () {
28
+ var _a;
29
+ const pathname = req.nextUrl.pathname;
30
+ const language = this.getLanguage(req);
31
+ const hostname = this.getHostHeader(req) || this.defaultHostname;
32
+ const startTimestamp = Date.now();
33
+ core_1.debug.multisite('multisite middleware start: %o', {
34
+ pathname,
35
+ language,
36
+ hostname,
37
+ });
38
+ // Response will be provided if other middleware is run before us
39
+ let response = res || server_1.NextResponse.next();
40
+ if (this.isPreview(req) || this.excludeRoute(pathname)) {
41
+ core_1.debug.multisite('skipped (%s)', this.isPreview(req) ? 'preview' : 'route excluded');
42
+ return response;
43
+ }
44
+ // Site name can be forced by query string parameter or cookie
45
+ const siteName = req.nextUrl.searchParams.get(this.SITE_SYMBOL) ||
46
+ (this.config.useCookieResolution &&
47
+ this.config.useCookieResolution(req) &&
48
+ ((_a = req.cookies.get(this.SITE_SYMBOL)) === null || _a === void 0 ? void 0 : _a.value)) ||
49
+ this.config.siteResolver.getByHost(hostname).name;
50
+ // Rewrite to site specific path
51
+ const rewritePath = (0, site_1.getSiteRewrite)(pathname, {
52
+ siteName,
53
+ });
54
+ response = this.rewrite(rewritePath, req, response);
55
+ // default site cookie attributes
56
+ const defaultCookieAttributes = {
57
+ secure: true,
58
+ httpOnly: true,
59
+ sameSite: 'none',
60
+ };
61
+ // Share site name with the following executed middlewares
62
+ response.cookies.set(this.SITE_SYMBOL, siteName, defaultCookieAttributes);
63
+ core_1.debug.multisite('multisite middleware end in %dms: %o', Date.now() - startTimestamp, {
64
+ rewritePath,
65
+ siteName,
66
+ headers: this.extractDebugHeaders(response.headers),
67
+ cookies: response.cookies,
68
+ });
69
+ return response;
70
+ });
71
+ }
72
+ /**
73
+ * Gets the Next.js middleware handler with error handling
74
+ * @returns middleware handler
75
+ */
76
+ getHandler() {
77
+ return (req, res) => __awaiter(this, void 0, void 0, function* () {
78
+ try {
79
+ return yield this.handler(req, res);
80
+ }
81
+ catch (error) {
82
+ console.log('Multisite middleware failed:');
83
+ console.log(error);
84
+ return res || server_1.NextResponse.next();
85
+ }
86
+ });
87
+ }
88
+ excludeRoute(pathname) {
89
+ // ignore files
90
+ return pathname.includes('.') || super.excludeRoute(pathname);
91
+ }
92
+ }
93
+ exports.MultisiteMiddleware = MultisiteMiddleware;
@@ -0,0 +1,231 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PersonalizeMiddleware = void 0;
13
+ const server_1 = require("next/server");
14
+ const personalize_1 = require("@sitecore-content-sdk/core/personalize");
15
+ const core_1 = require("@sitecore-content-sdk/core");
16
+ const middleware_1 = require("./middleware");
17
+ const server_2 = require("@sitecore-cloudsdk/core/server");
18
+ const server_3 = require("@sitecore-cloudsdk/personalize/server");
19
+ /**
20
+ * Middleware / handler to support Sitecore Personalize
21
+ */
22
+ class PersonalizeMiddleware extends middleware_1.MiddlewareBase {
23
+ /**
24
+ * @param {PersonalizeMiddlewareConfig} [config] Personalize middleware config
25
+ */
26
+ constructor(config) {
27
+ super(config);
28
+ this.config = config;
29
+ this.handler = (req, res) => __awaiter(this, void 0, void 0, function* () {
30
+ const pathname = req.nextUrl.pathname;
31
+ const language = this.getLanguage(req);
32
+ const hostname = this.getHostHeader(req) || this.defaultHostname;
33
+ const startTimestamp = Date.now();
34
+ const timeout = this.config.cdpConfig.timeout;
35
+ // Response will be provided if other middleware is run before us (e.g. redirects)
36
+ let response = res || server_1.NextResponse.next();
37
+ core_1.debug.personalize('personalize middleware start: %o', {
38
+ pathname,
39
+ language,
40
+ hostname,
41
+ headers: this.extractDebugHeaders(req.headers),
42
+ });
43
+ if (this.config.disabled && this.config.disabled(req, response)) {
44
+ core_1.debug.personalize('skipped (personalize middleware is disabled)');
45
+ return response;
46
+ }
47
+ if (response.redirected || // Don't attempt to personalize a redirect
48
+ this.isPreview(req) || // No need to personalize for preview (layout data is already prepared for preview)
49
+ this.excludeRoute(pathname)) {
50
+ core_1.debug.personalize('skipped (%s)', response.redirected ? 'redirected' : this.isPreview(req) ? 'preview' : 'route excluded');
51
+ return response;
52
+ }
53
+ const site = this.getSite(req, response);
54
+ // Get personalization info from Experience Edge
55
+ const personalizeInfo = yield this.personalizeService.getPersonalizeInfo(pathname, language, site.name);
56
+ if (!personalizeInfo) {
57
+ // Likely an invalid route / language
58
+ core_1.debug.personalize('skipped (personalize info not found)');
59
+ return response;
60
+ }
61
+ if (personalizeInfo.variantIds.length === 0) {
62
+ core_1.debug.personalize('skipped (no personalization configured)');
63
+ return response;
64
+ }
65
+ if (this.isPrefetch(req)) {
66
+ core_1.debug.personalize('skipped (prefetch)');
67
+ // Personalized, but this is a prefetch request.
68
+ // In this case, don't execute a personalize request; otherwise, the metrics for component A/B experiments would be inaccurate.
69
+ // Disable preflight caching to force revalidation on client-side navigation (personalization WILL be influenced).
70
+ // Note the reason we don't move this any earlier in the middleware is that we would then be sacrificing performance for non-personalized pages.
71
+ response.headers.set('x-middleware-cache', 'no-cache');
72
+ return response;
73
+ }
74
+ yield this.initPersonalizeServer({
75
+ hostname,
76
+ siteName: site.name,
77
+ request: req,
78
+ response,
79
+ });
80
+ const params = this.getExperienceParams(req);
81
+ const executions = this.getPersonalizeExecutions(personalizeInfo, language);
82
+ const identifiedVariantIds = [];
83
+ yield Promise.all(executions.map((execution) => this.personalize({
84
+ friendlyId: execution.friendlyId,
85
+ variantIds: execution.variantIds,
86
+ params,
87
+ language,
88
+ timeout,
89
+ }, req).then((personalization) => {
90
+ const variantId = personalization.variantId;
91
+ if (variantId) {
92
+ if (!execution.variantIds.includes(variantId)) {
93
+ core_1.debug.personalize('invalid variant %s', variantId);
94
+ }
95
+ else {
96
+ identifiedVariantIds.push(variantId);
97
+ }
98
+ }
99
+ })));
100
+ if (identifiedVariantIds.length === 0) {
101
+ core_1.debug.personalize('skipped (no variant(s) identified)');
102
+ return response;
103
+ }
104
+ // Path can be rewritten by previously executed middleware
105
+ const basePath = (res === null || res === void 0 ? void 0 : res.headers.get('x-sc-rewrite')) || pathname;
106
+ // Rewrite to persononalized path
107
+ const rewritePath = (0, personalize_1.getPersonalizedRewrite)(basePath, identifiedVariantIds);
108
+ response = this.rewrite(rewritePath, req, response);
109
+ // Disable preflight caching to force revalidation on client-side navigation (personalization MAY be influenced).
110
+ // See https://github.com/vercel/next.js/pull/32767
111
+ response.headers.set('x-middleware-cache', 'no-cache');
112
+ core_1.debug.personalize('personalize middleware end in %dms: %o', Date.now() - startTimestamp, {
113
+ rewritePath,
114
+ headers: this.extractDebugHeaders(response.headers),
115
+ });
116
+ return response;
117
+ });
118
+ // NOTE: we provide native fetch for compatibility on Next.js Edge Runtime
119
+ // (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
120
+ this.personalizeService = new personalize_1.GraphQLPersonalizeService(Object.assign(Object.assign({}, config.edgeConfig), { fetch: fetch }));
121
+ }
122
+ /**
123
+ * Gets the Next.js middleware handler with error handling
124
+ * @returns middleware handler
125
+ */
126
+ getHandler() {
127
+ return (req, res) => __awaiter(this, void 0, void 0, function* () {
128
+ try {
129
+ return yield this.handler(req, res);
130
+ }
131
+ catch (error) {
132
+ console.log('Personalize middleware failed:');
133
+ console.log(error);
134
+ return res || server_1.NextResponse.next();
135
+ }
136
+ });
137
+ }
138
+ initPersonalizeServer(_a) {
139
+ return __awaiter(this, arguments, void 0, function* ({ hostname, siteName, request, response, }) {
140
+ yield (0, server_2.CloudSDK)(request, response, {
141
+ sitecoreEdgeUrl: this.config.cdpConfig.sitecoreEdgeUrl,
142
+ sitecoreEdgeContextId: this.config.cdpConfig.sitecoreEdgeContextId,
143
+ siteName,
144
+ cookieDomain: hostname,
145
+ enableServerCookie: true,
146
+ })
147
+ .addPersonalize({ enablePersonalizeCookie: true })
148
+ .initialize();
149
+ });
150
+ }
151
+ personalize(_a, request_1) {
152
+ return __awaiter(this, arguments, void 0, function* ({ params, friendlyId, language, timeout, variantIds, }, request) {
153
+ var _b;
154
+ core_1.debug.personalize('executing experience for %s %o', friendlyId, params);
155
+ return (yield (0, server_3.personalize)(request, {
156
+ channel: this.config.cdpConfig.channel || 'WEB',
157
+ currency: (_b = this.config.cdpConfig.currency) !== null && _b !== void 0 ? _b : 'USD',
158
+ friendlyId,
159
+ params,
160
+ language,
161
+ pageVariantIds: variantIds,
162
+ }, { timeout }));
163
+ });
164
+ }
165
+ getExperienceParams(req) {
166
+ const utm = {
167
+ campaign: req.nextUrl.searchParams.get('utm_campaign') || undefined,
168
+ content: req.nextUrl.searchParams.get('utm_content') || undefined,
169
+ medium: req.nextUrl.searchParams.get('utm_medium') || undefined,
170
+ source: req.nextUrl.searchParams.get('utm_source') || undefined,
171
+ };
172
+ return {
173
+ // It's expected that the header name "referer" is actually a misspelling of the word "referrer"
174
+ // req.referrer is used during fetching to determine the value of the Referer header of the request being made,
175
+ // used as a fallback
176
+ referrer: req.headers.get('referer') || req.referrer,
177
+ utm: utm,
178
+ };
179
+ }
180
+ excludeRoute(pathname) {
181
+ // ignore files
182
+ return pathname.includes('.') || super.excludeRoute(pathname);
183
+ }
184
+ /**
185
+ * Aggregates personalize executions based on the provided route personalize information and language
186
+ * @param {PersonalizeInfo} personalizeInfo the route personalize information
187
+ * @param {string} language the language
188
+ * @returns An array of personalize executions
189
+ */
190
+ getPersonalizeExecutions(personalizeInfo, language) {
191
+ if (personalizeInfo.variantIds.length === 0) {
192
+ return [];
193
+ }
194
+ const results = [];
195
+ return personalizeInfo.variantIds.reduce((results, variantId) => {
196
+ if (variantId.includes('_')) {
197
+ // Component-level personalization in format "<ComponentID>_<VariantID>"
198
+ const componentId = variantId.split('_')[0];
199
+ const friendlyId = personalize_1.CdpHelper.getComponentFriendlyId(personalizeInfo.pageId, componentId, language, this.config.scope || this.config.edgeConfig.scope);
200
+ const execution = results.find((x) => x.friendlyId === friendlyId);
201
+ if (execution) {
202
+ execution.variantIds.push(variantId);
203
+ }
204
+ else {
205
+ // The default/control variant (format "<ComponentID>_default") is also a valid value returned by the execution
206
+ const defaultVariant = `${componentId}${personalize_1.DEFAULT_VARIANT}`;
207
+ results.push({
208
+ friendlyId,
209
+ variantIds: [defaultVariant, variantId],
210
+ });
211
+ }
212
+ }
213
+ else {
214
+ // Embedded (page-level) personalization in format "<VariantID>"
215
+ const friendlyId = personalize_1.CdpHelper.getPageFriendlyId(personalizeInfo.pageId, language, this.config.scope || this.config.edgeConfig.scope);
216
+ const execution = results.find((x) => x.friendlyId === friendlyId);
217
+ if (execution) {
218
+ execution.variantIds.push(variantId);
219
+ }
220
+ else {
221
+ results.push({
222
+ friendlyId,
223
+ variantIds: [variantId],
224
+ });
225
+ }
226
+ }
227
+ return results;
228
+ }, results);
229
+ }
230
+ }
231
+ exports.PersonalizeMiddleware = PersonalizeMiddleware;