@sitecore-content-sdk/nextjs 1.3.0-canary.9 → 1.4.0-canary.2

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 (234) hide show
  1. package/README.md +11 -11
  2. package/dist/cjs/client/index.js +10 -10
  3. package/dist/cjs/client/models.js +2 -2
  4. package/dist/cjs/client/sitecore-nextjs-client.js +160 -156
  5. package/dist/cjs/components/BYOCWrapper.js +31 -30
  6. package/dist/cjs/components/ComponentPropsContext.js +66 -59
  7. package/dist/cjs/components/FEaaSWrapper.js +33 -32
  8. package/dist/cjs/components/Link.js +117 -90
  9. package/dist/cjs/components/NextImage.js +66 -62
  10. package/dist/cjs/components/Placeholder.js +55 -50
  11. package/dist/cjs/components/RichText.js +133 -128
  12. package/dist/cjs/config/define-config.js +26 -25
  13. package/dist/cjs/config/index.js +5 -5
  14. package/dist/cjs/config-cli/define-cli-config.js +40 -39
  15. package/dist/cjs/config-cli/index.js +5 -5
  16. package/dist/cjs/editing/codegen/import-map.js +129 -118
  17. package/dist/cjs/editing/codegen/index.js +6 -6
  18. package/dist/cjs/editing/constants.js +10 -10
  19. package/dist/cjs/editing/editing-config-middleware.js +70 -69
  20. package/dist/cjs/editing/editing-render-middleware.js +145 -144
  21. package/dist/cjs/editing/feaas-render-middleware.js +102 -101
  22. package/dist/cjs/editing/index.js +19 -19
  23. package/dist/cjs/editing/render-middleware.js +46 -46
  24. package/dist/cjs/editing/utils.js +260 -257
  25. package/dist/cjs/index.js +132 -131
  26. package/dist/cjs/middleware/app-router-multisite-middleware.js +41 -20
  27. package/dist/cjs/middleware/index.js +30 -30
  28. package/dist/cjs/middleware/locale-middleware.js +85 -84
  29. package/dist/cjs/middleware/middleware.js +195 -192
  30. package/dist/cjs/middleware/multisite-middleware.js +141 -118
  31. package/dist/cjs/middleware/personalize-middleware.js +240 -236
  32. package/dist/cjs/middleware/redirects-middleware.js +323 -297
  33. package/dist/cjs/middleware/robots-middleware.js +45 -44
  34. package/dist/cjs/middleware/sitemap-middleware.js +50 -49
  35. package/dist/cjs/monitoring/healthcheck-middleware.js +31 -30
  36. package/dist/cjs/monitoring/index.js +5 -5
  37. package/dist/cjs/route-handler/editing-config-route-handler.js +110 -106
  38. package/dist/cjs/route-handler/editing-render-route-handler.js +270 -165
  39. package/dist/cjs/route-handler/index.js +11 -11
  40. package/dist/cjs/route-handler/robots-route-handler.js +69 -68
  41. package/dist/cjs/route-handler/sitemap-route-handler.js +66 -65
  42. package/dist/cjs/search/index.js +17 -0
  43. package/dist/cjs/services/component-props-service.js +142 -138
  44. package/dist/cjs/sharedTypes/component-props.js +2 -2
  45. package/dist/cjs/sharedTypes/sitecore-page-props.js +2 -2
  46. package/dist/cjs/site/index.js +5 -5
  47. package/dist/cjs/tools/codegen/import-map.js +15 -0
  48. package/dist/cjs/tools/component-props.loader.js +95 -95
  49. package/dist/cjs/tools/generate-map.js +317 -317
  50. package/dist/cjs/tools/index.js +14 -13
  51. package/dist/cjs/tools/templating/byoc-component.js +36 -36
  52. package/dist/cjs/tools/templating/constants.js +7 -7
  53. package/dist/cjs/tools/templating/default-component.js +35 -35
  54. package/dist/cjs/tools/templating/utils.js +200 -0
  55. package/dist/cjs/utils/index.js +14 -14
  56. package/dist/cjs/utils/utils.js +82 -73
  57. package/dist/esm/client/index.js +2 -2
  58. package/dist/esm/client/models.js +1 -1
  59. package/dist/esm/client/sitecore-nextjs-client.js +156 -152
  60. package/dist/esm/components/BYOCWrapper.js +27 -26
  61. package/dist/esm/components/ComponentPropsContext.js +28 -21
  62. package/dist/esm/components/FEaaSWrapper.js +29 -28
  63. package/dist/esm/components/Link.js +78 -51
  64. package/dist/esm/components/NextImage.js +60 -56
  65. package/dist/esm/components/Placeholder.js +18 -13
  66. package/dist/esm/components/RichText.js +96 -91
  67. package/dist/esm/config/define-config.js +21 -20
  68. package/dist/esm/config/index.js +1 -1
  69. package/dist/esm/config-cli/define-cli-config.js +36 -35
  70. package/dist/esm/config-cli/index.js +1 -1
  71. package/dist/esm/editing/codegen/import-map.js +92 -81
  72. package/dist/esm/editing/codegen/index.js +1 -1
  73. package/dist/esm/editing/constants.js +7 -7
  74. package/dist/esm/editing/editing-config-middleware.js +66 -65
  75. package/dist/esm/editing/editing-render-middleware.js +141 -140
  76. package/dist/esm/editing/feaas-render-middleware.js +98 -97
  77. package/dist/esm/editing/index.js +6 -6
  78. package/dist/esm/editing/render-middleware.js +42 -42
  79. package/dist/esm/editing/utils.js +246 -243
  80. package/dist/esm/index.js +25 -25
  81. package/dist/esm/middleware/app-router-multisite-middleware.js +37 -16
  82. package/dist/esm/middleware/index.js +11 -11
  83. package/dist/esm/middleware/locale-middleware.js +81 -80
  84. package/dist/esm/middleware/middleware.js +189 -186
  85. package/dist/esm/middleware/multisite-middleware.js +137 -114
  86. package/dist/esm/middleware/personalize-middleware.js +236 -232
  87. package/dist/esm/middleware/redirects-middleware.js +316 -290
  88. package/dist/esm/middleware/robots-middleware.js +41 -40
  89. package/dist/esm/middleware/sitemap-middleware.js +46 -45
  90. package/dist/esm/monitoring/healthcheck-middleware.js +27 -26
  91. package/dist/esm/monitoring/index.js +1 -1
  92. package/dist/esm/route-handler/editing-config-route-handler.js +106 -102
  93. package/dist/esm/route-handler/editing-render-route-handler.js +265 -160
  94. package/dist/esm/route-handler/index.js +4 -4
  95. package/dist/esm/route-handler/robots-route-handler.js +65 -64
  96. package/dist/esm/route-handler/sitemap-route-handler.js +63 -62
  97. package/dist/esm/search/index.js +1 -0
  98. package/dist/esm/services/component-props-service.js +135 -131
  99. package/dist/esm/sharedTypes/component-props.js +1 -1
  100. package/dist/esm/sharedTypes/sitecore-page-props.js +1 -1
  101. package/dist/esm/site/index.js +1 -1
  102. package/dist/esm/tools/codegen/import-map.js +11 -0
  103. package/dist/esm/tools/component-props.loader.js +59 -59
  104. package/dist/esm/tools/generate-map.js +279 -279
  105. package/dist/esm/tools/index.js +3 -2
  106. package/dist/esm/tools/templating/byoc-component.js +30 -30
  107. package/dist/esm/tools/templating/constants.js +4 -4
  108. package/dist/esm/tools/templating/default-component.js +29 -29
  109. package/dist/esm/tools/templating/utils.js +190 -0
  110. package/dist/esm/utils/index.js +3 -3
  111. package/dist/esm/utils/utils.js +74 -65
  112. package/package.json +87 -13
  113. package/search.d.ts +1 -0
  114. package/types/client/index.d.ts +3 -2
  115. package/types/client/index.d.ts.map +1 -0
  116. package/types/client/models.d.ts +9 -8
  117. package/types/client/models.d.ts.map +1 -0
  118. package/types/client/sitecore-nextjs-client.d.ts +68 -63
  119. package/types/client/sitecore-nextjs-client.d.ts.map +1 -0
  120. package/types/components/BYOCWrapper.d.ts +16 -14
  121. package/types/components/BYOCWrapper.d.ts.map +1 -0
  122. package/types/components/ComponentPropsContext.d.ts +30 -18
  123. package/types/components/ComponentPropsContext.d.ts.map +1 -0
  124. package/types/components/FEaaSWrapper.d.ts +17 -15
  125. package/types/components/FEaaSWrapper.d.ts.map +1 -0
  126. package/types/components/Link.d.ts +25 -15
  127. package/types/components/Link.d.ts.map +1 -0
  128. package/types/components/NextImage.d.ts +11 -6
  129. package/types/components/NextImage.d.ts.map +1 -0
  130. package/types/components/Placeholder.d.ts +14 -8
  131. package/types/components/Placeholder.d.ts.map +1 -0
  132. package/types/components/RichText.d.ts +35 -25
  133. package/types/components/RichText.d.ts.map +1 -0
  134. package/types/config/define-config.d.ts +42 -38
  135. package/types/config/define-config.d.ts.map +1 -0
  136. package/types/config/index.d.ts +2 -1
  137. package/types/config/index.d.ts.map +1 -0
  138. package/types/config-cli/define-cli-config.d.ts +10 -8
  139. package/types/config-cli/define-cli-config.d.ts.map +1 -0
  140. package/types/config-cli/index.d.ts +2 -1
  141. package/types/config-cli/index.d.ts.map +1 -0
  142. package/types/editing/codegen/import-map.d.ts +15 -3
  143. package/types/editing/codegen/import-map.d.ts.map +1 -0
  144. package/types/editing/codegen/index.d.ts +3 -2
  145. package/types/editing/codegen/index.d.ts.map +1 -0
  146. package/types/editing/constants.d.ts +8 -7
  147. package/types/editing/constants.d.ts.map +1 -0
  148. package/types/editing/editing-config-middleware.d.ts +37 -31
  149. package/types/editing/editing-config-middleware.d.ts.map +1 -0
  150. package/types/editing/editing-render-middleware.d.ts +47 -44
  151. package/types/editing/editing-render-middleware.d.ts.map +1 -0
  152. package/types/editing/feaas-render-middleware.d.ts +35 -32
  153. package/types/editing/feaas-render-middleware.d.ts.map +1 -0
  154. package/types/editing/index.d.ts +7 -6
  155. package/types/editing/index.d.ts.map +1 -0
  156. package/types/editing/render-middleware.d.ts +26 -25
  157. package/types/editing/render-middleware.d.ts.map +1 -0
  158. package/types/editing/utils.d.ts +110 -106
  159. package/types/editing/utils.d.ts.map +1 -0
  160. package/types/index.d.ts +25 -24
  161. package/types/index.d.ts.map +1 -0
  162. package/types/middleware/app-router-multisite-middleware.d.ts +28 -13
  163. package/types/middleware/app-router-multisite-middleware.d.ts.map +1 -0
  164. package/types/middleware/index.d.ts +12 -11
  165. package/types/middleware/index.d.ts.map +1 -0
  166. package/types/middleware/locale-middleware.d.ts +35 -32
  167. package/types/middleware/locale-middleware.d.ts.map +1 -0
  168. package/types/middleware/middleware.d.ts +135 -127
  169. package/types/middleware/middleware.d.ts.map +1 -0
  170. package/types/middleware/multisite-middleware.d.ts +54 -37
  171. package/types/middleware/multisite-middleware.d.ts.map +1 -0
  172. package/types/middleware/personalize-middleware.d.ts +81 -65
  173. package/types/middleware/personalize-middleware.d.ts.map +1 -0
  174. package/types/middleware/redirects-middleware.d.ts +68 -65
  175. package/types/middleware/redirects-middleware.d.ts.map +1 -0
  176. package/types/middleware/robots-middleware.d.ts +15 -13
  177. package/types/middleware/robots-middleware.d.ts.map +1 -0
  178. package/types/middleware/sitemap-middleware.d.ts +16 -14
  179. package/types/middleware/sitemap-middleware.d.ts.map +1 -0
  180. package/types/monitoring/healthcheck-middleware.d.ts +14 -12
  181. package/types/monitoring/healthcheck-middleware.d.ts.map +1 -0
  182. package/types/monitoring/index.d.ts +2 -1
  183. package/types/monitoring/index.d.ts.map +1 -0
  184. package/types/route-handler/editing-config-route-handler.d.ts +30 -24
  185. package/types/route-handler/editing-config-route-handler.d.ts.map +1 -0
  186. package/types/route-handler/editing-render-route-handler.d.ts +33 -25
  187. package/types/route-handler/editing-render-route-handler.d.ts.map +1 -0
  188. package/types/route-handler/index.d.ts +5 -4
  189. package/types/route-handler/index.d.ts.map +1 -0
  190. package/types/route-handler/robots-route-handler.d.ts +30 -28
  191. package/types/route-handler/robots-route-handler.d.ts.map +1 -0
  192. package/types/route-handler/sitemap-route-handler.d.ts +30 -28
  193. package/types/route-handler/sitemap-route-handler.d.ts.map +1 -0
  194. package/types/search/index.d.ts +2 -0
  195. package/types/search/index.d.ts.map +1 -0
  196. package/types/services/component-props-service.d.ts +62 -57
  197. package/types/services/component-props-service.d.ts.map +1 -0
  198. package/types/sharedTypes/component-props.d.ts +62 -47
  199. package/types/sharedTypes/component-props.d.ts.map +1 -0
  200. package/types/sharedTypes/sitecore-page-props.d.ts +14 -9
  201. package/types/sharedTypes/sitecore-page-props.d.ts.map +1 -0
  202. package/types/site/index.d.ts +2 -1
  203. package/types/site/index.d.ts.map +1 -0
  204. package/types/tools/codegen/import-map.d.ts +10 -0
  205. package/types/tools/codegen/import-map.d.ts.map +1 -0
  206. package/types/tools/component-props.loader.d.ts +8 -7
  207. package/types/tools/component-props.loader.d.ts.map +1 -0
  208. package/types/tools/generate-map.d.ts +26 -24
  209. package/types/tools/generate-map.d.ts.map +1 -0
  210. package/types/tools/index.d.ts +4 -2
  211. package/types/tools/index.d.ts.map +1 -0
  212. package/types/tools/templating/byoc-component.d.ts +3 -2
  213. package/types/tools/templating/byoc-component.d.ts.map +1 -0
  214. package/types/tools/templating/constants.d.ts +5 -4
  215. package/types/tools/templating/constants.d.ts.map +1 -0
  216. package/types/tools/templating/default-component.d.ts +3 -2
  217. package/types/tools/templating/default-component.d.ts.map +1 -0
  218. package/types/tools/templating/utils.d.ts +44 -0
  219. package/types/tools/templating/utils.d.ts.map +1 -0
  220. package/types/utils/index.d.ts +4 -3
  221. package/types/utils/index.d.ts.map +1 -0
  222. package/types/utils/utils.d.ts +34 -24
  223. package/types/utils/utils.d.ts.map +1 -0
  224. package/client.js +0 -1
  225. package/codegen.js +0 -1
  226. package/config-cli.js +0 -1
  227. package/config.js +0 -1
  228. package/editing.js +0 -1
  229. package/middleware.js +0 -1
  230. package/monitoring.js +0 -1
  231. package/route-handler.js +0 -1
  232. package/site.js +0 -1
  233. package/tools.js +0 -1
  234. package/utils.js +0 -1
