@sitecore-jss/sitecore-jss-nextjs 21.7.0-canary.6 → 21.7.0-canary.61

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 (51) hide show
  1. package/context.d.ts +1 -0
  2. package/context.js +1 -0
  3. package/dist/cjs/components/NextImage.js +2 -10
  4. package/dist/cjs/components/RichText.js +2 -2
  5. package/dist/cjs/context/context.js +83 -0
  6. package/dist/cjs/context/index.js +5 -0
  7. package/dist/cjs/editing/editing-config-middleware.js +49 -0
  8. package/dist/cjs/editing/editing-render-middleware.js +3 -16
  9. package/dist/cjs/editing/feaas-render-middleware.js +87 -0
  10. package/dist/cjs/editing/index.js +5 -1
  11. package/dist/cjs/editing/render-middleware.js +27 -0
  12. package/dist/cjs/graphql/index.js +2 -1
  13. package/dist/cjs/index.js +6 -3
  14. package/dist/cjs/middleware/personalize-middleware.js +33 -32
  15. package/dist/cjs/middleware/redirects-middleware.js +24 -9
  16. package/dist/cjs/revalidate/index.js +5 -0
  17. package/dist/cjs/revalidate/revalidate-middleware.js +216 -0
  18. package/dist/cjs/utils/utils.js +6 -18
  19. package/dist/esm/components/NextImage.js +1 -8
  20. package/dist/esm/components/RichText.js +2 -2
  21. package/dist/esm/context/context.js +79 -0
  22. package/dist/esm/context/index.js +1 -0
  23. package/dist/esm/editing/editing-config-middleware.js +45 -0
  24. package/dist/esm/editing/editing-render-middleware.js +4 -17
  25. package/dist/esm/editing/feaas-render-middleware.js +83 -0
  26. package/dist/esm/editing/index.js +2 -0
  27. package/dist/esm/editing/render-middleware.js +23 -0
  28. package/dist/esm/graphql/index.js +1 -1
  29. package/dist/esm/index.js +4 -3
  30. package/dist/esm/middleware/personalize-middleware.js +34 -33
  31. package/dist/esm/middleware/redirects-middleware.js +24 -9
  32. package/dist/esm/revalidate/index.js +1 -0
  33. package/dist/esm/revalidate/revalidate-middleware.js +212 -0
  34. package/dist/esm/utils/utils.js +6 -15
  35. package/package.json +13 -13
  36. package/revalidate.d.ts +1 -0
  37. package/revalidate.js +1 -0
  38. package/types/components/NextImage.d.ts +1 -2
  39. package/types/context/context.d.ts +116 -0
  40. package/types/context/index.d.ts +1 -0
  41. package/types/editing/editing-config-middleware.d.ts +29 -0
  42. package/types/editing/editing-render-middleware.d.ts +2 -11
  43. package/types/editing/feaas-render-middleware.d.ts +32 -0
  44. package/types/editing/index.d.ts +2 -0
  45. package/types/editing/render-middleware.d.ts +15 -0
  46. package/types/graphql/index.d.ts +1 -1
  47. package/types/index.d.ts +4 -3
  48. package/types/middleware/personalize-middleware.d.ts +20 -15
  49. package/types/revalidate/index.d.ts +1 -0
  50. package/types/revalidate/revalidate-middleware.d.ts +115 -0
  51. package/types/utils/utils.d.ts +1 -0
@@ -8,10 +8,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { NextResponse } from 'next/server';
11
- import { GraphQLPersonalizeService, getPersonalizedRewrite, PosResolver, } from '@sitecore-jss/sitecore-jss/personalize';
11
+ import { GraphQLPersonalizeService, getPersonalizedRewrite, } from '@sitecore-jss/sitecore-jss/personalize';
12
12
  import { debug } from '@sitecore-jss/sitecore-jss';
13
13
  import { MiddlewareBase } from './middleware';
14
- import { initServer } from '@sitecore/engage';
14
+ import { init, personalize } from '@sitecore-cloudsdk/personalize/server';
15
15
  /**
16
16
  * Middleware / handler to support Sitecore Personalize
17
17
  */
