@sitecore-jss/sitecore-jss-nextjs 21.7.0-canary.7 → 21.7.0-canary.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/NextImage.js +2 -10
- package/dist/cjs/components/RichText.js +2 -2
- package/dist/cjs/context/context.js +30 -10
- package/dist/cjs/editing/editing-config-middleware.js +49 -0
- package/dist/cjs/editing/editing-render-middleware.js +3 -16
- package/dist/cjs/editing/feaas-render-middleware.js +87 -0
- package/dist/cjs/editing/index.js +5 -1
- package/dist/cjs/editing/render-middleware.js +27 -0
- package/dist/cjs/graphql/index.js +2 -1
- package/dist/cjs/index.js +5 -2
- package/dist/cjs/middleware/personalize-middleware.js +1 -1
- package/dist/cjs/middleware/redirects-middleware.js +24 -10
- package/dist/cjs/revalidate/index.js +5 -0
- package/dist/cjs/revalidate/revalidate-middleware.js +216 -0
- package/dist/cjs/utils/utils.js +6 -18
- package/dist/esm/components/NextImage.js +1 -8
- package/dist/esm/components/RichText.js +2 -2
- package/dist/esm/context/context.js +30 -10
- package/dist/esm/editing/editing-config-middleware.js +45 -0
- package/dist/esm/editing/editing-render-middleware.js +4 -17
- package/dist/esm/editing/feaas-render-middleware.js +83 -0
- package/dist/esm/editing/index.js +2 -0
- package/dist/esm/editing/render-middleware.js +23 -0
- package/dist/esm/graphql/index.js +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/middleware/personalize-middleware.js +1 -1
- package/dist/esm/middleware/redirects-middleware.js +24 -10
- package/dist/esm/revalidate/index.js +1 -0
- package/dist/esm/revalidate/revalidate-middleware.js +212 -0
- package/dist/esm/utils/utils.js +6 -15
- package/package.json +10 -11
- package/revalidate.d.ts +1 -0
- package/revalidate.js +1 -0
- package/types/components/NextImage.d.ts +1 -2
- package/types/context/context.d.ts +13 -1
- package/types/editing/editing-config-middleware.d.ts +29 -0
- package/types/editing/editing-render-middleware.d.ts +2 -11
- package/types/editing/feaas-render-middleware.d.ts +32 -0
- package/types/editing/index.d.ts +2 -0
- package/types/editing/render-middleware.d.ts +15 -0
- package/types/graphql/index.d.ts +1 -1
- package/types/index.d.ts +3 -3
- package/types/revalidate/index.d.ts +1 -0
- package/types/revalidate/revalidate-middleware.d.ts +115 -0
- package/types/utils/utils.d.ts +1 -0
|
@@ -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/, '
|
|
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,34 @@ 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
|
-
|
|
60
|
-
if (absoluteUrlRegex.test(existsRedirect.target)) {
|
|
62
|
+
if (REGEXP_ABSOLUTE_URL.test(existsRedirect.target)) {
|
|
61
63
|
url.href = existsRedirect.target;
|
|
62
|
-
url.locale = req.nextUrl.locale;
|
|
63
64
|
}
|
|
64
65
|
else {
|
|
66
|
+
const source = `${url.pathname}${url.search}`;
|
|
65
67
|
url.search = existsRedirect.isQueryStringPreserved ? url.search : '';
|
|
66
68
|
const urlFirstPart = existsRedirect.target.split('/')[1];
|
|
67
69
|
if (this.locales.includes(urlFirstPart)) {
|
|
68
70
|
url.locale = urlFirstPart;
|
|
69
71
|
existsRedirect.target = existsRedirect.target.replace(`/${urlFirstPart}`, '');
|
|
70
72
|
}
|
|
71
|
-
|
|
73
|
+
const target = source
|
|
72
74
|
.replace(regexParser(existsRedirect.pattern), existsRedirect.target)
|
|
73
|
-
.replace(/^\/\//, '/')
|
|
75
|
+
.replace(/^\/\//, '/')
|
|
76
|
+
.split('?');
|
|
77
|
+
url.pathname = target[0];
|
|
78
|
+
if (target[1]) {
|
|
79
|
+
const newParams = new URLSearchParams(target[1]);
|
|
80
|
+
for (const [key, val] of newParams.entries()) {
|
|
81
|
+
url.searchParams.append(key, val);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
74
84
|
}
|
|
75
85
|
const redirectUrl = decodeURIComponent(url.href);
|
|
76
86
|
/** return Response redirect with http code of redirect type **/
|
|
@@ -135,13 +145,17 @@ export class RedirectsMiddleware extends MiddlewareBase {
|
|
|
135
145
|
const redirects = yield this.redirectsService.fetchRedirects(siteName);
|
|
136
146
|
const tragetURL = req.nextUrl.pathname;
|
|
137
147
|
const targetQS = req.nextUrl.search || '';
|
|
138
|
-
|
|
139
|
-
|
|
148
|
+
const language = this.getLanguage(req);
|
|
149
|
+
const modifyRedirects = structuredClone(redirects);
|
|
150
|
+
return modifyRedirects.length
|
|
151
|
+
? modifyRedirects.find((redirect) => {
|
|
152
|
+
redirect.pattern = redirect.pattern.replace(RegExp(`^[^]?/${language}/`, 'gi'), '');
|
|
140
153
|
redirect.pattern = `/^\/${redirect.pattern
|
|
141
154
|
.replace(/^\/|\/$/g, '')
|
|
142
155
|
.replace(/^\^\/|\/\$$/g, '')
|
|
143
156
|
.replace(/^\^|\$$/g, '')
|
|
144
|
-
.replace(
|
|
157
|
+
.replace(/(?<!\\)\?/g, '\\?')
|
|
158
|
+
.replace(/\$\/gi$/g, '')}[\/]?$/gi`;
|
|
145
159
|
return ((regexParser(redirect.pattern).test(tragetURL) ||
|
|
146
160
|
regexParser(redirect.pattern).test(`${tragetURL}${targetQS}`) ||
|
|
147
161
|
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
|
+
}
|
package/dist/esm/utils/utils.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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.
|
|
3
|
+
"version": "21.7.0-canary.70",
|
|
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 --entryPoints src/context/index.ts --entryPoints src/utils/index.ts --entryPoints src/site/index.ts --entryPoints src/graphql/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": ">=
|
|
18
|
-
"npm": ">=6"
|
|
17
|
+
"node": ">=18"
|
|
19
18
|
},
|
|
20
19
|
"author": {
|
|
21
20
|
"name": "Sitecore Corporation",
|
|
@@ -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": "^
|
|
57
|
+
"next": "^14.1.0",
|
|
59
58
|
"nock": "^13.3.0",
|
|
60
59
|
"nyc": "^15.1.0",
|
|
61
60
|
"react": "^18.2.0",
|
|
@@ -68,14 +67,14 @@
|
|
|
68
67
|
"peerDependencies": {
|
|
69
68
|
"@sitecore-cloudsdk/events": "^0.1.1",
|
|
70
69
|
"@sitecore-cloudsdk/personalize": "^0.1.1",
|
|
71
|
-
"next": "^
|
|
70
|
+
"next": "^14.1.0",
|
|
72
71
|
"react": "^18.2.0",
|
|
73
72
|
"react-dom": "^18.2.0"
|
|
74
73
|
},
|
|
75
74
|
"dependencies": {
|
|
76
|
-
"@sitecore-jss/sitecore-jss": "^21.7.0-canary.
|
|
77
|
-
"@sitecore-jss/sitecore-jss-dev-tools": "^21.7.0-canary.
|
|
78
|
-
"@sitecore-jss/sitecore-jss-react": "^21.7.0-canary.
|
|
75
|
+
"@sitecore-jss/sitecore-jss": "^21.7.0-canary.70",
|
|
76
|
+
"@sitecore-jss/sitecore-jss-dev-tools": "^21.7.0-canary.70",
|
|
77
|
+
"@sitecore-jss/sitecore-jss-react": "^21.7.0-canary.70",
|
|
79
78
|
"@vercel/kv": "^0.2.1",
|
|
80
79
|
"node-html-parser": "^6.1.4",
|
|
81
80
|
"prop-types": "^15.8.1",
|
|
@@ -84,7 +83,7 @@
|
|
|
84
83
|
},
|
|
85
84
|
"description": "",
|
|
86
85
|
"types": "types/index.d.ts",
|
|
87
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "097b4492319daf9a214181f7c6992a81ad869b03",
|
|
88
87
|
"files": [
|
|
89
88
|
"dist",
|
|
90
89
|
"types",
|
package/revalidate.d.ts
ADDED
|
@@ -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 {
|
|
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 {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LayoutServicePageState } from '@sitecore-jss/sitecore-jss-react';
|
|
1
2
|
/**
|
|
2
3
|
* Software Development Kit (SDK) instance
|
|
3
4
|
*/
|
|
@@ -23,6 +24,10 @@ export interface ContextInitProps {
|
|
|
23
24
|
* Your Sitecore site name
|
|
24
25
|
*/
|
|
25
26
|
siteName?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Sitecore page state (normal, preview, edit)
|
|
29
|
+
*/
|
|
30
|
+
pageState?: LayoutServicePageState;
|
|
26
31
|
}
|
|
27
32
|
/**
|
|
28
33
|
* Configuration that is passed to the Context.
|
|
@@ -72,6 +77,10 @@ export declare class Context<SDKModules extends SDKModulesType> {
|
|
|
72
77
|
* The Sitecore site name
|
|
73
78
|
*/
|
|
74
79
|
siteName: string;
|
|
80
|
+
/**
|
|
81
|
+
* Sitecore page state (normal, preview, edit)
|
|
82
|
+
*/
|
|
83
|
+
pageState: LayoutServicePageState;
|
|
75
84
|
/**
|
|
76
85
|
* Software Development Kits (SDKs) to be initialized
|
|
77
86
|
*/
|
|
@@ -84,6 +93,9 @@ export declare class Context<SDKModules extends SDKModulesType> {
|
|
|
84
93
|
protected sdkPromises: {
|
|
85
94
|
[module in keyof SDKModules]?: Promise<SDKModules[module]['sdk']>;
|
|
86
95
|
};
|
|
96
|
+
protected sdkErrors: {
|
|
97
|
+
[module in keyof SDKModules]?: string;
|
|
98
|
+
};
|
|
87
99
|
constructor(props: ContextConfig<SDKModules>);
|
|
88
100
|
init(props?: ContextInitProps): void;
|
|
89
101
|
/**
|
|
@@ -92,7 +104,7 @@ export declare class Context<SDKModules extends SDKModulesType> {
|
|
|
92
104
|
* @param {string} name SDK name
|
|
93
105
|
* @returns initialized SDK
|
|
94
106
|
*/
|
|
95
|
-
getSDK<T extends keyof SDKModules>(name: T)
|
|
107
|
+
getSDK: <T extends keyof SDKModules>(name: T) => Promise<SDKModules[T]["sdk"]>;
|
|
96
108
|
/**
|
|
97
109
|
* Initializes the Software Development Kit (SDK)
|
|
98
110
|
*
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
+
import { Metadata } from '@sitecore-jss/sitecore-jss-dev-tools';
|
|
3
|
+
export type EditingConfigMiddlewareConfig = {
|
|
4
|
+
/**
|
|
5
|
+
* Components available in the application
|
|
6
|
+
*/
|
|
7
|
+
components: string[] | Map<string, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Application metadata
|
|
10
|
+
*/
|
|
11
|
+
metadata: Metadata;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Middleware / handler used in the editing config API route in xmcloud add on (e.g. '/api/editing/config')
|
|
15
|
+
* provides configuration information to determine feature compatibility on Pages side.
|
|
16
|
+
*/
|
|
17
|
+
export declare class EditingConfigMiddleware {
|
|
18
|
+
protected config: EditingConfigMiddlewareConfig;
|
|
19
|
+
/**
|
|
20
|
+
* @param {EditingConfigMiddlewareConfig} [config] Editing configuration middleware config
|
|
21
|
+
*/
|
|
22
|
+
constructor(config: EditingConfigMiddlewareConfig);
|
|
23
|
+
/**
|
|
24
|
+
* Gets the Next.js API route handler
|
|
25
|
+
* @returns middleware handler
|
|
26
|
+
*/
|
|
27
|
+
getHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
|
|
28
|
+
private handler;
|
|
29
|
+
}
|
|
@@ -2,6 +2,7 @@ import { NextApiRequest, NextApiResponse } from 'next';
|
|
|
2
2
|
import { AxiosDataFetcher } from '@sitecore-jss/sitecore-jss';
|
|
3
3
|
import { EditingData } from './editing-data';
|
|
4
4
|
import { EditingDataService } from './editing-data-service';
|
|
5
|
+
import { RenderMiddlewareBase } from './render-middleware';
|
|
5
6
|
export interface EditingRenderMiddlewareConfig {
|
|
6
7
|
/**
|
|
7
8
|
* The `AxiosDataFetcher` instance to use for API requests.
|
|
@@ -41,7 +42,7 @@ export interface EditingRenderMiddlewareConfig {
|
|
|
41
42
|
* Middleware / handler for use in the editing render Next.js API route (e.g. '/api/editing/render')
|
|
42
43
|
* which is required for Sitecore editing support.
|
|
43
44
|
*/
|
|
44
|
-
export declare class EditingRenderMiddleware {
|
|
45
|
+
export declare class EditingRenderMiddleware extends RenderMiddlewareBase {
|
|
45
46
|
private editingDataService;
|
|
46
47
|
private dataFetcher;
|
|
47
48
|
private resolvePageUrl;
|
|
@@ -55,16 +56,6 @@ export declare class EditingRenderMiddleware {
|
|
|
55
56
|
* @returns route handler
|
|
56
57
|
*/
|
|
57
58
|
getHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
|
|
58
|
-
/**
|
|
59
|
-
* Gets query parameters that should be passed along to subsequent requests
|
|
60
|
-
* @param query Object of query parameters from incoming URL
|
|
61
|
-
* @returns Object of approved query parameters
|
|
62
|
-
*/
|
|
63
|
-
protected getQueryParamsForPropagation: (query: Partial<{
|
|
64
|
-
[key: string]: string | string[];
|
|
65
|
-
}>) => {
|
|
66
|
-
[key: string]: string;
|
|
67
|
-
};
|
|
68
59
|
private handler;
|
|
69
60
|
/**
|
|
70
61
|
* Default page URL resolution.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
+
import { RenderMiddlewareBase } from './render-middleware';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for `FEAASRenderMiddleware`.
|
|
5
|
+
*/
|
|
6
|
+
export interface FEAASRenderMiddlewareConfig {
|
|
7
|
+
/**
|
|
8
|
+
* Defines FEAAS page route to render.
|
|
9
|
+
* This may be necessary for certain custom Next.js routing configurations.
|
|
10
|
+
* @default /feaas/render
|
|
11
|
+
*/
|
|
12
|
+
pageUrl?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Middleware / handler for use in the feaas render Next.js API route (e.g. '/api/editing/feaas/render')
|
|
16
|
+
* which is required for Sitecore editing support.
|
|
17
|
+
*/
|
|
18
|
+
export declare class FEAASRenderMiddleware extends RenderMiddlewareBase {
|
|
19
|
+
protected config?: FEAASRenderMiddlewareConfig | undefined;
|
|
20
|
+
private pageUrl;
|
|
21
|
+
private defaultPageUrl;
|
|
22
|
+
/**
|
|
23
|
+
* @param {EditingRenderMiddlewareConfig} [config] Editing render middleware config
|
|
24
|
+
*/
|
|
25
|
+
constructor(config?: FEAASRenderMiddlewareConfig | undefined);
|
|
26
|
+
/**
|
|
27
|
+
* Gets the Next.js API route handler
|
|
28
|
+
* @returns route handler
|
|
29
|
+
*/
|
|
30
|
+
getHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
|
|
31
|
+
private handler;
|
|
32
|
+
}
|
package/types/editing/index.d.ts
CHANGED
|
@@ -4,3 +4,5 @@ export { EditingDataMiddleware, EditingDataMiddlewareConfig } from './editing-da
|
|
|
4
4
|
export { EditingRenderMiddleware, EditingRenderMiddlewareConfig, } from './editing-render-middleware';
|
|
5
5
|
export { EditingPreviewData, EditingDataService, BasicEditingDataService, BasicEditingDataServiceConfig, ServerlessEditingDataService, ServerlessEditingDataServiceConfig, editingDataService, } from './editing-data-service';
|
|
6
6
|
export { VercelEditingDataCache } from './vercel-editing-data-cache';
|
|
7
|
+
export { FEAASRenderMiddleware, FEAASRenderMiddlewareConfig } from './feaas-render-middleware';
|
|
8
|
+
export { EditingConfigMiddleware, EditingConfigMiddlewareConfig, } from './editing-config-middleware';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for middleware that handles pages and components rendering in Sitecore Editors.
|
|
3
|
+
*/
|
|
4
|
+
export declare abstract class RenderMiddlewareBase {
|
|
5
|
+
/**
|
|
6
|
+
* Gets query parameters that should be passed along to subsequent requests (e.g. for deployment protection bypass)
|
|
7
|
+
* @param {Object} query Object of query parameters from incoming URL
|
|
8
|
+
* @returns Object of approved query parameters
|
|
9
|
+
*/
|
|
10
|
+
protected getQueryParamsForPropagation: (query: Partial<{
|
|
11
|
+
[key: string]: string | string[];
|
|
12
|
+
}>) => {
|
|
13
|
+
[key: string]: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
package/types/graphql/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { GraphQLRequestClient, GraphQLRequestClientFactory, GraphQLRequestClientFactoryConfig, getEdgeProxyContentUrl, } from '@sitecore-jss/sitecore-jss/graphql';
|
|
1
|
+
export { RetryStrategy, DefaultRetryStrategy, GraphQLRequestClient, GraphQLRequestClientFactory, GraphQLRequestClientFactoryConfig, getEdgeProxyContentUrl, } from '@sitecore-jss/sitecore-jss/graphql';
|
package/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { constants, HttpDataFetcher, HttpResponse, AxiosResponse, AxiosDataFetcher, AxiosDataFetcherConfig, NativeDataFetcher, NativeDataFetcherConfig, HTMLLink, enableDebug, debug, } from '@sitecore-jss/sitecore-jss';
|
|
1
|
+
export { constants, HttpDataFetcher, HttpResponse, AxiosResponse, AxiosDataFetcher, AxiosDataFetcherConfig, ClientError, NativeDataFetcher, NativeDataFetcherConfig, HTMLLink, enableDebug, debug, } from '@sitecore-jss/sitecore-jss';
|
|
2
2
|
import { GraphQLRequestClient as GraphQLRequestClientDep } from './graphql';
|
|
3
3
|
import { resolveUrl as resolveUrlDep } from '@sitecore-jss/sitecore-jss/utils';
|
|
4
4
|
/** @deprecated use import from '@sitecore-jss/sitecore-jss-nextjs/utils' instead */
|
|
@@ -8,7 +8,7 @@ declare const GraphQLRequestClient: typeof GraphQLRequestClientDep;
|
|
|
8
8
|
export { GraphQLRequestClient };
|
|
9
9
|
export { handleEditorFastRefresh, getPublicUrl };
|
|
10
10
|
export { isEditorActive, resetEditorChromes, resolveUrl, tryParseEnvValue };
|
|
11
|
-
export { LayoutService, LayoutServiceData, LayoutServicePageState, LayoutServiceContext, LayoutServiceContextData, GraphQLLayoutService, GraphQLLayoutServiceConfig, RestLayoutService, RestLayoutServiceConfig, PlaceholderData, PlaceholdersData, RouteData, Field, Item, HtmlElementRendering, getChildPlaceholder, getFieldValue, ComponentRendering, ComponentFields, ComponentParams, RenderingType, EDITING_COMPONENT_PLACEHOLDER, EDITING_COMPONENT_ID, } from '@sitecore-jss/sitecore-jss/layout';
|
|
11
|
+
export { LayoutService, LayoutServiceData, LayoutServicePageState, LayoutServiceContext, LayoutServiceContextData, GraphQLLayoutService, GraphQLLayoutServiceConfig, RestLayoutService, RestLayoutServiceConfig, PlaceholderData, PlaceholdersData, RouteData, Field, Item, HtmlElementRendering, getChildPlaceholder, getFieldValue, ComponentRendering, ComponentFields, ComponentParams, RenderingType, EDITING_COMPONENT_PLACEHOLDER, EDITING_COMPONENT_ID, getContentStylesheetLink, } from '@sitecore-jss/sitecore-jss/layout';
|
|
12
12
|
export { mediaApi } from '@sitecore-jss/sitecore-jss/media';
|
|
13
13
|
export { trackingApi, TrackingRequestOptions, CampaignInstance, GoalInstance, OutcomeInstance, EventInstance, PageViewInstance, } from '@sitecore-jss/sitecore-jss/tracking';
|
|
14
14
|
export { DictionaryPhrases, DictionaryService, GraphQLDictionaryService, GraphQLDictionaryServiceConfig, RestDictionaryService, RestDictionaryServiceConfig, } from '@sitecore-jss/sitecore-jss/i18n';
|
|
@@ -33,4 +33,4 @@ export { FEaaSWrapper };
|
|
|
33
33
|
export { BYOCWrapper };
|
|
34
34
|
export { ComponentBuilder, ComponentBuilderConfig } from './ComponentBuilder';
|
|
35
35
|
export { Context, ContextConfig, SDK } from './context';
|
|
36
|
-
export { ComponentFactory, Image, ImageField, ImageFieldValue, ImageProps, LinkField, LinkFieldValue, Text, TextField, DateField, EditFrame, FEaaSComponent, FEaaSComponentProps, FEaaSComponentParams, fetchFEaaSComponentServerProps, BYOCComponentParams, BYOCComponent, BYOCComponentProps, getFEAASLibraryStylesheetLinks, File, FileField, RichTextField, VisitorIdentification, PlaceholderComponentProps, SitecoreContext, SitecoreContextState, SitecoreContextValue, SitecoreContextReactContext, withSitecoreContext, useSitecoreContext, withEditorChromes, withPlaceholder, withDatasourceCheck, ImageSizeParameters, ComponentConsumerProps, WithSitecoreContextOptions, WithSitecoreContextProps, } from '@sitecore-jss/sitecore-jss-react';
|
|
36
|
+
export { ComponentFactory, Image, ImageField, ImageFieldValue, ImageProps, LinkField, LinkFieldValue, Text, TextField, DateField, EditFrame, FEaaSComponent, FEaaSComponentProps, FEaaSComponentParams, fetchFEaaSComponentServerProps, BYOCComponentParams, BYOCComponent, BYOCComponentProps, getFEAASLibraryStylesheetLinks, getComponentLibraryStylesheetLinks, File, FileField, RichTextField, VisitorIdentification, PlaceholderComponentProps, SitecoreContext, SitecoreContextState, SitecoreContextValue, SitecoreContextReactContext, withSitecoreContext, useSitecoreContext, withEditorChromes, withPlaceholder, withDatasourceCheck, ImageSizeParameters, ComponentConsumerProps, WithSitecoreContextOptions, WithSitecoreContextProps, } from '@sitecore-jss/sitecore-jss-react';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RevalidateMiddleware } from './revalidate-middleware';
|