@@ -1,236 +1,240 @@
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 personalize_1 = require("@sitecore-content-sdk/core/personalize");
14
- const core_1 = require("@sitecore-content-sdk/core");
15
- const middleware_1 = require("./middleware");
16
- const server_1 = require("@sitecore-cloudsdk/core/server");
17
- const server_2 = require("@sitecore-cloudsdk/personalize/server");
18
- /**
19
- * Middleware / handler to support Sitecore Personalize
20
- */
21
- class PersonalizeMiddleware extends middleware_1.MiddlewareBase {
22
- /**
23
- * @param {PersonalizeMiddlewareConfig} [config] Personalize middleware config
24
- */
25
- constructor(config) {
26
- var _a;
27
- super(config);
28
- this.config = config;
29
- this.handle = (req, res) => __awaiter(this, void 0, void 0, function* () {
30
- if (!this.config.enabled) {
31
- core_1.debug.personalize('skipped (personalize middleware is disabled globally)');
32
- return res;
33
- }
34
- try {
35
- const pathname = req.nextUrl.pathname;
36
- const language = this.getLanguage(req, res);
37
- const hostname = this.getHostHeader(req) || this.defaultHostname;
38
- const startTimestamp = Date.now();
39
- const cdpTimeout = this.config.cdpTimeout;
40
- core_1.debug.personalize('personalize middleware start: %o', {
41
- pathname,
42
- language,
43
- hostname,
44
- headers: this.extractDebugHeaders(req.headers),
45
- });
46
- if (this.disabled(req, res)) {
47
- core_1.debug.personalize('skipped (personalize middleware is disabled)');
48
- return res;
49
- }
50
- if (res.redirected || // Don't attempt to personalize a redirect
51
- this.isPreview(req) // No need to personalize for preview (layout data is already prepared for preview)
52
- ) {
53
- core_1.debug.personalize('skipped (%s)', res.redirected ? 'redirected' : 'preview');
54
- return res;
55
- }
56
- const site = this.getSite(req, res);
57
- // Get personalization info from Experience Edge
58
- const personalizeInfo = yield this.personalizeService.getPersonalizeInfo(pathname, language, site.name);
59
- if (!personalizeInfo) {
60
- // Likely an invalid route / language
61
- core_1.debug.personalize('skipped (personalize info not found)');
62
- return res;
63
- }
64
- if (personalizeInfo.variantIds.length === 0) {
65
- core_1.debug.personalize('skipped (no personalization configured)');
66
- return res;
67
- }
68
- if (this.isPrefetch(req)) {
69
- core_1.debug.personalize('skipped (prefetch)');
70
- // Personalized, but this is a prefetch request.
71
- // In this case, don't execute a personalize request; otherwise, the metrics for component A/B experiments would be inaccurate.
72
- // Disable preflight caching to force revalidation on client-side navigation (personalization WILL be influenced).
73
- // 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.
74
- res.headers.set('x-middleware-cache', 'no-cache');
75
- res.headers.set('Cache-Control', 'no-store, must-revalidate');
76
- return res;
77
- }
78
- yield this.initPersonalizeServer({
79
- hostname,
80
- siteName: site.name,
81
- request: req,
82
- response: res,
83
- });
84
- const params = this.getExperienceParams(req);
85
- const executions = this.getPersonalizeExecutions(personalizeInfo, language);
86
- const identifiedVariantIds = [];
87
- yield Promise.all(executions.map((execution) => this.personalize({
88
- friendlyId: execution.friendlyId,
89
- variantIds: execution.variantIds,
90
- params,
91
- language,
92
- timeout: cdpTimeout,
93
- }, req).then((personalization) => {
94
- const variantId = personalization.variantId;
95
- if (variantId) {
96
- if (!execution.variantIds.includes(variantId)) {
97
- core_1.debug.personalize('invalid variant %s', variantId);
98
- }
99
- else {
100
- identifiedVariantIds.push(variantId);
101
- }
102
- }
103
- })));
104
- if (identifiedVariantIds.length === 0) {
105
- core_1.debug.personalize('skipped (no variant(s) identified)');
106
- return res;
107
- }
108
- // Path can be rewritten by previously executed middleware
109
- const basePath = (res === null || res === void 0 ? void 0 : res.headers.get(middleware_1.REWRITE_HEADER_NAME)) || pathname;
110
- // Rewrite to persononalized path
111
- const rewritePath = (0, personalize_1.getPersonalizedRewrite)(basePath, identifiedVariantIds);
112
- const response = this.rewrite(rewritePath, req, res);
113
- // Disable preflight caching to force revalidation on client-side navigation (personalization MAY be influenced).
114
- // See https://github.com/vercel/next.js/pull/32767
115
- response.headers.set('x-middleware-cache', 'no-cache');
116
- core_1.debug.personalize('personalize middleware end in %dms: %o', Date.now() - startTimestamp, {
117
- rewritePath,
118
- headers: this.extractDebugHeaders(response.headers),
119
- });
120
- return response;
121
- }
122
- catch (error) {
123
- console.log('Personalize middleware failed:');
124
- console.log(error);
125
- return res;
126
- }
127
- });
128
- const graphQLOptions = {
129
- api: {
130
- edge: {
131
- contextId: this.config.contextId,
132
- clientContextId: this.config.clientContextId,
133
- edgeUrl: this.config.edgeUrl,
134
- },
135
- },
136
- };
137
- // NOTE: we provide native fetch for compatibility on Next.js Edge Runtime
138
- // (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
139
- this.personalizeService =
140
- (_a = this.config.personalizeService) !== null && _a !== void 0 ? _a : new personalize_1.PersonalizeService({
141
- clientFactory: this.getClientFactory(graphQLOptions),
142
- timeout: this.config.edgeTimeout,
143
- scope: this.config.scope,
144
- fetch: fetch,
145
- });
146
- }
147
- getExperienceParams(req) {
148
- const extraParams = this.config.getExtraUtmParams ? this.config.getExtraUtmParams(req) : {};
149
- const utm = Object.assign({ campaign: req.nextUrl.searchParams.get('utm_campaign') || undefined, content: req.nextUrl.searchParams.get('utm_content') || undefined, medium: req.nextUrl.searchParams.get('utm_medium') || undefined, source: req.nextUrl.searchParams.get('utm_source') || undefined }, extraParams);
150
- return {
151
- // It's expected that the header name "referer" is actually a misspelling of the word "referrer"
152
- // req.referrer is used during fetching to determine the value of the Referer header of the request being made,
153
- // used as a fallback
154
- referrer: req.headers.get('referer') || req.referrer,
155
- utm,
156
- };
157
- }
158
- disabled(req, res) {
159
- // ignore files
160
- return req.nextUrl.pathname.includes('.') || super.disabled(req, res);
161
- }
162
- initPersonalizeServer(_a) {
163
- return __awaiter(this, arguments, void 0, function* ({ hostname, siteName, request, response, }) {
164
- yield (0, server_1.CloudSDK)(request, response, {
165
- sitecoreEdgeUrl: this.config.edgeUrl,
166
- sitecoreEdgeContextId: this.config.contextId,
167
- siteName,
168
- cookieDomain: hostname,
169
- enableServerCookie: true,
170
- })
171
- .addPersonalize({ enablePersonalizeCookie: true })
172
- .initialize();
173
- });
174
- }
175
- personalize(_a, request_1) {
176
- return __awaiter(this, arguments, void 0, function* ({ params, friendlyId, language, timeout, variantIds, }, request) {
177
- var _b;
178
- core_1.debug.personalize('executing experience for %s %o', friendlyId, params);
179
- return (yield (0, server_2.personalize)(request, {
180
- channel: this.config.channel || 'WEB',
181
- currency: (_b = this.config.currency) !== null && _b !== void 0 ? _b : 'USD',
182
- friendlyId,
183
- params,
184
- language,
185
- pageVariantIds: variantIds,
186
- }, { timeout }));
187
- });
188
- }
189
- /**
190
- * Aggregates personalize executions based on the provided route personalize information and language
191
- * @param {PersonalizeInfo} personalizeInfo the route personalize information
192
- * @param {string} language the language
193
- * @returns An array of personalize executions
194
- */
195
- getPersonalizeExecutions(personalizeInfo, language) {
196
- if (personalizeInfo.variantIds.length === 0) {
197
- return [];
198
- }
199
- const results = [];
200
- return personalizeInfo.variantIds.reduce((results, variantId) => {
201
- if (variantId.includes('_')) {
202
- // Component-level personalization in format "<ComponentID>_<VariantID>"
203
- const componentId = variantId.split('_')[0];
204
- const friendlyId = personalize_1.CdpHelper.getComponentFriendlyId(personalizeInfo.pageId, componentId, language, this.config.scope);
205
- const execution = results.find((x) => x.friendlyId === friendlyId);
206
- if (execution) {
207
- execution.variantIds.push(variantId);
208
- }
209
- else {
210
- // The default/control variant (format "<ComponentID>_default") is also a valid value returned by the execution
211
- const defaultVariant = `${componentId}${personalize_1.DEFAULT_VARIANT}`;
212
- results.push({
213
- friendlyId,
214
- variantIds: [defaultVariant, variantId],
215
- });
216
- }
217
- }
218
- else {
219
- // Embedded (page-level) personalization in format "<VariantID>"
220
- const friendlyId = personalize_1.CdpHelper.getPageFriendlyId(personalizeInfo.pageId, language, this.config.scope);
221
- const execution = results.find((x) => x.friendlyId === friendlyId);
222
- if (execution) {
223
- execution.variantIds.push(variantId);
224
- }
225
- else {
226
- results.push({
227
- friendlyId,
228
- variantIds: [variantId],
229
- });
230
- }
231
- }
232
- return results;
233
- }, results);
234
- }
235
- }
236
- exports.PersonalizeMiddleware = PersonalizeMiddleware;
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 personalize_1 = require("@sitecore-content-sdk/core/personalize");
14
+ const core_1 = require("@sitecore-content-sdk/core");
15
+ const middleware_1 = require("./middleware");
16
+ const server_1 = require("@sitecore-cloudsdk/core/server");
17
+ const server_2 = require("@sitecore-cloudsdk/personalize/server");
18
+ /**
19
+ * Middleware / handler to support Sitecore Personalize
20
+ * @public
21
+ */
22
+ class PersonalizeMiddleware extends middleware_1.MiddlewareBase {
23
+ /**
24
+ * @param {PersonalizeMiddlewareConfig} [config] Personalize middleware config
25
+ */
26
+ constructor(config) {
27
+ var _a;
28
+ super(config);
29
+ this.config = config;
30
+ this.handle = (req, res) => __awaiter(this, void 0, void 0, function* () {
31
+ // Skip if service wasn't initialized (no edge config)
32
+ if (!this.personalizeService) {
33
+ core_1.debug.personalize('skipped (personalize service not configured - edge config required)');
34
+ return res;
35
+ }
36
+ if (!this.config.enabled) {
37
+ core_1.debug.personalize('skipped (personalize middleware is disabled globally)');
38
+ return res;
39
+ }
40
+ try {
41
+ const pathname = req.nextUrl.pathname;
42
+ const language = this.getLanguage(req, res);
43
+ const hostname = this.getHostHeader(req) || this.defaultHostname;
44
+ const startTimestamp = Date.now();
45
+ const cdpTimeout = this.config.cdpTimeout;
46
+ const geo = this.config.extractGeoDataCb
47
+ ? yield this.config.extractGeoDataCb(req)
48
+ : undefined;
49
+ core_1.debug.personalize('personalize middleware start: %o', Object.assign(Object.assign({ pathname,
50
+ language,
51
+ hostname }, (geo && { geo })), { headers: this.extractDebugHeaders(req.headers) }));
52
+ if (this.disabled(req, res)) {
53
+ core_1.debug.personalize('skipped (personalize middleware is disabled)');
54
+ return res;
55
+ }
56
+ if (res.redirected || // Don't attempt to personalize a redirect
57
+ this.isPreview(req) // No need to personalize for preview (layout data is already prepared for preview)
58
+ ) {
59
+ core_1.debug.personalize('skipped (%s)', res.redirected ? 'redirected' : 'preview');
60
+ return res;
61
+ }
62
+ const site = this.getSite(req, res);
63
+ // Get personalization info from Experience Edge
64
+ const personalizeInfo = yield this.personalizeService.getPersonalizeInfo(pathname, language, site.name);
65
+ if (!personalizeInfo) {
66
+ // Likely an invalid route / language
67
+ core_1.debug.personalize('skipped (personalize info not found)');
68
+ return res;
69
+ }
70
+ if (personalizeInfo.variantIds.length === 0) {
71
+ core_1.debug.personalize('skipped (no personalization configured)');
72
+ return res;
73
+ }
74
+ if (this.isPrefetch(req)) {
75
+ core_1.debug.personalize('skipped (prefetch)');
76
+ // Personalized, but this is a prefetch request.
77
+ // In this case, don't execute a personalize request; otherwise, the metrics for component A/B experiments would be inaccurate.
78
+ // Disable preflight caching to force revalidation on client-side navigation (personalization WILL be influenced).
79
+ // 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.
80
+ res.headers.set('x-middleware-cache', 'no-cache');
81
+ res.headers.set('Cache-Control', 'no-store, must-revalidate');
82
+ return res;
83
+ }
84
+ yield this.initPersonalizeServer({
85
+ hostname,
86
+ siteName: site.name,
87
+ request: req,
88
+ response: res,
89
+ });
90
+ const params = this.getExperienceParams(req);
91
+ const executions = this.getPersonalizeExecutions(personalizeInfo, language);
92
+ const identifiedVariantIds = [];
93
+ yield Promise.all(executions.map((execution) => this.personalize(Object.assign({ friendlyId: execution.friendlyId, variantIds: execution.variantIds, params,
94
+ language, timeout: cdpTimeout }, (geo && { geo })), req).then((personalization) => {
95
+ const variantId = personalization.variantId;
96
+ if (variantId) {
97
+ if (!execution.variantIds.includes(variantId)) {
98
+ core_1.debug.personalize('invalid variant %s', variantId);
99
+ }
100
+ else {
101
+ identifiedVariantIds.push(variantId);
102
+ }
103
+ }
104
+ })));
105
+ if (identifiedVariantIds.length === 0) {
106
+ core_1.debug.personalize('skipped (no variant(s) identified)');
107
+ return res;
108
+ }
109
+ // Path can be rewritten by previously executed middleware
110
+ const basePath = (res === null || res === void 0 ? void 0 : res.headers.get(middleware_1.REWRITE_HEADER_NAME)) || pathname;
111
+ // Rewrite to persononalized path
112
+ const rewritePath = (0, personalize_1.getPersonalizedRewrite)(basePath, identifiedVariantIds);
113
+ const response = this.rewrite(rewritePath, req, res);
114
+ // Disable preflight caching to force revalidation on client-side navigation (personalization MAY be influenced).
115
+ // See https://github.com/vercel/next.js/pull/32767
116
+ response.headers.set('x-middleware-cache', 'no-cache');
117
+ core_1.debug.personalize('personalize middleware end in %dms: %o', Date.now() - startTimestamp, {
118
+ rewritePath,
119
+ headers: this.extractDebugHeaders(response.headers),
120
+ });
121
+ return response;
122
+ }
123
+ catch (error) {
124
+ console.log('Personalize middleware failed:');
125
+ console.log(error);
126
+ return res;
127
+ }
128
+ });
129
+ // Validate edge config is present - personalize requires Edge platform
130
+ if (!this.config.contextId && !this.config.clientContextId) {
131
+ console.warn('[PersonalizeMiddleware] Personalize middleware requires Edge configuration (contextId/clientContextId). ' +
132
+ 'Personalize features will be disabled. This is expected in local container development.');
133
+ // Set to null to indicate service is disabled
134
+ this.personalizeService = null;
135
+ return;
136
+ }
137
+ const graphQLOptions = {
138
+ api: {
139
+ edge: {
140
+ contextId: this.config.contextId,
141
+ clientContextId: this.config.clientContextId,
142
+ edgeUrl: this.config.edgeUrl,
143
+ },
144
+ },
145
+ };
146
+ // NOTE: we provide native fetch for compatibility on Next.js Edge Runtime
147
+ // (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
148
+ this.personalizeService =
149
+ (_a = this.config.personalizeService) !== null && _a !== void 0 ? _a : new personalize_1.PersonalizeService({
150
+ clientFactory: this.getClientFactory(graphQLOptions),
151
+ timeout: this.config.edgeTimeout,
152
+ scope: this.config.scope,
153
+ fetch: fetch,
154
+ });
155
+ }
156
+ getExperienceParams(req) {
157
+ const extraParams = this.config.getExtraUtmParams ? this.config.getExtraUtmParams(req) : {};
158
+ const utm = Object.assign({ campaign: req.nextUrl.searchParams.get('utm_campaign') || undefined, content: req.nextUrl.searchParams.get('utm_content') || undefined, medium: req.nextUrl.searchParams.get('utm_medium') || undefined, source: req.nextUrl.searchParams.get('utm_source') || undefined }, extraParams);
159
+ return {
160
+ // It's expected that the header name "referer" is actually a misspelling of the word "referrer"
161
+ // req.referrer is used during fetching to determine the value of the Referer header of the request being made,
162
+ // used as a fallback
163
+ referrer: req.headers.get('referer') || req.referrer,
164
+ utm,
165
+ };
166
+ }
167
+ disabled(req, res) {
168
+ // ignore files
169
+ return req.nextUrl.pathname.includes('.') || super.disabled(req, res);
170
+ }
171
+ initPersonalizeServer(_a) {
172
+ return __awaiter(this, arguments, void 0, function* ({ hostname, siteName, request, response, }) {
173
+ yield (0, server_1.CloudSDK)(request, response, {
174
+ sitecoreEdgeUrl: this.config.edgeUrl,
175
+ sitecoreEdgeContextId: this.config.contextId,
176
+ siteName,
177
+ cookieDomain: hostname,
178
+ enableServerCookie: true,
179
+ })
180
+ .addPersonalize({ enablePersonalizeCookie: true })
181
+ .initialize();
182
+ });
183
+ }
184
+ personalize(_a, request_1) {
185
+ return __awaiter(this, arguments, void 0, function* ({ params, friendlyId, language, timeout, variantIds, geo, }, request) {
186
+ var _b;
187
+ core_1.debug.personalize('executing experience for %s %o', friendlyId, params);
188
+ return (yield (0, server_2.personalize)(request, Object.assign({ channel: this.config.channel || 'WEB', currency: (_b = this.config.currency) !== null && _b !== void 0 ? _b : 'USD', friendlyId,
189
+ params,
190
+ language, pageVariantIds: variantIds }, (geo && { geo })), { timeout }));
191
+ });
192
+ }
193
+ /**
194
+ * Aggregates personalize executions based on the provided route personalize information and language
195
+ * @param {PersonalizeInfo} personalizeInfo the route personalize information
196
+ * @param {string} language the language
197
+ * @returns An array of personalize executions
198
+ */
199
+ getPersonalizeExecutions(personalizeInfo, language) {
200
+ if (personalizeInfo.variantIds.length === 0) {
201
+ return [];
202
+ }
203
+ const results = [];
204
+ return personalizeInfo.variantIds.reduce((results, variantId) => {
205
+ if (variantId.includes('_')) {
206
+ // Component-level personalization in format "<ComponentID>_<VariantID>"
207
+ const componentId = variantId.split('_')[0];
208
+ const friendlyId = personalize_1.CdpHelper.getComponentFriendlyId(personalizeInfo.pageId, componentId, language, this.config.scope);
209
+ const execution = results.find((x) => x.friendlyId === friendlyId);
210
+ if (execution) {
211
+ execution.variantIds.push(variantId);
212
+ }
213
+ else {
214
+ // The default/control variant (format "<ComponentID>_default") is also a valid value returned by the execution
215
+ const defaultVariant = `${componentId}${personalize_1.DEFAULT_VARIANT}`;
216
+ results.push({
217
+ friendlyId,
218
+ variantIds: [defaultVariant, variantId],
219
+ });
220
+ }
221
+ }
222
+ else {
223
+ // Embedded (page-level) personalization in format "<VariantID>"
224
+ const friendlyId = personalize_1.CdpHelper.getPageFriendlyId(personalizeInfo.pageId, language, this.config.scope);
225
+ const execution = results.find((x) => x.friendlyId === friendlyId);
226
+ if (execution) {
227
+ execution.variantIds.push(variantId);
228
+ }
229
+ else {
230
+ results.push({
231
+ friendlyId,
232
+ variantIds: [variantId],
233
+ });
234
+ }
235
+ }
236
+ return results;
237
+ }, results);
238
+ }
239
+ }
240
+ exports.PersonalizeMiddleware = PersonalizeMiddleware;