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