@@ -23,7 +23,6 @@ export class PersonalizeMiddleware extends MiddlewareBase {
23
23
  super(config);
24
24
  this.config = config;
25
25
  this.handler = (req, res) => __awaiter(this, void 0, void 0, function* () {
26
- var _a;
27
26
  const pathname = req.nextUrl.pathname;
28
27
  const language = this.getLanguage(req);
29
28
  const hostname = this.getHostHeader(req) || this.defaultHostname;
@@ -59,30 +58,20 @@ export class PersonalizeMiddleware extends MiddlewareBase {
59
58
  debug.personalize('skipped (no personalization configured)');
60
59
  return response;
61
60
  }
62
- const engageServer = this.initializeEngageServer(hostname, site, language);
63
- // creates the browser ID cookie on the server side
64
- // and includes the cookie in the response header
65
- try {
66
- yield engageServer.handleCookie(req, response, timeout);
67
- }
68
- catch (error) {
69
- debug.personalize('skipped (browser id generation failed)');
70
- throw error;
71
- }
61
+ yield this.initPersonalizeServer({
62
+ hostname,
63
+ siteName: site.name,
64
+ request: req,
65
+ response,
66
+ });
72
67
  const params = this.getExperienceParams(req);
73
- debug.personalize('executing experience for %s %s %o', personalizeInfo.contentId, params);
74
- const personalizationData = {
75
- channel: this.config.cdpConfig.channel || 'WEB',
76
- currency: (_a = this.config.cdpConfig.currency) !== null && _a !== void 0 ? _a : 'USA',
77
- friendlyId: personalizeInfo.contentId,
78
- params,
79
- language,
80
- };
68
+ debug.personalize('executing experience for %s %o', personalizeInfo.contentId, params);
81
69
  let variantId;
82
- // Execute targeted experience in CDP
70
+ // Execute targeted experience in Personalize SDK
83
71
  // eslint-disable-next-line no-useless-catch
84
72
  try {
85
- variantId = (yield engageServer.personalize(personalizationData, req, timeout)).variantId;
73
+ const personalization = yield this.personalize({ personalizeInfo, params, language, timeout }, req);
74
+ variantId = personalization.variantId;
86
75
  }
87
76
  catch (error) {
88
77
  throw error;
@@ -129,17 +118,29 @@ export class PersonalizeMiddleware extends MiddlewareBase {
129
118
  }
130
119
  });
131
120
  }
132
- initializeEngageServer(hostName, site, language) {
133
- const engageServer = initServer({
134
- clientKey: this.config.cdpConfig.clientKey,
135
- targetURL: this.config.cdpConfig.endpoint,
136
- pointOfSale: this.config.getPointOfSale
137
- ? this.config.getPointOfSale(site, language)
138
- : PosResolver.resolve(site, language),
139
- cookieDomain: hostName,
140
- forceServerCookieMode: true,
121
+ initPersonalizeServer({ hostname, siteName, request, response, }) {
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ yield init({
124
+ sitecoreEdgeUrl: this.config.cdpConfig.sitecoreEdgeUrl,
125
+ sitecoreEdgeContextId: this.config.cdpConfig.sitecoreEdgeContextId,
126
+ siteName,
127
+ cookieDomain: hostname,
128
+ enableServerCookie: true,
129
+ }, request, response);
130
+ });
131
+ }
132
+ personalize({ params, personalizeInfo, language, timeout, }, request) {
133
+ var _a;
134
+ return __awaiter(this, void 0, void 0, function* () {
135
+ const personalizationData = {
136
+ channel: this.config.cdpConfig.channel || 'WEB',
137
+ currency: (_a = this.config.cdpConfig.currency) !== null && _a !== void 0 ? _a : 'USD',
138
+ friendlyId: personalizeInfo.contentId,
139
+ params,
140
+ language,
141
+ };
142
+ return (yield personalize(personalizationData, request, timeout));
141
143
  });
142
- return engageServer;
143
144
  }
144
145
  getExperienceParams(req) {
145
146
  const utm = {
@@ -12,7 +12,8 @@ import { NextResponse } from 'next/server';
12
12
  import { GraphQLRedirectsService, REDIRECT_TYPE_301, REDIRECT_TYPE_302, REDIRECT_TYPE_SERVER_TRANSFER, } from '@sitecore-jss/sitecore-jss/site';
13
13
  import { debug } from '@sitecore-jss/sitecore-jss';
14
14
  import { MiddlewareBase } from './middleware';
15
- const REGEXP_CONTEXT_SITE_LANG = new RegExp(/\$siteLang/, 'gi');
15
+ const REGEXP_CONTEXT_SITE_LANG = new RegExp(/\$siteLang/, 'i');
16
+ const REGEXP_ABSOLUTE_URL = new RegExp('^(?:[a-z]+:)?//', 'i');
16
17
  /**
17
18
  * Middleware / handler fetches all redirects from Sitecore instance by grapqhl service
18
19
  * compares with current url and redirects to target url
@@ -52,25 +53,35 @@ export class RedirectsMiddleware extends MiddlewareBase {
52
53
  return res || NextResponse.next();
53
54
  }
54
55
  // Find context site language and replace token
55
- if (REGEXP_CONTEXT_SITE_LANG.test(existsRedirect.target)) {
56
+ if (REGEXP_CONTEXT_SITE_LANG.test(existsRedirect.target) &&
57
+ !(REGEXP_ABSOLUTE_URL.test(existsRedirect.target) &&
58
+ existsRedirect.target.includes(hostname))) {
56
59
  existsRedirect.target = existsRedirect.target.replace(REGEXP_CONTEXT_SITE_LANG, site.language);
57
60
  }
58
61
  const url = req.nextUrl.clone();
59
- const absoluteUrlRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
60
- if (absoluteUrlRegex.test(existsRedirect.target)) {
62
+ if (REGEXP_ABSOLUTE_URL.test(existsRedirect.target)) {
61
63
  url.href = existsRedirect.target;
62
64
  url.locale = req.nextUrl.locale;
63
65
  }
64
66
  else {
67
+ const source = `${url.pathname}${url.search}`;
65
68
  url.search = existsRedirect.isQueryStringPreserved ? url.search : '';
66
69
  const urlFirstPart = existsRedirect.target.split('/')[1];
67
70
  if (this.locales.includes(urlFirstPart)) {
68
71
  url.locale = urlFirstPart;
69
72
  existsRedirect.target = existsRedirect.target.replace(`/${urlFirstPart}`, '');
70
73
  }
71
- url.pathname = url.pathname
74
+ const target = source
72
75
  .replace(regexParser(existsRedirect.pattern), existsRedirect.target)
73
- .replace(/^\/\//, '/');
76
+ .replace(/^\/\//, '/')
77
+ .split('?');
78
+ url.pathname = target[0];
79
+ if (target[1]) {
80
+ const newParams = new URLSearchParams(target[1]);
81
+ for (const [key, val] of newParams.entries()) {
82
+ url.searchParams.append(key, val);
83
+ }
84
+ }
74
85
  }
75
86
  const redirectUrl = decodeURIComponent(url.href);
76
87
  /** return Response redirect with http code of redirect type **/
@@ -135,13 +146,17 @@ export class RedirectsMiddleware extends MiddlewareBase {
135
146
  const redirects = yield this.redirectsService.fetchRedirects(siteName);
136
147
  const tragetURL = req.nextUrl.pathname;
137
148
  const targetQS = req.nextUrl.search || '';
138
- return redirects.length
139
- ? redirects.find((redirect) => {
149
+ const language = this.getLanguage(req);
150
+ const modifyRedirects = structuredClone(redirects);
151
+ return modifyRedirects.length
152
+ ? modifyRedirects.find((redirect) => {
153
+ redirect.pattern = redirect.pattern.replace(RegExp(`^[^]?/${language}/`, 'gi'), '');
140
154
  redirect.pattern = `/^\/${redirect.pattern
141
155
  .replace(/^\/|\/$/g, '')
142
156
  .replace(/^\^\/|\/\$$/g, '')
143
157
  .replace(/^\^|\$$/g, '')
144
- .replace(/\$\/gi$/g, '')}$/gi`;
158
+ .replace(/(?<!\\)\?/g, '\\?')
159
+ .replace(/\$\/gi$/g, '')}[\/]?$/gi`;
145
160
  return ((regexParser(redirect.pattern).test(tragetURL) ||
146
161
  regexParser(redirect.pattern).test(`${tragetURL}${targetQS}`) ||
147
162
  regexParser(redirect.pattern).test(`/${req.nextUrl.locale}${tragetURL}`) ||
@@ -0,0 +1 @@
1
+ export { RevalidateMiddleware } from './revalidate-middleware';
@@ -0,0 +1,212 @@
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 { I18NConfig } from 'next/dist/server/config-shared';
11
+ import { GraphQLPersonalizeService, getPersonalizedRewrite, } from '@sitecore-jss/sitecore-jss/personalize';
12
+ import { getSiteRewrite } from '@sitecore-jss/sitecore-jss/site';
13
+ import { debug } from '@sitecore-jss/sitecore-jss';
14
+ var EntityDefinition;
15
+ (function (EntityDefinition) {
16
+ EntityDefinition["LayoutData"] = "LayoutData";
17
+ EntityDefinition["Item"] = "Item";
18
+ })(EntityDefinition || (EntityDefinition = {}));
19
+ /**
20
+ * Middleware / handler for on-demand ISR (e.g. '/api/revalidate').
21
+ */
22
+ export class RevalidateMiddleware {
23
+ constructor(config) {
24
+ this.config = config;
25
+ this.handler = (req, res) => __awaiter(this, void 0, void 0, function* () {
26
+ // filter out updated paths and language from request.body
27
+ const filteredUpdates = this.getFilteredUpdates(req);
28
+ if (this.isEmpty(filteredUpdates)) {
29
+ // nothing to revalidate
30
+ return res.status(204).json({ message: 'No updates to revalidate' });
31
+ }
32
+ // extract only paths from filtered updates object
33
+ const paths = this.extractPaths(filteredUpdates);
34
+ const pathsToRevalidate = [];
35
+ // when personalization is configured and when both multiSite and personalization are configured
36
+ if (this.config.personalize) {
37
+ const personalizeInfo = yield this.getPersonalizedResults(filteredUpdates);
38
+ if (this.config.multiSite) {
39
+ this.handleMultiSitePersonalization(personalizeInfo, pathsToRevalidate, this.getPathName, this.getSiteName);
40
+ }
41
+ else {
42
+ this.handleNonMultiSitePersonalization(personalizeInfo, pathsToRevalidate, this.getPathName);
43
+ }
44
+ }
45
+ // when only multiSite is configured
46
+ if (this.config.multiSite && !this.config.personalize) {
47
+ const multiSitePaths = paths.map((path) => getSiteRewrite(this.getPathName(path), { siteName: this.getSiteName(path) }));
48
+ pathsToRevalidate.push(...multiSitePaths);
49
+ }
50
+ // when both multiSite and personalization are not configured
51
+ if (!this.config.multiSite && !this.config.personalize) {
52
+ const defaultPaths = paths.map((path) => this.getPathName(path));
53
+ pathsToRevalidate.push(...defaultPaths);
54
+ }
55
+ // when other locales are configured besides defaultLocale
56
+ if (!this.isEmpty(filteredUpdates)) {
57
+ const filteredLanguage = [...new Set(filteredUpdates.map(({ language }) => language))].join(',');
58
+ if (this.config.localePrefix) {
59
+ const language = this.config.localePrefix(filteredLanguage);
60
+ if (language) {
61
+ yield Promise.all(pathsToRevalidate.map((path) => res.revalidate(`/${language}` + path)));
62
+ }
63
+ }
64
+ }
65
+ yield Promise.all(pathsToRevalidate.map((path) => res.revalidate(path)));
66
+ debug.revalidate(`revalidated paths: ${pathsToRevalidate.join(', ')}`);
67
+ });
68
+ this.personalizeService = new GraphQLPersonalizeService({
69
+ clientFactory: config.clientFactory,
70
+ });
71
+ }
72
+ /**
73
+ * Generates a Next.js API route handler that executes a revalidation process.
74
+ * @returns The route handler function for handling Next.js API requests.
75
+ */
76
+ getHandler() {
77
+ return (req, res) => __awaiter(this, void 0, void 0, function* () {
78
+ try {
79
+ yield this.handler(req, res);
80
+ return res.status(200).json({ revalidated: true });
81
+ }
82
+ catch (error) {
83
+ console.log('Error Revalidating:');
84
+ console.log(error);
85
+ return res.status(500).json({ revalidated: false });
86
+ }
87
+ });
88
+ }
89
+ /**
90
+ * Gets personalized results for the updated paths
91
+ * @param {UpdatedPaths[]} filteredUpdates Updated paths
92
+ */
93
+ getPersonalizedResults(filteredUpdates) {
94
+ return __awaiter(this, void 0, void 0, function* () {
95
+ const personalizedResults = [];
96
+ const nonPersonalizedResults = [];
97
+ yield Promise.all(filteredUpdates.map((update) => __awaiter(this, void 0, void 0, function* () {
98
+ const siteName = this.getSiteName(update.path);
99
+ const pathName = this.getPathName(update.path);
100
+ const personalizeInfo = yield this.personalizeService.getPersonalizeInfo(pathName, update.language, siteName);
101
+ if (personalizeInfo && personalizeInfo.variantIds.length > 0) {
102
+ personalizeInfo.variantIds.forEach((variantId) => {
103
+ personalizedResults.push({
104
+ path: update.path,
105
+ variantId,
106
+ });
107
+ });
108
+ }
109
+ else {
110
+ // Collect paths without personalized info
111
+ nonPersonalizedResults.push({
112
+ path: update.path,
113
+ });
114
+ }
115
+ })));
116
+ return {
117
+ personalized: personalizedResults,
118
+ nonPersonalized: nonPersonalizedResults,
119
+ };
120
+ });
121
+ }
122
+ isEmpty(data) {
123
+ return data.length === 0;
124
+ }
125
+ /**
126
+ * Extracts the paths from the updated paths
127
+ * @param {UpdatedPaths[]} filteredUpdates Updated paths
128
+ * @returns {string[]} paths
129
+ */
130
+ extractPaths(filteredUpdates) {
131
+ return filteredUpdates.map((update) => update.path);
132
+ }
133
+ /**
134
+ * Gets the site name from the path name
135
+ * @param {string} pathname Path name
136
+ * @returns {string} site name
137
+ */
138
+ getSiteName(pathname) {
139
+ let siteName = '';
140
+ const path = pathname.endsWith('/') ? pathname : pathname + '/';
141
+ const result = path.match('(.*?)\\/');
142
+ if (result && result[1] !== '') {
143
+ siteName = result[1];
144
+ }
145
+ return siteName;
146
+ }
147
+ /**
148
+ * Gets the path name from the full path
149
+ * @param {string} fullPath Full path
150
+ * @returns {string} path name
151
+ */
152
+ getPathName(fullPath) {
153
+ const pathParts = fullPath.split('/').filter((part) => part !== '');
154
+ if (pathParts.length >= 2) {
155
+ const siteName = `/${pathParts[0]}/`;
156
+ const path = `/${pathParts.slice(1).join('/')}`;
157
+ return path.startsWith(siteName) ? path.slice(siteName.length) : path;
158
+ }
159
+ return '/';
160
+ }
161
+ extractSiteName(path) {
162
+ const siteName = path.split('/')[0];
163
+ return siteName;
164
+ }
165
+ /**
166
+ * Filters out the updated paths and language from the request body
167
+ * @param {NextApiRequest} req Next.js API request
168
+ * @returns {UpdatedPaths[]} updated paths
169
+ */
170
+ getFilteredUpdates(req) {
171
+ var _a, _b;
172
+ if (!((_a = req.body) === null || _a === void 0 ? void 0 : _a.updates) || this.isEmpty(req.body.updates)) {
173
+ return [];
174
+ }
175
+ return (_b = req.body) === null || _b === void 0 ? void 0 : _b.updates.filter((update) => update.entity_definition === EntityDefinition.LayoutData && update.entity_culture).map((update) => {
176
+ if (update.identifier === 'website/') {
177
+ return null;
178
+ }
179
+ return {
180
+ path: update.identifier,
181
+ language: update.entity_culture,
182
+ };
183
+ }).filter(Boolean);
184
+ }
185
+ handleMultiSitePersonalization(personalizeInfo, pathsToRevalidate, getPathName, getSiteName) {
186
+ if (personalizeInfo.personalized.length > 0) {
187
+ const personalizedRewrite = personalizeInfo.personalized.map((info) => {
188
+ return getPersonalizedRewrite(getSiteRewrite(getPathName(info.path), { siteName: getSiteName(info.path) }), {
189
+ variantId: info.variantId,
190
+ });
191
+ });
192
+ pathsToRevalidate.push(...personalizedRewrite);
193
+ }
194
+ if (personalizeInfo.nonPersonalized.length > 0) {
195
+ const nonPersonalizedRewrite = personalizeInfo.nonPersonalized.map((info) => {
196
+ return getSiteRewrite(getPathName(info.path), {
197
+ siteName: getSiteName(info.path),
198
+ });
199
+ });
200
+ pathsToRevalidate.push(...nonPersonalizedRewrite);
201
+ }
202
+ }
203
+ handleNonMultiSitePersonalization(personalizeInfo, pathsToRevalidate, getPathName) {
204
+ const nonMultiSitePersonalizedRewrite = personalizeInfo.personalized.map((info) => {
205
+ return getPersonalizedRewrite(getPathName(info.path), { variantId: info.variantId });
206
+ });
207
+ const nonMultiSiteNonPersonalizedRewrite = personalizeInfo.nonPersonalized.map((info) => {
208
+ return this.getPathName(info.path);
209
+ });
210
+ pathsToRevalidate.push(...nonMultiSitePersonalizedRewrite, ...nonMultiSiteNonPersonalizedRewrite);
211
+ }
212
+ }
@@ -1,4 +1,3 @@
1
- import chalk from 'chalk';
2
1
  import { isEditorActive, resetEditorChromes } from '@sitecore-jss/sitecore-jss/utils';
3
2
  /**
4
3
  * Get the publicUrl.
@@ -7,27 +6,19 @@ import { isEditorActive, resetEditorChromes } from '@sitecore-jss/sitecore-jss/u
7
6
  * VERCEL_URL is provided by Vercel in case if we are in Preview deployment (deployment based on the custom branch),
8
7
  * preview deployment has unique url, we don't know exact url.
9
8
  * Similarly, DEPLOY_URL is provided by Netlify and would give us the deploy URL
9
+ * In production non-editing environments it is desirable to use relative urls, so in that case set PUBLIC_URL = ''
10
10
  */
11
11
  export const getPublicUrl = () => {
12
- if (process.env.NETLIFY && process.env.DEPLOY_URL)
13
- return process.env.DEPLOY_URL;
14
- if (process.env.VERCEL_URL)
15
- return `https://${process.env.VERCEL_URL}`;
16
12
  let url = process.env.PUBLIC_URL;
17
13
  if (url === undefined) {
18
- console.warn(`${chalk.yellow.bold('Warning:')} An PUBLIC_URL environment variable is not defined. Falling back to http://localhost:3000.`);
14
+ if (process.env.NETLIFY && process.env.DEPLOY_URL)
15
+ return process.env.DEPLOY_URL;
16
+ if (process.env.VERCEL_URL)
17
+ return `https://${process.env.VERCEL_URL}`;
19
18
  url = 'http://localhost:3000';
20
19
  }
21
- else {
22
- try {
23
- new URL(url);
24
- }
25
- catch (error) {
26
- throw new Error(`The PUBLIC_URL environment variable '${url}' is not a valid URL.`);
27
- }
28
- }
29
20
  // Ensure no trailing slash
30
- return url.toString().replace(/\/$/, '');
21
+ return url.replace(/\/$/, '');
31
22
  };
32
23
  /**
33
24
  * Since Sitecore editors do not support Fast Refresh:
package/package.json CHANGED
@@ -1,21 +1,20 @@
1
1
  {
2
2
  "name": "@sitecore-jss/sitecore-jss-nextjs",
3
- "version": "21.7.0-canary.6",
3
+ "version": "21.7.0-canary.61",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "sideEffects": false,
7
7
  "scripts": {
8
8
  "build": "npm run clean && tsc -p tsconfig.json && tsc -p tsconfig-esm.json",
9
9
  "clean": "del-cli dist types",
10
- "lint": "eslint ./src/**/*.tsx ./src/**/*.ts",
10
+ "lint": "eslint \"./src/**/*.tsx\" \"./src/**/*.ts\"",
11
11
  "test": "mocha --require ./test/setup.js \"./src/**/*.test.ts\" \"./src/**/*.test.tsx\" --exit",
12
12
  "prepublishOnly": "npm run build",
13
13
  "coverage": "nyc npm test",
14
- "generate-docs": "npx typedoc --plugin typedoc-plugin-markdown --readme none --out ../../ref-docs/sitecore-jss-nextjs --entryPoints src/index.ts --entryPoints src/monitoring/index.ts --entryPoints src/editing/index.ts --entryPoints src/middleware/index.ts --githubPages false"
14
+ "generate-docs": "npx typedoc --plugin typedoc-plugin-markdown --readme none --out ../../ref-docs/sitecore-jss-nextjs --entryPoints src/index.ts --entryPoints src/monitoring/index.ts --entryPoints src/editing/index.ts --entryPoints src/middleware/index.ts --entryPoints src/context/index.ts --entryPoints src/utils/index.ts --entryPoints src/site/index.ts --entryPoints src/graphql/index.ts --entryPoints src/revalidate/index.ts --githubPages false"
15
15
  },
16
16
  "engines": {
17
- "node": ">=12",
18
- "npm": ">=6"
17
+ "node": ">=18"
19
18
  },
20
19
  "author": {
21
20
  "name": "Sitecore Corporation",
@@ -30,7 +29,7 @@
30
29
  "url": "https://github.com/sitecore/jss/issues"
31
30
  },
32
31
  "devDependencies": {
33
- "@sitecore/engage": "^1.4.1",
32
+ "@sitecore-cloudsdk/personalize": "^0.1.1",
34
33
  "@types/chai": "^4.3.4",
35
34
  "@types/chai-as-promised": "^7.1.5",
36
35
  "@types/chai-string": "^1.4.2",
@@ -55,7 +54,7 @@
55
54
  "eslint-plugin-react": "^7.32.1",
56
55
  "jsdom": "^21.1.0",
57
56
  "mocha": "^10.2.0",
58
- "next": "^13.4.16",
57
+ "next": "^14.1.0",
59
58
  "nock": "^13.3.0",
60
59
  "nyc": "^15.1.0",
61
60
  "react": "^18.2.0",
@@ -66,15 +65,16 @@
66
65
  "typescript": "~4.9.4"
67
66
  },
68
67
  "peerDependencies": {
69
- "@sitecore/engage": "^1.4.1",
70
- "next": "^13.4.16",
68
+ "@sitecore-cloudsdk/events": "^0.1.1",
69
+ "@sitecore-cloudsdk/personalize": "^0.1.1",
70
+ "next": "^14.1.0",
71
71
  "react": "^18.2.0",
72
72
  "react-dom": "^18.2.0"
73
73
  },
74
74
  "dependencies": {
75
- "@sitecore-jss/sitecore-jss": "^21.7.0-canary.6",
76
- "@sitecore-jss/sitecore-jss-dev-tools": "^21.7.0-canary.6",
77
- "@sitecore-jss/sitecore-jss-react": "^21.7.0-canary.6",
75
+ "@sitecore-jss/sitecore-jss": "^21.7.0-canary.61",
76
+ "@sitecore-jss/sitecore-jss-dev-tools": "^21.7.0-canary.61",
77
+ "@sitecore-jss/sitecore-jss-react": "^21.7.0-canary.61",
78
78
  "@vercel/kv": "^0.2.1",
79
79
  "node-html-parser": "^6.1.4",
80
80
  "prop-types": "^15.8.1",
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "description": "",
85
85
  "types": "types/index.d.ts",
86
- "gitHead": "3468861efc54046977809988c5a6d0745a40aacb",
86
+ "gitHead": "cc2bf3228ef6492eb9c6b2702d763ec44eaf189b",
87
87
  "files": [
88
88
  "dist",
89
89
  "types",
@@ -0,0 +1 @@
1
+ export * from './types/revalidate/index';
package/revalidate.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./dist/cjs/revalidate/index');
@@ -1,8 +1,7 @@
1
1
  /// <reference types="@types/react" />
2
2
  import React from 'react';
3
3
  import { ImageProps } from '@sitecore-jss/sitecore-jss-react';
4
- import { ImageLoader, ImageProps as NextImageProperties } from 'next/image';
4
+ import { ImageProps as NextImageProperties } from 'next/image';
5
5
  type NextImageProps = Omit<ImageProps, 'media'> & Partial<NextImageProperties>;
6
- export declare const sitecoreLoader: ImageLoader;
7
6
  export declare const NextImage: React.FC<NextImageProps>;
8
7
  export {};
@@ -0,0 +1,116 @@
1
+ import { LayoutServicePageState } from '@sitecore-jss/sitecore-jss-react';
2
+ /**
3
+ * Software Development Kit (SDK) instance
4
+ */
5
+ export type SDK<SDKType = unknown> = {
6
+ /**
7
+ * The Software Development Kit (SDK) library instance
8
+ */
9
+ sdk: SDKType;
10
+ /**
11
+ * Initializes the Software Development Kit (SDK)
12
+ */
13
+ init: (props: InitSDKProps) => Promise<void>;
14
+ };
15
+ /**
16
+ * Software Development Kits (SDKs) to be initialized
17
+ */
18
+ type SDKModulesType = Record<string, SDK>;
19
+ /**
20
+ * Properties that are passed to the Context.
21
+ */
22
+ export interface ContextInitProps {
23
+ /**
24
+ * Your Sitecore site name
25
+ */
26
+ siteName?: string;
27
+ /**
28
+ * Sitecore page state (normal, preview, edit)
29
+ */
30
+ pageState?: LayoutServicePageState;
31
+ }
32
+ /**
33
+ * Configuration that is passed to the Context.
34
+ */
35
+ export interface ContextConfig<SDKModules extends SDKModulesType> {
36
+ /**
37
+ * Your Sitecore Edge URL
38
+ */
39
+ sitecoreEdgeUrl: string;
40
+ /**
41
+ * Your Sitecore Edge Context ID
42
+ */
43
+ sitecoreEdgeContextId: string;
44
+ /**
45
+ * Your Sitecore site name
46
+ */
47
+ siteName: string;
48
+ /**
49
+ * Software Development Kits (SDKs) to be initialized
50
+ */
51
+ sdks: {
52
+ [module in keyof SDKModules]: SDKModules[module];
53
+ };
54
+ }
55
+ /**
56
+ * Properties that are passed to the Software Development Kit (SDK) initialization function.
57
+ */
58
+ type InitSDKProps = Omit<ContextConfig<SDKModulesType>, 'sdks'>;
59
+ /**
60
+ * Context instance that is used to initialize the application Context and associated Software Development Kits (SDKs).
61
+ */
62
+ export declare class Context<SDKModules extends SDKModulesType> {
63
+ protected props: ContextConfig<SDKModules>;
64
+ /**
65
+ * Indicates whether the Context and SDK(s) have been initialized
66
+ */
67
+ isInitialized: boolean;
68
+ /**
69
+ * The Sitecore Edge URL
70
+ */
71
+ readonly sitecoreEdgeUrl: string;
72
+ /**
73
+ * The Sitecore Edge Context ID
74
+ */
75
+ readonly sitecoreEdgeContextId: string;
76
+ /**
77
+ * The Sitecore site name
78
+ */
79
+ siteName: string;
80
+ /**
81
+ * Sitecore page state (normal, preview, edit)
82
+ */
83
+ pageState: LayoutServicePageState;
84
+ /**
85
+ * Software Development Kits (SDKs) to be initialized
86
+ */
87
+ readonly sdks: {
88
+ [module in keyof SDKModules]?: SDKModules[module]['sdk'];
89
+ };
90
+ /**
91
+ * Promises for the SDKs
92
+ */
93
+ protected sdkPromises: {
94
+ [module in keyof SDKModules]?: Promise<SDKModules[module]['sdk']>;
95
+ };
96
+ protected sdkErrors: {
97
+ [module in keyof SDKModules]?: string;
98
+ };
99
+ constructor(props: ContextConfig<SDKModules>);
100
+ init(props?: ContextInitProps): void;
101
+ /**
102
+ * Retrieves the Software Development Kit (SDK) instance, ensuring it is initialized before returning
103
+ *
104
+ * @param {string} name SDK name
105
+ * @returns initialized SDK
106
+ */
107
+ getSDK: <T extends keyof SDKModules>(name: T) => Promise<SDKModules[T]["sdk"]>;
108
+ /**
109
+ * Initializes the Software Development Kit (SDK)
110
+ *
111
+ * @param {T} name SDK name
112
+ * @returns {void}
113
+ */
114
+ protected initSDK<T extends keyof SDKModules>(name: T): void;
115
+ }
116
+ export {};
@@ -0,0 +1 @@
1
+ export { Context, ContextConfig, SDK } from './context';