@sitecore-jss/sitecore-jss-nextjs 22.4.0-canary.1 → 22.4.0-canary.10
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/editing/editing-data-service.js +1 -1
- package/dist/cjs/editing/editing-render-middleware.js +57 -22
- package/dist/cjs/editing/index.js +6 -1
- package/dist/cjs/editing/render-middleware.js +8 -6
- package/dist/cjs/index.js +5 -3
- package/dist/cjs/middleware/redirects-middleware.js +53 -81
- package/dist/esm/editing/editing-data-service.js +2 -2
- package/dist/esm/editing/editing-render-middleware.js +57 -23
- package/dist/esm/editing/index.js +2 -1
- package/dist/esm/editing/render-middleware.js +8 -6
- package/dist/esm/index.js +3 -2
- package/dist/esm/middleware/redirects-middleware.js +54 -82
- package/package.json +5 -5
- package/types/editing/editing-data-service.d.ts +5 -5
- package/types/editing/editing-render-middleware.d.ts +28 -7
- package/types/editing/index.d.ts +2 -1
- package/types/editing/render-middleware.d.ts +1 -1
- package/types/index.d.ts +3 -2
- package/types/middleware/redirects-middleware.d.ts +0 -11
|
@@ -90,7 +90,7 @@ class ServerlessEditingDataService {
|
|
|
90
90
|
if (!this.apiRoute.includes('[key]')) {
|
|
91
91
|
throw new Error(`The specified apiRoute '${this.apiRoute}' is missing '[key]'.`);
|
|
92
92
|
}
|
|
93
|
-
this.dataFetcher = (_b = config === null || config === void 0 ? void 0 : config.dataFetcher) !== null && _b !== void 0 ? _b : new sitecore_jss_1.
|
|
93
|
+
this.dataFetcher = (_b = config === null || config === void 0 ? void 0 : config.dataFetcher) !== null && _b !== void 0 ? _b : new sitecore_jss_1.NativeDataFetcher({ debugger: sitecore_jss_1.debug.editing });
|
|
94
94
|
}
|
|
95
95
|
/**
|
|
96
96
|
* Stores Sitecore editor payload data for later retrieval by key
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.EditingRenderMiddleware = exports.MetadataHandler = exports.isEditingMetadataPreviewData = exports.ChromesHandler = void 0;
|
|
12
|
+
exports.EditingRenderMiddleware = exports.MetadataHandler = exports.isComponentLibraryPreviewData = exports.isEditingMetadataPreviewData = exports.ChromesHandler = void 0;
|
|
13
13
|
const constants_1 = require("next/constants");
|
|
14
14
|
const sitecore_jss_1 = require("@sitecore-jss/sitecore-jss");
|
|
15
15
|
const layout_1 = require("@sitecore-jss/sitecore-jss/layout");
|
|
@@ -52,7 +52,7 @@ class ChromesHandler extends render_middleware_1.RenderMiddlewareBase {
|
|
|
52
52
|
return `${process.env.VERCEL ? 'https' : 'http'}://${req.headers.host}`;
|
|
53
53
|
};
|
|
54
54
|
this.editingDataService = (_a = config === null || config === void 0 ? void 0 : config.editingDataService) !== null && _a !== void 0 ? _a : editing_data_service_1.editingDataService;
|
|
55
|
-
this.dataFetcher = (_b = config === null || config === void 0 ? void 0 : config.dataFetcher) !== null && _b !== void 0 ? _b : new sitecore_jss_1.
|
|
55
|
+
this.dataFetcher = (_b = config === null || config === void 0 ? void 0 : config.dataFetcher) !== null && _b !== void 0 ? _b : new sitecore_jss_1.NativeDataFetcher({ debugger: sitecore_jss_1.debug.editing });
|
|
56
56
|
this.resolvePageUrl = (_c = config === null || config === void 0 ? void 0 : config.resolvePageUrl) !== null && _c !== void 0 ? _c : this.defaultResolvePageUrl;
|
|
57
57
|
this.resolveServerUrl = (_d = config === null || config === void 0 ? void 0 : config.resolveServerUrl) !== null && _d !== void 0 ? _d : this.defaultResolveServerUrl;
|
|
58
58
|
}
|
|
@@ -79,7 +79,7 @@ class ChromesHandler extends render_middleware_1.RenderMiddlewareBase {
|
|
|
79
79
|
const cookies = res.getHeader('Set-Cookie');
|
|
80
80
|
headers.cookie = `${headers.cookie ? headers.cookie + ';' : ''}${cookies.join(';')}`;
|
|
81
81
|
// Make actual render request for page route, passing on preview cookies as well as any approved query string parameters.
|
|
82
|
-
// Note timestamp effectively disables caching the request
|
|
82
|
+
// Note timestamp effectively disables caching the request (no amount of cache headers seemed to do it)
|
|
83
83
|
sitecore_jss_1.debug.editing('fetching page route for %s', editingData.path);
|
|
84
84
|
const requestUrl = new URL(this.resolvePageUrl({ serverUrl, itemPath: editingData.path }));
|
|
85
85
|
for (const key in params) {
|
|
@@ -125,8 +125,7 @@ class ChromesHandler extends render_middleware_1.RenderMiddlewareBase {
|
|
|
125
125
|
catch (err) {
|
|
126
126
|
const error = err;
|
|
127
127
|
console.error(error);
|
|
128
|
-
if (error.response
|
|
129
|
-
// Axios error, which could mean the server or page URL isn't quite right, so provide a more helpful hint
|
|
128
|
+
if (error.response) {
|
|
130
129
|
console.info(
|
|
131
130
|
// eslint-disable-next-line quotes
|
|
132
131
|
"Hint: for non-standard server or Next.js route configurations, you may need to override the 'resolveServerUrl' or 'resolvePageUrl' available on the 'EditingRenderMiddleware' config.");
|
|
@@ -184,6 +183,19 @@ const isEditingMetadataPreviewData = (data) => {
|
|
|
184
183
|
data.editMode === layout_1.EditMode.Metadata);
|
|
185
184
|
};
|
|
186
185
|
exports.isEditingMetadataPreviewData = isEditingMetadataPreviewData;
|
|
186
|
+
/**
|
|
187
|
+
* Type guard for Component Library mode
|
|
188
|
+
* @param {object} data preview data to check
|
|
189
|
+
* @returns true if the data is EditingMetadataPreviewData
|
|
190
|
+
* @see EditingMetadataPreviewData
|
|
191
|
+
*/
|
|
192
|
+
const isComponentLibraryPreviewData = (data) => {
|
|
193
|
+
return (typeof data === 'object' &&
|
|
194
|
+
data !== null &&
|
|
195
|
+
'mode' in data &&
|
|
196
|
+
data.mode === 'library');
|
|
197
|
+
};
|
|
198
|
+
exports.isComponentLibraryPreviewData = isComponentLibraryPreviewData;
|
|
187
199
|
/**
|
|
188
200
|
* Handler for the Editing Metadata GET requests.
|
|
189
201
|
* This handler is responsible for redirecting the request to the page route.
|
|
@@ -197,13 +209,17 @@ class MetadataHandler {
|
|
|
197
209
|
var _a, _b, _c;
|
|
198
210
|
const { query } = req;
|
|
199
211
|
const startTimestamp = Date.now();
|
|
200
|
-
const
|
|
212
|
+
const mode = query.mode;
|
|
213
|
+
const metadataDefaultRequiredParams = ['sc_site', 'sc_itemid', 'sc_lang', 'route', 'mode'];
|
|
214
|
+
const metadataComponentRequiredParams = [
|
|
201
215
|
'sc_site',
|
|
202
216
|
'sc_itemid',
|
|
217
|
+
'sc_renderingId',
|
|
218
|
+
'sc_uid',
|
|
203
219
|
'sc_lang',
|
|
204
|
-
'route',
|
|
205
220
|
'mode',
|
|
206
221
|
];
|
|
222
|
+
const requiredQueryParams = mode === 'library' ? metadataComponentRequiredParams : metadataDefaultRequiredParams;
|
|
207
223
|
const missingQueryParams = requiredQueryParams.filter((param) => !query[param]);
|
|
208
224
|
// Validate query parameters
|
|
209
225
|
if (missingQueryParams.length) {
|
|
@@ -212,21 +228,40 @@ class MetadataHandler {
|
|
|
212
228
|
html: `<html><body>Missing required query parameters: ${missingQueryParams.join(', ')}</body></html>`,
|
|
213
229
|
});
|
|
214
230
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
231
|
+
if (mode === 'library') {
|
|
232
|
+
// dedicated route and layout to SSR component library
|
|
233
|
+
query.route = '/component-library/render';
|
|
234
|
+
res.setPreviewData({
|
|
235
|
+
itemId: query.sc_itemid,
|
|
236
|
+
componentUid: query.sc_uid,
|
|
237
|
+
renderingId: query.sc_renderingId,
|
|
238
|
+
language: query.sc_lang,
|
|
239
|
+
site: query.sc_site,
|
|
240
|
+
pageState: layout_1.LayoutServicePageState.Normal,
|
|
241
|
+
mode: 'library',
|
|
242
|
+
dataSourceId: query.sc_datasourceId,
|
|
243
|
+
version: query.sc_version,
|
|
244
|
+
}, {
|
|
245
|
+
maxAge: 3,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
res.setPreviewData({
|
|
250
|
+
site: query.sc_site,
|
|
251
|
+
itemId: query.sc_itemid,
|
|
252
|
+
language: query.sc_lang,
|
|
253
|
+
// for sc_variantId we may employ multiple variants (page-layout + component level)
|
|
254
|
+
variantIds: ((_a = query.sc_variant) === null || _a === void 0 ? void 0 : _a.split(',')) || [personalize_1.DEFAULT_VARIANT],
|
|
255
|
+
version: query.sc_version,
|
|
256
|
+
editMode: layout_1.EditMode.Metadata,
|
|
257
|
+
pageState: query.mode,
|
|
258
|
+
layoutKind: query.sc_layoutKind,
|
|
259
|
+
},
|
|
260
|
+
// Cache the preview data for 3 seconds to ensure the page is rendered with the correct preview data not the cached one
|
|
261
|
+
{
|
|
262
|
+
maxAge: 3,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
230
265
|
// Cookies with the SameSite=Lax policy set by Next.js setPreviewData function causes CORS issue
|
|
231
266
|
// when Next.js preview mode is activated, resulting the page to render in normal mode instead.
|
|
232
267
|
// By replacing it with "SameSite=None; Secure", we ensure cookies are correctly sent with
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EditingConfigMiddleware = exports.FEAASRenderMiddleware = exports.VercelEditingDataCache = exports.editingDataService = exports.ServerlessEditingDataService = exports.BasicEditingDataService = exports.isEditingMetadataPreviewData = exports.EditingRenderMiddleware = exports.EditingDataMiddleware = exports.EditingDataDiskCache = exports.GraphQLEditingService = void 0;
|
|
3
|
+
exports.EDITING_COMPONENT_ID = exports.EDITING_COMPONENT_PLACEHOLDER = exports.RenderingType = exports.EditingConfigMiddleware = exports.FEAASRenderMiddleware = exports.VercelEditingDataCache = exports.editingDataService = exports.ServerlessEditingDataService = exports.BasicEditingDataService = exports.isComponentLibraryPreviewData = exports.isEditingMetadataPreviewData = exports.EditingRenderMiddleware = exports.EditingDataMiddleware = exports.EditingDataDiskCache = exports.GraphQLEditingService = void 0;
|
|
4
4
|
var editing_1 = require("@sitecore-jss/sitecore-jss/editing");
|
|
5
5
|
Object.defineProperty(exports, "GraphQLEditingService", { enumerable: true, get: function () { return editing_1.GraphQLEditingService; } });
|
|
6
6
|
var editing_data_cache_1 = require("./editing-data-cache");
|
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "EditingDataMiddleware", { enumerable: true, get:
|
|
|
10
10
|
var editing_render_middleware_1 = require("./editing-render-middleware");
|
|
11
11
|
Object.defineProperty(exports, "EditingRenderMiddleware", { enumerable: true, get: function () { return editing_render_middleware_1.EditingRenderMiddleware; } });
|
|
12
12
|
Object.defineProperty(exports, "isEditingMetadataPreviewData", { enumerable: true, get: function () { return editing_render_middleware_1.isEditingMetadataPreviewData; } });
|
|
13
|
+
Object.defineProperty(exports, "isComponentLibraryPreviewData", { enumerable: true, get: function () { return editing_render_middleware_1.isComponentLibraryPreviewData; } });
|
|
13
14
|
var editing_data_service_1 = require("./editing-data-service");
|
|
14
15
|
Object.defineProperty(exports, "BasicEditingDataService", { enumerable: true, get: function () { return editing_data_service_1.BasicEditingDataService; } });
|
|
15
16
|
Object.defineProperty(exports, "ServerlessEditingDataService", { enumerable: true, get: function () { return editing_data_service_1.ServerlessEditingDataService; } });
|
|
@@ -20,3 +21,7 @@ var feaas_render_middleware_1 = require("./feaas-render-middleware");
|
|
|
20
21
|
Object.defineProperty(exports, "FEAASRenderMiddleware", { enumerable: true, get: function () { return feaas_render_middleware_1.FEAASRenderMiddleware; } });
|
|
21
22
|
var editing_config_middleware_1 = require("./editing-config-middleware");
|
|
22
23
|
Object.defineProperty(exports, "EditingConfigMiddleware", { enumerable: true, get: function () { return editing_config_middleware_1.EditingConfigMiddleware; } });
|
|
24
|
+
var layout_1 = require("@sitecore-jss/sitecore-jss/layout");
|
|
25
|
+
Object.defineProperty(exports, "RenderingType", { enumerable: true, get: function () { return layout_1.RenderingType; } });
|
|
26
|
+
Object.defineProperty(exports, "EDITING_COMPONENT_PLACEHOLDER", { enumerable: true, get: function () { return layout_1.EDITING_COMPONENT_PLACEHOLDER; } });
|
|
27
|
+
Object.defineProperty(exports, "EDITING_COMPONENT_ID", { enumerable: true, get: function () { return layout_1.EDITING_COMPONENT_ID; } });
|
|
@@ -28,13 +28,15 @@ class RenderMiddlewareBase {
|
|
|
28
28
|
* @returns Object of approved headers
|
|
29
29
|
*/
|
|
30
30
|
this.getHeadersForPropagation = (headers) => {
|
|
31
|
-
|
|
32
|
-
constants_1.EDITING_PASS_THROUGH_HEADERS.
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
// Filter and normalize headers
|
|
32
|
+
const filteredHeaders = constants_1.EDITING_PASS_THROUGH_HEADERS.reduce((acc, header) => {
|
|
33
|
+
const value = headers[header];
|
|
34
|
+
if (value) {
|
|
35
|
+
acc[header] = Array.isArray(value) ? value.join(', ') : value;
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
return acc;
|
|
38
|
+
}, {});
|
|
39
|
+
return filteredHeaders;
|
|
38
40
|
};
|
|
39
41
|
}
|
|
40
42
|
}
|
package/dist/cjs/index.js
CHANGED
|
@@ -23,11 +23,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.FEaaSComponent = exports.EditFrame = exports.DateField = exports.Text = exports.Image = exports.ComponentBuilder = exports.BYOCWrapper = exports.FEaaSWrapper = exports.NextImage = exports.Placeholder = exports.RichText = exports.Link = exports.useComponentProps = exports.ComponentPropsContext = exports.ComponentPropsReactContext = exports.normalizeSiteRewrite = exports.getSiteRewriteData = exports.getSiteRewrite = exports.GraphQLSiteInfoService = exports.SiteResolver = exports.GraphQLRobotsService = exports.GraphQLErrorPagesService = exports.GraphQLSitemapXmlService = exports.MultisiteGraphQLSitemapService = exports.GraphQLSitemapService = exports.DisconnectedSitemapService = exports.ComponentPropsService = exports.CdpHelper = exports.normalizePersonalizedRewrite = exports.getGroomedVariantIds = exports.getPersonalizedRewriteData = exports.getPersonalizedRewrite = exports.personalizeLayout = exports.RestDictionaryService = exports.GraphQLDictionaryService = exports.trackingApi = exports.mediaApi = exports.EditMode = exports.getContentStylesheetLink = exports.getFieldValue = exports.getChildPlaceholder = exports.RestLayoutService = exports.GraphQLLayoutService = exports.LayoutServicePageState = exports.MemoryCacheClient = exports.debug = exports.enableDebug = exports.NativeDataFetcher = exports.
|
|
27
|
-
exports.EditingScripts = exports.withEmptyFieldEditingComponent = exports.withFieldMetadata = exports.withDatasourceCheck = exports.withPlaceholder = exports.withEditorChromes = exports.useSitecoreContext = exports.withSitecoreContext = exports.SitecoreContextReactContext = exports.SitecoreContext = exports.VisitorIdentification = exports.DefaultEmptyFieldEditingComponentText = exports.DefaultEmptyFieldEditingComponentImage = exports.File = exports.getComponentLibraryStylesheetLinks = exports.BYOCComponent = exports.fetchFEaaSComponentServerProps = void 0;
|
|
26
|
+
exports.FEaaSComponent = exports.EditFrame = exports.DateField = exports.Text = exports.Image = exports.ComponentBuilder = exports.BYOCWrapper = exports.FEaaSWrapper = exports.NextImage = exports.Placeholder = exports.RichText = exports.Link = exports.useComponentProps = exports.ComponentPropsContext = exports.ComponentPropsReactContext = exports.normalizeSiteRewrite = exports.getSiteRewriteData = exports.getSiteRewrite = exports.GraphQLSiteInfoService = exports.SiteResolver = exports.GraphQLRobotsService = exports.GraphQLErrorPagesService = exports.GraphQLSitemapXmlService = exports.MultisiteGraphQLSitemapService = exports.GraphQLSitemapService = exports.DisconnectedSitemapService = exports.ComponentPropsService = exports.CdpHelper = exports.normalizePersonalizedRewrite = exports.getGroomedVariantIds = exports.getPersonalizedRewriteData = exports.getPersonalizedRewrite = exports.personalizeLayout = exports.RestDictionaryService = exports.GraphQLDictionaryService = exports.trackingApi = exports.mediaApi = exports.RestComponentLayoutService = exports.EditMode = exports.getContentStylesheetLink = exports.getFieldValue = exports.getChildPlaceholder = exports.RestLayoutService = exports.GraphQLLayoutService = exports.LayoutServicePageState = exports.MemoryCacheClient = exports.debug = exports.enableDebug = exports.NativeDataFetcher = exports.constants = void 0;
|
|
27
|
+
exports.EditingScripts = exports.withEmptyFieldEditingComponent = exports.withFieldMetadata = exports.withDatasourceCheck = exports.withPlaceholder = exports.withEditorChromes = exports.useSitecoreContext = exports.withSitecoreContext = exports.SitecoreContextReactContext = exports.SitecoreContext = exports.VisitorIdentification = exports.DefaultEmptyFieldEditingComponentText = exports.DefaultEmptyFieldEditingComponentImage = exports.ComponentLibraryLayout = exports.File = exports.getComponentLibraryStylesheetLinks = exports.BYOCComponent = exports.fetchFEaaSComponentServerProps = void 0;
|
|
28
28
|
var sitecore_jss_1 = require("@sitecore-jss/sitecore-jss");
|
|
29
29
|
Object.defineProperty(exports, "constants", { enumerable: true, get: function () { return sitecore_jss_1.constants; } });
|
|
30
|
-
Object.defineProperty(exports, "AxiosDataFetcher", { enumerable: true, get: function () { return sitecore_jss_1.AxiosDataFetcher; } });
|
|
31
30
|
Object.defineProperty(exports, "NativeDataFetcher", { enumerable: true, get: function () { return sitecore_jss_1.NativeDataFetcher; } });
|
|
32
31
|
Object.defineProperty(exports, "enableDebug", { enumerable: true, get: function () { return sitecore_jss_1.enableDebug; } });
|
|
33
32
|
Object.defineProperty(exports, "debug", { enumerable: true, get: function () { return sitecore_jss_1.debug; } });
|
|
@@ -40,6 +39,8 @@ Object.defineProperty(exports, "getChildPlaceholder", { enumerable: true, get: f
|
|
|
40
39
|
Object.defineProperty(exports, "getFieldValue", { enumerable: true, get: function () { return layout_1.getFieldValue; } });
|
|
41
40
|
Object.defineProperty(exports, "getContentStylesheetLink", { enumerable: true, get: function () { return layout_1.getContentStylesheetLink; } });
|
|
42
41
|
Object.defineProperty(exports, "EditMode", { enumerable: true, get: function () { return layout_1.EditMode; } });
|
|
42
|
+
var editing_1 = require("@sitecore-jss/sitecore-jss/editing");
|
|
43
|
+
Object.defineProperty(exports, "RestComponentLayoutService", { enumerable: true, get: function () { return editing_1.RestComponentLayoutService; } });
|
|
43
44
|
var media_1 = require("@sitecore-jss/sitecore-jss/media");
|
|
44
45
|
Object.defineProperty(exports, "mediaApi", { enumerable: true, get: function () { return media_1.mediaApi; } });
|
|
45
46
|
var tracking_1 = require("@sitecore-jss/sitecore-jss/tracking");
|
|
@@ -99,6 +100,7 @@ Object.defineProperty(exports, "fetchFEaaSComponentServerProps", { enumerable: t
|
|
|
99
100
|
Object.defineProperty(exports, "BYOCComponent", { enumerable: true, get: function () { return sitecore_jss_react_1.BYOCComponent; } });
|
|
100
101
|
Object.defineProperty(exports, "getComponentLibraryStylesheetLinks", { enumerable: true, get: function () { return sitecore_jss_react_1.getComponentLibraryStylesheetLinks; } });
|
|
101
102
|
Object.defineProperty(exports, "File", { enumerable: true, get: function () { return sitecore_jss_react_1.File; } });
|
|
103
|
+
Object.defineProperty(exports, "ComponentLibraryLayout", { enumerable: true, get: function () { return sitecore_jss_react_1.ComponentLibraryLayout; } });
|
|
102
104
|
Object.defineProperty(exports, "DefaultEmptyFieldEditingComponentImage", { enumerable: true, get: function () { return sitecore_jss_react_1.DefaultEmptyFieldEditingComponentImage; } });
|
|
103
105
|
Object.defineProperty(exports, "DefaultEmptyFieldEditingComponentText", { enumerable: true, get: function () { return sitecore_jss_react_1.DefaultEmptyFieldEditingComponentText; } });
|
|
104
106
|
Object.defineProperty(exports, "VisitorIdentification", { enumerable: true, get: function () { return sitecore_jss_react_1.VisitorIdentification; } });
|
|
@@ -45,20 +45,28 @@ class RedirectsMiddleware extends middleware_1.MiddlewareBase {
|
|
|
45
45
|
});
|
|
46
46
|
const createResponse = () => __awaiter(this, void 0, void 0, function* () {
|
|
47
47
|
var _a;
|
|
48
|
+
const response = res || server_1.NextResponse.next();
|
|
48
49
|
if (this.config.disabled && this.config.disabled(req, res || server_1.NextResponse.next())) {
|
|
49
50
|
sitecore_jss_1.debug.redirects('skipped (redirects middleware is disabled)');
|
|
50
|
-
return
|
|
51
|
+
return response;
|
|
51
52
|
}
|
|
52
53
|
if (this.isPreview(req) || this.excludeRoute(pathname)) {
|
|
53
54
|
sitecore_jss_1.debug.redirects('skipped (%s)', this.isPreview(req) ? 'preview' : 'route excluded');
|
|
54
|
-
return
|
|
55
|
+
return response;
|
|
56
|
+
}
|
|
57
|
+
// Skip prefetch requests from Next.js, which are not original client requests
|
|
58
|
+
// as they load unnecessary requests that burden the redirects middleware with meaningless traffic
|
|
59
|
+
if (this.isPrefetch(req)) {
|
|
60
|
+
sitecore_jss_1.debug.redirects('skipped (prefetch)');
|
|
61
|
+
response.headers.set('x-middleware-cache', 'no-cache');
|
|
62
|
+
return response;
|
|
55
63
|
}
|
|
56
64
|
site = this.getSite(req, res);
|
|
57
65
|
// Find the redirect from result of RedirectService
|
|
58
66
|
const existsRedirect = yield this.getExistsRedirect(req, site.name);
|
|
59
67
|
if (!existsRedirect) {
|
|
60
68
|
sitecore_jss_1.debug.redirects('skipped (redirect does not exist)');
|
|
61
|
-
return
|
|
69
|
+
return response;
|
|
62
70
|
}
|
|
63
71
|
// Find context site language and replace token
|
|
64
72
|
if (REGEXP_CONTEXT_SITE_LANG.test(existsRedirect.target) &&
|
|
@@ -72,27 +80,26 @@ class RedirectsMiddleware extends middleware_1.MiddlewareBase {
|
|
|
72
80
|
url.href = existsRedirect.target;
|
|
73
81
|
}
|
|
74
82
|
else {
|
|
75
|
-
const
|
|
76
|
-
const
|
|
83
|
+
const isUrl = (0, utils_1.isRegexOrUrl)(existsRedirect.pattern) === 'url';
|
|
84
|
+
const targetParts = existsRedirect.target.split('/');
|
|
85
|
+
const urlFirstPart = targetParts[1];
|
|
77
86
|
if (this.locales.includes(urlFirstPart)) {
|
|
78
87
|
req.nextUrl.locale = urlFirstPart;
|
|
79
88
|
existsRedirect.target = existsRedirect.target.replace(`/${urlFirstPart}`, '');
|
|
80
89
|
}
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
.replace(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
const prepareNewURL = new URL(`${target[0]}${url.search}`, url.origin);
|
|
90
|
+
const targetSegments = isUrl
|
|
91
|
+
? existsRedirect.target.split('?')
|
|
92
|
+
: url.pathname.replace(/\/*$/gi, '') + existsRedirect.matchedQueryString;
|
|
93
|
+
const [targetPath, targetQueryString] = isUrl
|
|
94
|
+
? targetSegments
|
|
95
|
+
: targetSegments
|
|
96
|
+
.replace((0, regex_parser_1.default)(existsRedirect.pattern), existsRedirect.target)
|
|
97
|
+
.replace(/^\/\//, '/')
|
|
98
|
+
.split('?');
|
|
99
|
+
const mergedQueryString = existsRedirect.isQueryStringPreserved
|
|
100
|
+
? (0, utils_1.mergeURLSearchParams)(new URLSearchParams((_a = url.search) !== null && _a !== void 0 ? _a : ''), new URLSearchParams(targetQueryString || ''))
|
|
101
|
+
: targetQueryString || '';
|
|
102
|
+
const prepareNewURL = new URL(`${targetPath}${mergedQueryString ? '?' + mergedQueryString : ''}`, url.origin);
|
|
96
103
|
url.href = prepareNewURL.href;
|
|
97
104
|
url.pathname = prepareNewURL.pathname;
|
|
98
105
|
url.search = prepareNewURL.search;
|
|
@@ -101,16 +108,16 @@ class RedirectsMiddleware extends middleware_1.MiddlewareBase {
|
|
|
101
108
|
/** return Response redirect with http code of redirect type */
|
|
102
109
|
switch (existsRedirect.redirectType) {
|
|
103
110
|
case site_1.REDIRECT_TYPE_301: {
|
|
104
|
-
return this.createRedirectResponse(url,
|
|
111
|
+
return this.createRedirectResponse(url, response, 301, 'Moved Permanently');
|
|
105
112
|
}
|
|
106
113
|
case site_1.REDIRECT_TYPE_302: {
|
|
107
|
-
return this.createRedirectResponse(url,
|
|
114
|
+
return this.createRedirectResponse(url, response, 302, 'Found');
|
|
108
115
|
}
|
|
109
116
|
case site_1.REDIRECT_TYPE_SERVER_TRANSFER: {
|
|
110
|
-
return this.rewrite(url.href, req,
|
|
117
|
+
return this.rewrite(url.href, req, response);
|
|
111
118
|
}
|
|
112
119
|
default:
|
|
113
|
-
return
|
|
120
|
+
return response;
|
|
114
121
|
}
|
|
115
122
|
});
|
|
116
123
|
const response = yield createResponse();
|
|
@@ -152,59 +159,43 @@ class RedirectsMiddleware extends middleware_1.MiddlewareBase {
|
|
|
152
159
|
*/
|
|
153
160
|
getExistsRedirect(req, siteName) {
|
|
154
161
|
return __awaiter(this, void 0, void 0, function* () {
|
|
155
|
-
const redirects = yield this.redirectsService.fetchRedirects(siteName);
|
|
156
162
|
const { pathname: targetURL, search: targetQS = '', locale } = this.normalizeUrl(req.nextUrl.clone());
|
|
163
|
+
const normalizedPath = targetURL.replace(/\/*$/gi, '');
|
|
164
|
+
const redirects = yield this.redirectsService.fetchRedirects(siteName);
|
|
157
165
|
const language = this.getLanguage(req);
|
|
158
166
|
const modifyRedirects = structuredClone(redirects);
|
|
167
|
+
let matchedQueryString;
|
|
159
168
|
return modifyRedirects.length
|
|
160
169
|
? modifyRedirects.find((redirect) => {
|
|
170
|
+
var _a;
|
|
171
|
+
if ((0, utils_1.isRegexOrUrl)(redirect.pattern) === 'url') {
|
|
172
|
+
const parseUrlPattern = redirect.pattern.endsWith('/')
|
|
173
|
+
? redirect.pattern.slice(0, -1).split('?')
|
|
174
|
+
: redirect.pattern.split('?');
|
|
175
|
+
return ((parseUrlPattern[0] === normalizedPath ||
|
|
176
|
+
parseUrlPattern[0] === `/${locale}${normalizedPath}`) &&
|
|
177
|
+
(0, utils_1.areURLSearchParamsEqual)(new URLSearchParams((_a = parseUrlPattern[1]) !== null && _a !== void 0 ? _a : ''), new URLSearchParams(targetQS)));
|
|
178
|
+
}
|
|
161
179
|
// Modify the redirect pattern to ignore the language prefix in the path
|
|
162
|
-
|
|
180
|
+
// And escapes non-special "?" characters in a string or regex.
|
|
181
|
+
redirect.pattern = (0, utils_1.escapeNonSpecialQuestionMarks)(redirect.pattern.replace(new RegExp(`^[^]?/${language}/`, 'gi'), ''));
|
|
163
182
|
// Prepare the redirect pattern as a regular expression, making it more flexible for matching URLs
|
|
164
183
|
redirect.pattern = `/^\/${redirect.pattern
|
|
165
184
|
.replace(/^\/|\/$/g, '') // Removes leading and trailing slashes
|
|
166
185
|
.replace(/^\^\/|\/\$$/g, '') // Removes unnecessary start (^) and end ($) anchors
|
|
167
186
|
.replace(/^\^|\$$/g, '') // Further cleans up anchors
|
|
168
|
-
.replace(/(?<!\\)\?/g, '\\?') // Escapes question marks in the pattern
|
|
169
187
|
.replace(/\$\/gi$/g, '')}[\/]?$/i`; // Ensures the pattern allows an optional trailing slash
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
* To account for this, the method `isPermutedQueryMatch` generates all possible permutations
|
|
177
|
-
* of the query parameters and checks if any of those permutations match the regex pattern for the redirect.
|
|
178
|
-
*
|
|
179
|
-
* NOTE: This fix is specifically implemented for Netlify, where query parameters are sometimes
|
|
180
|
-
* automatically sorted, which can cause issues with matching redirects if the order of query
|
|
181
|
-
* parameters is important. By checking every possible permutation, we ensure that redirects
|
|
182
|
-
* work correctly on Netlify despite this behavior.
|
|
183
|
-
*
|
|
184
|
-
* It passes several pieces of information to the function:
|
|
185
|
-
* 1. `pathname`: The normalized URL path without query parameters (e.g., '/about').
|
|
186
|
-
* 2. `queryString`: The current query string from the URL, which will be permuted and matched (e.g., '?key1=value1&key2=value2').
|
|
187
|
-
* 3. `pattern`: The regex pattern for the redirect that we are trying to match against the URL (e.g., '/about?key1=value1').
|
|
188
|
-
* 4. `locale`: The locale part of the URL (if any), which helps support multilingual URLs.
|
|
189
|
-
*
|
|
190
|
-
* If one of the permutations of the query string matches the redirect pattern, the function
|
|
191
|
-
* returns the matched query string, which is stored in `matchedQueryString`. If no match is found,
|
|
192
|
-
* it returns `undefined`. The `matchedQueryString` is later used to indicate whether the query
|
|
193
|
-
* string contributed to a successful redirect match.
|
|
194
|
-
*/
|
|
195
|
-
const matchedQueryString = this.isPermutedQueryMatch({
|
|
196
|
-
pathname: targetURL,
|
|
197
|
-
queryString: targetQS,
|
|
198
|
-
pattern: redirect.pattern,
|
|
199
|
-
locale,
|
|
200
|
-
});
|
|
188
|
+
matchedQueryString = [
|
|
189
|
+
(0, regex_parser_1.default)(redirect.pattern).test(`${normalizedPath}${targetQS}`),
|
|
190
|
+
(0, regex_parser_1.default)(redirect.pattern).test(`/${locale}${normalizedPath}${targetQS}`),
|
|
191
|
+
].some(Boolean)
|
|
192
|
+
? targetQS
|
|
193
|
+
: undefined;
|
|
201
194
|
// Save the matched query string (if found) into the redirect object
|
|
202
195
|
redirect.matchedQueryString = matchedQueryString || '';
|
|
203
|
-
|
|
204
|
-
return (((0, regex_parser_1.default)(redirect.pattern).test(targetURL) ||
|
|
196
|
+
return (!!((0, regex_parser_1.default)(redirect.pattern).test(targetURL) ||
|
|
205
197
|
(0, regex_parser_1.default)(redirect.pattern).test(`/${req.nextUrl.locale}${targetURL}`) ||
|
|
206
|
-
matchedQueryString) &&
|
|
207
|
-
(redirect.locale ? redirect.locale.toLowerCase() === locale.toLowerCase() : true));
|
|
198
|
+
matchedQueryString) && (redirect.locale ? redirect.locale.toLowerCase() === locale.toLowerCase() : true));
|
|
208
199
|
})
|
|
209
200
|
: undefined;
|
|
210
201
|
});
|
|
@@ -269,24 +260,5 @@ class RedirectsMiddleware extends middleware_1.MiddlewareBase {
|
|
|
269
260
|
}
|
|
270
261
|
return redirect;
|
|
271
262
|
}
|
|
272
|
-
/**
|
|
273
|
-
* Checks if the current URL query matches the provided pattern, considering all permutations of query parameters.
|
|
274
|
-
* It constructs all possible query parameter permutations and tests them against the pattern.
|
|
275
|
-
* @param {object} params - The parameters for the URL match.
|
|
276
|
-
* @param {string} params.pathname - The current URL pathname.
|
|
277
|
-
* @param {string} params.queryString - The current URL query string.
|
|
278
|
-
* @param {string} params.pattern - The regex pattern to test the constructed URLs against.
|
|
279
|
-
* @param {string} [params.locale] - The locale prefix to include in the URL if present.
|
|
280
|
-
* @returns {string | undefined} - return query string if any of the query permutations match the provided pattern, undefined otherwise.
|
|
281
|
-
*/
|
|
282
|
-
isPermutedQueryMatch({ pathname, queryString, pattern, locale, }) {
|
|
283
|
-
const paramsArray = Array.from(new URLSearchParams(queryString).entries());
|
|
284
|
-
const listOfPermuted = (0, utils_1.getPermutations)(paramsArray).map((permutation) => '?' + permutation.map(([key, value]) => `${key}=${value}`).join('&'));
|
|
285
|
-
const normalizedPath = pathname.replace(/\/*$/gi, '');
|
|
286
|
-
return listOfPermuted.find((query) => [
|
|
287
|
-
(0, regex_parser_1.default)(pattern).test(`${normalizedPath}${query}`),
|
|
288
|
-
(0, regex_parser_1.default)(pattern).test(`/${locale}${normalizedPath}${query}`),
|
|
289
|
-
].some(Boolean));
|
|
290
|
-
}
|
|
291
263
|
}
|
|
292
264
|
exports.RedirectsMiddleware = RedirectsMiddleware;
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { QUERY_PARAM_EDITING_SECRET } from '@sitecore-jss/sitecore-jss/editing';
|
|
11
|
-
import {
|
|
11
|
+
import { NativeDataFetcher, debug } from '@sitecore-jss/sitecore-jss';
|
|
12
12
|
import { editingDataDiskCache } from './editing-data-cache';
|
|
13
13
|
import { getJssEditingSecret } from '../utils/utils';
|
|
14
14
|
/**
|
|
@@ -85,7 +85,7 @@ export class ServerlessEditingDataService {
|
|
|
85
85
|
if (!this.apiRoute.includes('[key]')) {
|
|
86
86
|
throw new Error(`The specified apiRoute '${this.apiRoute}' is missing '[key]'.`);
|
|
87
87
|
}
|
|
88
|
-
this.dataFetcher = (_b = config === null || config === void 0 ? void 0 : config.dataFetcher) !== null && _b !== void 0 ? _b : new
|
|
88
|
+
this.dataFetcher = (_b = config === null || config === void 0 ? void 0 : config.dataFetcher) !== null && _b !== void 0 ? _b : new NativeDataFetcher({ debugger: debug.editing });
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
91
|
* Stores Sitecore editor payload data for later retrieval by key
|
|
@@ -8,8 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { STATIC_PROPS_ID, SERVER_PROPS_ID } from 'next/constants';
|
|
11
|
-
import {
|
|
12
|
-
import { EditMode } from '@sitecore-jss/sitecore-jss/layout';
|
|
11
|
+
import { NativeDataFetcher, debug } from '@sitecore-jss/sitecore-jss';
|
|
12
|
+
import { EditMode, LayoutServicePageState } from '@sitecore-jss/sitecore-jss/layout';
|
|
13
13
|
import { QUERY_PARAM_EDITING_SECRET, EDITING_ALLOWED_ORIGINS, } from '@sitecore-jss/sitecore-jss/editing';
|
|
14
14
|
import { editingDataService } from './editing-data-service';
|
|
15
15
|
import { getJssEditingSecret } from '../utils/utils';
|
|
@@ -49,7 +49,7 @@ export class ChromesHandler extends RenderMiddlewareBase {
|
|
|
49
49
|
return `${process.env.VERCEL ? 'https' : 'http'}://${req.headers.host}`;
|
|
50
50
|
};
|
|
51
51
|
this.editingDataService = (_a = config === null || config === void 0 ? void 0 : config.editingDataService) !== null && _a !== void 0 ? _a : editingDataService;
|
|
52
|
-
this.dataFetcher = (_b = config === null || config === void 0 ? void 0 : config.dataFetcher) !== null && _b !== void 0 ? _b : new
|
|
52
|
+
this.dataFetcher = (_b = config === null || config === void 0 ? void 0 : config.dataFetcher) !== null && _b !== void 0 ? _b : new NativeDataFetcher({ debugger: debug.editing });
|
|
53
53
|
this.resolvePageUrl = (_c = config === null || config === void 0 ? void 0 : config.resolvePageUrl) !== null && _c !== void 0 ? _c : this.defaultResolvePageUrl;
|
|
54
54
|
this.resolveServerUrl = (_d = config === null || config === void 0 ? void 0 : config.resolveServerUrl) !== null && _d !== void 0 ? _d : this.defaultResolveServerUrl;
|
|
55
55
|
}
|
|
@@ -76,7 +76,7 @@ export class ChromesHandler extends RenderMiddlewareBase {
|
|
|
76
76
|
const cookies = res.getHeader('Set-Cookie');
|
|
77
77
|
headers.cookie = `${headers.cookie ? headers.cookie + ';' : ''}${cookies.join(';')}`;
|
|
78
78
|
// Make actual render request for page route, passing on preview cookies as well as any approved query string parameters.
|
|
79
|
-
// Note timestamp effectively disables caching the request
|
|
79
|
+
// Note timestamp effectively disables caching the request (no amount of cache headers seemed to do it)
|
|
80
80
|
debug.editing('fetching page route for %s', editingData.path);
|
|
81
81
|
const requestUrl = new URL(this.resolvePageUrl({ serverUrl, itemPath: editingData.path }));
|
|
82
82
|
for (const key in params) {
|
|
@@ -122,8 +122,7 @@ export class ChromesHandler extends RenderMiddlewareBase {
|
|
|
122
122
|
catch (err) {
|
|
123
123
|
const error = err;
|
|
124
124
|
console.error(error);
|
|
125
|
-
if (error.response
|
|
126
|
-
// Axios error, which could mean the server or page URL isn't quite right, so provide a more helpful hint
|
|
125
|
+
if (error.response) {
|
|
127
126
|
console.info(
|
|
128
127
|
// eslint-disable-next-line quotes
|
|
129
128
|
"Hint: for non-standard server or Next.js route configurations, you may need to override the 'resolveServerUrl' or 'resolvePageUrl' available on the 'EditingRenderMiddleware' config.");
|
|
@@ -179,6 +178,18 @@ export const isEditingMetadataPreviewData = (data) => {
|
|
|
179
178
|
'editMode' in data &&
|
|
180
179
|
data.editMode === EditMode.Metadata);
|
|
181
180
|
};
|
|
181
|
+
/**
|
|
182
|
+
* Type guard for Component Library mode
|
|
183
|
+
* @param {object} data preview data to check
|
|
184
|
+
* @returns true if the data is EditingMetadataPreviewData
|
|
185
|
+
* @see EditingMetadataPreviewData
|
|
186
|
+
*/
|
|
187
|
+
export const isComponentLibraryPreviewData = (data) => {
|
|
188
|
+
return (typeof data === 'object' &&
|
|
189
|
+
data !== null &&
|
|
190
|
+
'mode' in data &&
|
|
191
|
+
data.mode === 'library');
|
|
192
|
+
};
|
|
182
193
|
/**
|
|
183
194
|
* Handler for the Editing Metadata GET requests.
|
|
184
195
|
* This handler is responsible for redirecting the request to the page route.
|
|
@@ -192,13 +203,17 @@ export class MetadataHandler {
|
|
|
192
203
|
var _a, _b, _c;
|
|
193
204
|
const { query } = req;
|
|
194
205
|
const startTimestamp = Date.now();
|
|
195
|
-
const
|
|
206
|
+
const mode = query.mode;
|
|
207
|
+
const metadataDefaultRequiredParams = ['sc_site', 'sc_itemid', 'sc_lang', 'route', 'mode'];
|
|
208
|
+
const metadataComponentRequiredParams = [
|
|
196
209
|
'sc_site',
|
|
197
210
|
'sc_itemid',
|
|
211
|
+
'sc_renderingId',
|
|
212
|
+
'sc_uid',
|
|
198
213
|
'sc_lang',
|
|
199
|
-
'route',
|
|
200
214
|
'mode',
|
|
201
215
|
];
|
|
216
|
+
const requiredQueryParams = mode === 'library' ? metadataComponentRequiredParams : metadataDefaultRequiredParams;
|
|
202
217
|
const missingQueryParams = requiredQueryParams.filter((param) => !query[param]);
|
|
203
218
|
// Validate query parameters
|
|
204
219
|
if (missingQueryParams.length) {
|
|
@@ -207,21 +222,40 @@ export class MetadataHandler {
|
|
|
207
222
|
html: `<html><body>Missing required query parameters: ${missingQueryParams.join(', ')}</body></html>`,
|
|
208
223
|
});
|
|
209
224
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
+
if (mode === 'library') {
|
|
226
|
+
// dedicated route and layout to SSR component library
|
|
227
|
+
query.route = '/component-library/render';
|
|
228
|
+
res.setPreviewData({
|
|
229
|
+
itemId: query.sc_itemid,
|
|
230
|
+
componentUid: query.sc_uid,
|
|
231
|
+
renderingId: query.sc_renderingId,
|
|
232
|
+
language: query.sc_lang,
|
|
233
|
+
site: query.sc_site,
|
|
234
|
+
pageState: LayoutServicePageState.Normal,
|
|
235
|
+
mode: 'library',
|
|
236
|
+
dataSourceId: query.sc_datasourceId,
|
|
237
|
+
version: query.sc_version,
|
|
238
|
+
}, {
|
|
239
|
+
maxAge: 3,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
res.setPreviewData({
|
|
244
|
+
site: query.sc_site,
|
|
245
|
+
itemId: query.sc_itemid,
|
|
246
|
+
language: query.sc_lang,
|
|
247
|
+
// for sc_variantId we may employ multiple variants (page-layout + component level)
|
|
248
|
+
variantIds: ((_a = query.sc_variant) === null || _a === void 0 ? void 0 : _a.split(',')) || [DEFAULT_VARIANT],
|
|
249
|
+
version: query.sc_version,
|
|
250
|
+
editMode: EditMode.Metadata,
|
|
251
|
+
pageState: query.mode,
|
|
252
|
+
layoutKind: query.sc_layoutKind,
|
|
253
|
+
},
|
|
254
|
+
// Cache the preview data for 3 seconds to ensure the page is rendered with the correct preview data not the cached one
|
|
255
|
+
{
|
|
256
|
+
maxAge: 3,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
225
259
|
// Cookies with the SameSite=Lax policy set by Next.js setPreviewData function causes CORS issue
|
|
226
260
|
// when Next.js preview mode is activated, resulting the page to render in normal mode instead.
|
|
227
261
|
// By replacing it with "SameSite=None; Secure", we ensure cookies are correctly sent with
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export { GraphQLEditingService } from '@sitecore-jss/sitecore-jss/editing';
|
|
2
2
|
export { EditingDataDiskCache } from './editing-data-cache';
|
|
3
3
|
export { EditingDataMiddleware } from './editing-data-middleware';
|
|
4
|
-
export { EditingRenderMiddleware, isEditingMetadataPreviewData, } from './editing-render-middleware';
|
|
4
|
+
export { EditingRenderMiddleware, isEditingMetadataPreviewData, isComponentLibraryPreviewData, } from './editing-render-middleware';
|
|
5
5
|
export { BasicEditingDataService, ServerlessEditingDataService, editingDataService, } from './editing-data-service';
|
|
6
6
|
export { VercelEditingDataCache } from './vercel-editing-data-cache';
|
|
7
7
|
export { FEAASRenderMiddleware } from './feaas-render-middleware';
|
|
8
8
|
export { EditingConfigMiddleware, } from './editing-config-middleware';
|
|
9
|
+
export { RenderingType, EDITING_COMPONENT_PLACEHOLDER, EDITING_COMPONENT_ID, } from '@sitecore-jss/sitecore-jss/layout';
|
|
@@ -25,13 +25,15 @@ export class RenderMiddlewareBase {
|
|
|
25
25
|
* @returns Object of approved headers
|
|
26
26
|
*/
|
|
27
27
|
this.getHeadersForPropagation = (headers) => {
|
|
28
|
-
|
|
29
|
-
EDITING_PASS_THROUGH_HEADERS.
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
// Filter and normalize headers
|
|
29
|
+
const filteredHeaders = EDITING_PASS_THROUGH_HEADERS.reduce((acc, header) => {
|
|
30
|
+
const value = headers[header];
|
|
31
|
+
if (value) {
|
|
32
|
+
acc[header] = Array.isArray(value) ? value.join(', ') : value;
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
return acc;
|
|
35
|
+
}, {});
|
|
36
|
+
return filteredHeaders;
|
|
35
37
|
};
|
|
36
38
|
}
|
|
37
39
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { constants,
|
|
1
|
+
export { constants, NativeDataFetcher, enableDebug, debug, MemoryCacheClient, } from '@sitecore-jss/sitecore-jss';
|
|
2
2
|
export { LayoutServicePageState, GraphQLLayoutService, RestLayoutService, getChildPlaceholder, getFieldValue, getContentStylesheetLink, EditMode, } from '@sitecore-jss/sitecore-jss/layout';
|
|
3
|
+
export { RestComponentLayoutService } from '@sitecore-jss/sitecore-jss/editing';
|
|
3
4
|
export { mediaApi } from '@sitecore-jss/sitecore-jss/media';
|
|
4
5
|
export { trackingApi, } from '@sitecore-jss/sitecore-jss/tracking';
|
|
5
6
|
export { GraphQLDictionaryService, RestDictionaryService, } from '@sitecore-jss/sitecore-jss/i18n';
|
|
@@ -19,4 +20,4 @@ import * as BYOCWrapper from './components/BYOCWrapper';
|
|
|
19
20
|
export { FEaaSWrapper };
|
|
20
21
|
export { BYOCWrapper };
|
|
21
22
|
export { ComponentBuilder } from './ComponentBuilder';
|
|
22
|
-
export { Image, Text, DateField, EditFrame, FEaaSComponent, fetchFEaaSComponentServerProps, BYOCComponent, getComponentLibraryStylesheetLinks, File, DefaultEmptyFieldEditingComponentImage, DefaultEmptyFieldEditingComponentText, VisitorIdentification, SitecoreContext, SitecoreContextReactContext, withSitecoreContext, useSitecoreContext, withEditorChromes, withPlaceholder, withDatasourceCheck, withFieldMetadata, withEmptyFieldEditingComponent, EditingScripts, } from '@sitecore-jss/sitecore-jss-react';
|
|
23
|
+
export { Image, Text, DateField, EditFrame, FEaaSComponent, fetchFEaaSComponentServerProps, BYOCComponent, getComponentLibraryStylesheetLinks, File, ComponentLibraryLayout, DefaultEmptyFieldEditingComponentImage, DefaultEmptyFieldEditingComponentText, VisitorIdentification, SitecoreContext, SitecoreContextReactContext, withSitecoreContext, useSitecoreContext, withEditorChromes, withPlaceholder, withDatasourceCheck, withFieldMetadata, withEmptyFieldEditingComponent, EditingScripts, } from '@sitecore-jss/sitecore-jss-react';
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { debug } from '@sitecore-jss/sitecore-jss';
|
|
11
11
|
import { GraphQLRedirectsService, REDIRECT_TYPE_301, REDIRECT_TYPE_302, REDIRECT_TYPE_SERVER_TRANSFER, } from '@sitecore-jss/sitecore-jss/site';
|
|
12
|
-
import {
|
|
12
|
+
import { areURLSearchParamsEqual, escapeNonSpecialQuestionMarks, isRegexOrUrl, mergeURLSearchParams, } from '@sitecore-jss/sitecore-jss/utils';
|
|
13
13
|
import { NextResponse } from 'next/server';
|
|
14
14
|
import regexParser from 'regex-parser';
|
|
15
15
|
import { MiddlewareBase } from './middleware';
|
|
@@ -39,20 +39,28 @@ export class RedirectsMiddleware extends MiddlewareBase {
|
|
|
39
39
|
});
|
|
40
40
|
const createResponse = () => __awaiter(this, void 0, void 0, function* () {
|
|
41
41
|
var _a;
|
|
42
|
+
const response = res || NextResponse.next();
|
|
42
43
|
if (this.config.disabled && this.config.disabled(req, res || NextResponse.next())) {
|
|
43
44
|
debug.redirects('skipped (redirects middleware is disabled)');
|
|
44
|
-
return
|
|
45
|
+
return response;
|
|
45
46
|
}
|
|
46
47
|
if (this.isPreview(req) || this.excludeRoute(pathname)) {
|
|
47
48
|
debug.redirects('skipped (%s)', this.isPreview(req) ? 'preview' : 'route excluded');
|
|
48
|
-
return
|
|
49
|
+
return response;
|
|
50
|
+
}
|
|
51
|
+
// Skip prefetch requests from Next.js, which are not original client requests
|
|
52
|
+
// as they load unnecessary requests that burden the redirects middleware with meaningless traffic
|
|
53
|
+
if (this.isPrefetch(req)) {
|
|
54
|
+
debug.redirects('skipped (prefetch)');
|
|
55
|
+
response.headers.set('x-middleware-cache', 'no-cache');
|
|
56
|
+
return response;
|
|
49
57
|
}
|
|
50
58
|
site = this.getSite(req, res);
|
|
51
59
|
// Find the redirect from result of RedirectService
|
|
52
60
|
const existsRedirect = yield this.getExistsRedirect(req, site.name);
|
|
53
61
|
if (!existsRedirect) {
|
|
54
62
|
debug.redirects('skipped (redirect does not exist)');
|
|
55
|
-
return
|
|
63
|
+
return response;
|
|
56
64
|
}
|
|
57
65
|
// Find context site language and replace token
|
|
58
66
|
if (REGEXP_CONTEXT_SITE_LANG.test(existsRedirect.target) &&
|
|
@@ -66,27 +74,26 @@ export class RedirectsMiddleware extends MiddlewareBase {
|
|
|
66
74
|
url.href = existsRedirect.target;
|
|
67
75
|
}
|
|
68
76
|
else {
|
|
69
|
-
const
|
|
70
|
-
const
|
|
77
|
+
const isUrl = isRegexOrUrl(existsRedirect.pattern) === 'url';
|
|
78
|
+
const targetParts = existsRedirect.target.split('/');
|
|
79
|
+
const urlFirstPart = targetParts[1];
|
|
71
80
|
if (this.locales.includes(urlFirstPart)) {
|
|
72
81
|
req.nextUrl.locale = urlFirstPart;
|
|
73
82
|
existsRedirect.target = existsRedirect.target.replace(`/${urlFirstPart}`, '');
|
|
74
83
|
}
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
.replace(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
const prepareNewURL = new URL(`${target[0]}${url.search}`, url.origin);
|
|
84
|
+
const targetSegments = isUrl
|
|
85
|
+
? existsRedirect.target.split('?')
|
|
86
|
+
: url.pathname.replace(/\/*$/gi, '') + existsRedirect.matchedQueryString;
|
|
87
|
+
const [targetPath, targetQueryString] = isUrl
|
|
88
|
+
? targetSegments
|
|
89
|
+
: targetSegments
|
|
90
|
+
.replace(regexParser(existsRedirect.pattern), existsRedirect.target)
|
|
91
|
+
.replace(/^\/\//, '/')
|
|
92
|
+
.split('?');
|
|
93
|
+
const mergedQueryString = existsRedirect.isQueryStringPreserved
|
|
94
|
+
? mergeURLSearchParams(new URLSearchParams((_a = url.search) !== null && _a !== void 0 ? _a : ''), new URLSearchParams(targetQueryString || ''))
|
|
95
|
+
: targetQueryString || '';
|
|
96
|
+
const prepareNewURL = new URL(`${targetPath}${mergedQueryString ? '?' + mergedQueryString : ''}`, url.origin);
|
|
90
97
|
url.href = prepareNewURL.href;
|
|
91
98
|
url.pathname = prepareNewURL.pathname;
|
|
92
99
|
url.search = prepareNewURL.search;
|
|
@@ -95,16 +102,16 @@ export class RedirectsMiddleware extends MiddlewareBase {
|
|
|
95
102
|
/** return Response redirect with http code of redirect type */
|
|
96
103
|
switch (existsRedirect.redirectType) {
|
|
97
104
|
case REDIRECT_TYPE_301: {
|
|
98
|
-
return this.createRedirectResponse(url,
|
|
105
|
+
return this.createRedirectResponse(url, response, 301, 'Moved Permanently');
|
|
99
106
|
}
|
|
100
107
|
case REDIRECT_TYPE_302: {
|
|
101
|
-
return this.createRedirectResponse(url,
|
|
108
|
+
return this.createRedirectResponse(url, response, 302, 'Found');
|
|
102
109
|
}
|
|
103
110
|
case REDIRECT_TYPE_SERVER_TRANSFER: {
|
|
104
|
-
return this.rewrite(url.href, req,
|
|
111
|
+
return this.rewrite(url.href, req, response);
|
|
105
112
|
}
|
|
106
113
|
default:
|
|
107
|
-
return
|
|
114
|
+
return response;
|
|
108
115
|
}
|
|
109
116
|
});
|
|
110
117
|
const response = yield createResponse();
|
|
@@ -146,59 +153,43 @@ export class RedirectsMiddleware extends MiddlewareBase {
|
|
|
146
153
|
*/
|
|
147
154
|
getExistsRedirect(req, siteName) {
|
|
148
155
|
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
-
const redirects = yield this.redirectsService.fetchRedirects(siteName);
|
|
150
156
|
const { pathname: targetURL, search: targetQS = '', locale } = this.normalizeUrl(req.nextUrl.clone());
|
|
157
|
+
const normalizedPath = targetURL.replace(/\/*$/gi, '');
|
|
158
|
+
const redirects = yield this.redirectsService.fetchRedirects(siteName);
|
|
151
159
|
const language = this.getLanguage(req);
|
|
152
160
|
const modifyRedirects = structuredClone(redirects);
|
|
161
|
+
let matchedQueryString;
|
|
153
162
|
return modifyRedirects.length
|
|
154
163
|
? modifyRedirects.find((redirect) => {
|
|
164
|
+
var _a;
|
|
165
|
+
if (isRegexOrUrl(redirect.pattern) === 'url') {
|
|
166
|
+
const parseUrlPattern = redirect.pattern.endsWith('/')
|
|
167
|
+
? redirect.pattern.slice(0, -1).split('?')
|
|
168
|
+
: redirect.pattern.split('?');
|
|
169
|
+
return ((parseUrlPattern[0] === normalizedPath ||
|
|
170
|
+
parseUrlPattern[0] === `/${locale}${normalizedPath}`) &&
|
|
171
|
+
areURLSearchParamsEqual(new URLSearchParams((_a = parseUrlPattern[1]) !== null && _a !== void 0 ? _a : ''), new URLSearchParams(targetQS)));
|
|
172
|
+
}
|
|
155
173
|
// Modify the redirect pattern to ignore the language prefix in the path
|
|
156
|
-
|
|
174
|
+
// And escapes non-special "?" characters in a string or regex.
|
|
175
|
+
redirect.pattern = escapeNonSpecialQuestionMarks(redirect.pattern.replace(new RegExp(`^[^]?/${language}/`, 'gi'), ''));
|
|
157
176
|
// Prepare the redirect pattern as a regular expression, making it more flexible for matching URLs
|
|
158
177
|
redirect.pattern = `/^\/${redirect.pattern
|
|
159
178
|
.replace(/^\/|\/$/g, '') // Removes leading and trailing slashes
|
|
160
179
|
.replace(/^\^\/|\/\$$/g, '') // Removes unnecessary start (^) and end ($) anchors
|
|
161
180
|
.replace(/^\^|\$$/g, '') // Further cleans up anchors
|
|
162
|
-
.replace(/(?<!\\)\?/g, '\\?') // Escapes question marks in the pattern
|
|
163
181
|
.replace(/\$\/gi$/g, '')}[\/]?$/i`; // Ensures the pattern allows an optional trailing slash
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
* To account for this, the method `isPermutedQueryMatch` generates all possible permutations
|
|
171
|
-
* of the query parameters and checks if any of those permutations match the regex pattern for the redirect.
|
|
172
|
-
*
|
|
173
|
-
* NOTE: This fix is specifically implemented for Netlify, where query parameters are sometimes
|
|
174
|
-
* automatically sorted, which can cause issues with matching redirects if the order of query
|
|
175
|
-
* parameters is important. By checking every possible permutation, we ensure that redirects
|
|
176
|
-
* work correctly on Netlify despite this behavior.
|
|
177
|
-
*
|
|
178
|
-
* It passes several pieces of information to the function:
|
|
179
|
-
* 1. `pathname`: The normalized URL path without query parameters (e.g., '/about').
|
|
180
|
-
* 2. `queryString`: The current query string from the URL, which will be permuted and matched (e.g., '?key1=value1&key2=value2').
|
|
181
|
-
* 3. `pattern`: The regex pattern for the redirect that we are trying to match against the URL (e.g., '/about?key1=value1').
|
|
182
|
-
* 4. `locale`: The locale part of the URL (if any), which helps support multilingual URLs.
|
|
183
|
-
*
|
|
184
|
-
* If one of the permutations of the query string matches the redirect pattern, the function
|
|
185
|
-
* returns the matched query string, which is stored in `matchedQueryString`. If no match is found,
|
|
186
|
-
* it returns `undefined`. The `matchedQueryString` is later used to indicate whether the query
|
|
187
|
-
* string contributed to a successful redirect match.
|
|
188
|
-
*/
|
|
189
|
-
const matchedQueryString = this.isPermutedQueryMatch({
|
|
190
|
-
pathname: targetURL,
|
|
191
|
-
queryString: targetQS,
|
|
192
|
-
pattern: redirect.pattern,
|
|
193
|
-
locale,
|
|
194
|
-
});
|
|
182
|
+
matchedQueryString = [
|
|
183
|
+
regexParser(redirect.pattern).test(`${normalizedPath}${targetQS}`),
|
|
184
|
+
regexParser(redirect.pattern).test(`/${locale}${normalizedPath}${targetQS}`),
|
|
185
|
+
].some(Boolean)
|
|
186
|
+
? targetQS
|
|
187
|
+
: undefined;
|
|
195
188
|
// Save the matched query string (if found) into the redirect object
|
|
196
189
|
redirect.matchedQueryString = matchedQueryString || '';
|
|
197
|
-
|
|
198
|
-
return ((regexParser(redirect.pattern).test(targetURL) ||
|
|
190
|
+
return (!!(regexParser(redirect.pattern).test(targetURL) ||
|
|
199
191
|
regexParser(redirect.pattern).test(`/${req.nextUrl.locale}${targetURL}`) ||
|
|
200
|
-
matchedQueryString) &&
|
|
201
|
-
(redirect.locale ? redirect.locale.toLowerCase() === locale.toLowerCase() : true));
|
|
192
|
+
matchedQueryString) && (redirect.locale ? redirect.locale.toLowerCase() === locale.toLowerCase() : true));
|
|
202
193
|
})
|
|
203
194
|
: undefined;
|
|
204
195
|
});
|
|
@@ -263,23 +254,4 @@ export class RedirectsMiddleware extends MiddlewareBase {
|
|
|
263
254
|
}
|
|
264
255
|
return redirect;
|
|
265
256
|
}
|
|
266
|
-
/**
|
|
267
|
-
* Checks if the current URL query matches the provided pattern, considering all permutations of query parameters.
|
|
268
|
-
* It constructs all possible query parameter permutations and tests them against the pattern.
|
|
269
|
-
* @param {object} params - The parameters for the URL match.
|
|
270
|
-
* @param {string} params.pathname - The current URL pathname.
|
|
271
|
-
* @param {string} params.queryString - The current URL query string.
|
|
272
|
-
* @param {string} params.pattern - The regex pattern to test the constructed URLs against.
|
|
273
|
-
* @param {string} [params.locale] - The locale prefix to include in the URL if present.
|
|
274
|
-
* @returns {string | undefined} - return query string if any of the query permutations match the provided pattern, undefined otherwise.
|
|
275
|
-
*/
|
|
276
|
-
isPermutedQueryMatch({ pathname, queryString, pattern, locale, }) {
|
|
277
|
-
const paramsArray = Array.from(new URLSearchParams(queryString).entries());
|
|
278
|
-
const listOfPermuted = getPermutations(paramsArray).map((permutation) => '?' + permutation.map(([key, value]) => `${key}=${value}`).join('&'));
|
|
279
|
-
const normalizedPath = pathname.replace(/\/*$/gi, '');
|
|
280
|
-
return listOfPermuted.find((query) => [
|
|
281
|
-
regexParser(pattern).test(`${normalizedPath}${query}`),
|
|
282
|
-
regexParser(pattern).test(`/${locale}${normalizedPath}${query}`),
|
|
283
|
-
].some(Boolean));
|
|
284
|
-
}
|
|
285
257
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sitecore-jss/sitecore-jss-nextjs",
|
|
3
|
-
"version": "22.4.0-canary.
|
|
3
|
+
"version": "22.4.0-canary.10",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -73,9 +73,9 @@
|
|
|
73
73
|
"react-dom": "^18.2.0"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@sitecore-jss/sitecore-jss": "^22.4.0-canary.
|
|
77
|
-
"@sitecore-jss/sitecore-jss-dev-tools": "^22.4.0-canary.
|
|
78
|
-
"@sitecore-jss/sitecore-jss-react": "^22.4.0-canary.
|
|
76
|
+
"@sitecore-jss/sitecore-jss": "^22.4.0-canary.10",
|
|
77
|
+
"@sitecore-jss/sitecore-jss-dev-tools": "^22.4.0-canary.10",
|
|
78
|
+
"@sitecore-jss/sitecore-jss-react": "^22.4.0-canary.10",
|
|
79
79
|
"@vercel/kv": "^0.2.1",
|
|
80
80
|
"prop-types": "^15.8.1",
|
|
81
81
|
"regex-parser": "^2.2.11",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
},
|
|
84
84
|
"description": "",
|
|
85
85
|
"types": "types/index.d.ts",
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "1220b71aa4c565d5f8dffde56f362543d6fda3f7",
|
|
87
87
|
"files": [
|
|
88
88
|
"dist",
|
|
89
89
|
"types",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NativeDataFetcher } from '@sitecore-jss/sitecore-jss';
|
|
2
2
|
import { EditingData } from './editing-data';
|
|
3
3
|
import { EditingDataCache } from './editing-data-cache';
|
|
4
4
|
import { PreviewData } from 'next';
|
|
@@ -87,11 +87,11 @@ export interface ServerlessEditingDataServiceConfig {
|
|
|
87
87
|
*/
|
|
88
88
|
apiRoute?: string;
|
|
89
89
|
/**
|
|
90
|
-
* The `
|
|
91
|
-
* @default new
|
|
92
|
-
* @see
|
|
90
|
+
* The `NativeDataFetcher` instance to use for API requests.
|
|
91
|
+
* @default new NativeDataFetcher()
|
|
92
|
+
* @see NativeDataFetcher
|
|
93
93
|
*/
|
|
94
|
-
dataFetcher?:
|
|
94
|
+
dataFetcher?: NativeDataFetcher;
|
|
95
95
|
}
|
|
96
96
|
/**
|
|
97
97
|
* Service responsible for maintaining Sitecore editor data between requests
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
-
import {
|
|
2
|
+
import { NativeDataFetcher } from '@sitecore-jss/sitecore-jss';
|
|
3
3
|
import { EditMode, LayoutServicePageState } from '@sitecore-jss/sitecore-jss/layout';
|
|
4
4
|
import { RenderMetadataQueryParams, LayoutKind } from '@sitecore-jss/sitecore-jss/editing';
|
|
5
5
|
import { EditingDataService } from './editing-data-service';
|
|
@@ -11,11 +11,11 @@ export type EditingRenderMiddlewareConfig = {
|
|
|
11
11
|
/**
|
|
12
12
|
* -- Edit Mode Chromes --
|
|
13
13
|
*
|
|
14
|
-
* The `
|
|
15
|
-
* @default new
|
|
16
|
-
* @see
|
|
14
|
+
* The `NativeDataFetcher` instance to use for API requests.
|
|
15
|
+
* @default new NativeDataFetcher()
|
|
16
|
+
* @see NativeDataFetcher
|
|
17
17
|
*/
|
|
18
|
-
dataFetcher?:
|
|
18
|
+
dataFetcher?: NativeDataFetcher;
|
|
19
19
|
/**
|
|
20
20
|
* -- Edit Mode Chromes --
|
|
21
21
|
*
|
|
@@ -99,7 +99,7 @@ export type EditingRenderMiddlewareMetadataConfig = Pick<EditingRenderMiddleware
|
|
|
99
99
|
/**
|
|
100
100
|
* Next.js API request with Metadata query parameters.
|
|
101
101
|
*/
|
|
102
|
-
type MetadataNextApiRequest = NextApiRequest & {
|
|
102
|
+
export type MetadataNextApiRequest = NextApiRequest & {
|
|
103
103
|
query: RenderMetadataQueryParams;
|
|
104
104
|
};
|
|
105
105
|
/**
|
|
@@ -115,6 +115,21 @@ export type EditingMetadataPreviewData = {
|
|
|
115
115
|
version?: string;
|
|
116
116
|
layoutKind?: LayoutKind;
|
|
117
117
|
};
|
|
118
|
+
/**
|
|
119
|
+
* Data for Component Library rendering mode
|
|
120
|
+
*/
|
|
121
|
+
export interface ComponentLibraryRenderPreviewData {
|
|
122
|
+
site: string;
|
|
123
|
+
itemId: string;
|
|
124
|
+
renderingId: string;
|
|
125
|
+
componentUid: string;
|
|
126
|
+
language: string;
|
|
127
|
+
pageState: LayoutServicePageState;
|
|
128
|
+
mode?: 'library';
|
|
129
|
+
variant?: string;
|
|
130
|
+
version?: string;
|
|
131
|
+
dataSourceId?: string;
|
|
132
|
+
}
|
|
118
133
|
/**
|
|
119
134
|
* Type guard for EditingMetadataPreviewData
|
|
120
135
|
* @param {object} data preview data to check
|
|
@@ -122,6 +137,13 @@ export type EditingMetadataPreviewData = {
|
|
|
122
137
|
* @see EditingMetadataPreviewData
|
|
123
138
|
*/
|
|
124
139
|
export declare const isEditingMetadataPreviewData: (data: unknown) => data is EditingMetadataPreviewData;
|
|
140
|
+
/**
|
|
141
|
+
* Type guard for Component Library mode
|
|
142
|
+
* @param {object} data preview data to check
|
|
143
|
+
* @returns true if the data is EditingMetadataPreviewData
|
|
144
|
+
* @see EditingMetadataPreviewData
|
|
145
|
+
*/
|
|
146
|
+
export declare const isComponentLibraryPreviewData: (data: unknown) => data is ComponentLibraryRenderPreviewData;
|
|
125
147
|
/**
|
|
126
148
|
* Handler for the Editing Metadata GET requests.
|
|
127
149
|
* This handler is responsible for redirecting the request to the page route.
|
|
@@ -154,4 +176,3 @@ export declare class EditingRenderMiddleware extends RenderMiddlewareBase {
|
|
|
154
176
|
getHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
|
|
155
177
|
private handler;
|
|
156
178
|
}
|
|
157
|
-
export {};
|
package/types/editing/index.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ export { GraphQLEditingService } from '@sitecore-jss/sitecore-jss/editing';
|
|
|
2
2
|
export { EditingData } from './editing-data';
|
|
3
3
|
export { EditingDataCache, EditingDataDiskCache } from './editing-data-cache';
|
|
4
4
|
export { EditingDataMiddleware, EditingDataMiddlewareConfig } from './editing-data-middleware';
|
|
5
|
-
export { EditingRenderMiddleware, EditingRenderMiddlewareConfig, EditingMetadataPreviewData, isEditingMetadataPreviewData, } from './editing-render-middleware';
|
|
5
|
+
export { EditingRenderMiddleware, EditingRenderMiddlewareConfig, EditingMetadataPreviewData, isEditingMetadataPreviewData, isComponentLibraryPreviewData, } from './editing-render-middleware';
|
|
6
6
|
export { EditingPreviewData, EditingDataService, BasicEditingDataService, BasicEditingDataServiceConfig, ServerlessEditingDataService, ServerlessEditingDataServiceConfig, editingDataService, } from './editing-data-service';
|
|
7
7
|
export { VercelEditingDataCache } from './vercel-editing-data-cache';
|
|
8
8
|
export { FEAASRenderMiddleware, FEAASRenderMiddlewareConfig } from './feaas-render-middleware';
|
|
9
9
|
export { EditingConfigMiddleware, EditingConfigMiddlewareConfig, } from './editing-config-middleware';
|
|
10
|
+
export { RenderingType, EDITING_COMPONENT_PLACEHOLDER, EDITING_COMPONENT_ID, } from '@sitecore-jss/sitecore-jss/layout';
|
package/types/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { constants, HttpDataFetcher,
|
|
1
|
+
export { constants, HttpDataFetcher, NativeDataFetcher, NativeDataFetcherConfig, NativeDataFetcherResponse, NativeDataFetcherError, HTMLLink, enableDebug, debug, CacheClient, CacheOptions, MemoryCacheClient, } from '@sitecore-jss/sitecore-jss';
|
|
2
2
|
export { LayoutService, LayoutServiceData, LayoutServicePageState, LayoutServiceContext, LayoutServiceContextData, GraphQLLayoutService, GraphQLLayoutServiceConfig, RestLayoutService, RestLayoutServiceConfig, PlaceholderData, PlaceholdersData, RouteData, Field, Item, HtmlElementRendering, getChildPlaceholder, getFieldValue, ComponentRendering, ComponentFields, ComponentParams, getContentStylesheetLink, EditMode, } from '@sitecore-jss/sitecore-jss/layout';
|
|
3
|
+
export { RestComponentLayoutService } from '@sitecore-jss/sitecore-jss/editing';
|
|
3
4
|
export { mediaApi } from '@sitecore-jss/sitecore-jss/media';
|
|
4
5
|
export { trackingApi, TrackingRequestOptions, CampaignInstance, GoalInstance, OutcomeInstance, EventInstance, PageViewInstance, } from '@sitecore-jss/sitecore-jss/tracking';
|
|
5
6
|
export { DictionaryPhrases, DictionaryService, GraphQLDictionaryService, GraphQLDictionaryServiceConfig, RestDictionaryService, RestDictionaryServiceConfig, } from '@sitecore-jss/sitecore-jss/i18n';
|
|
@@ -22,4 +23,4 @@ import * as BYOCWrapper from './components/BYOCWrapper';
|
|
|
22
23
|
export { FEaaSWrapper };
|
|
23
24
|
export { BYOCWrapper };
|
|
24
25
|
export { ComponentBuilder, ComponentBuilderConfig } from './ComponentBuilder';
|
|
25
|
-
export { ComponentFactory, Image, ImageField, ImageFieldValue, ImageProps, LinkField, LinkFieldValue, Text, TextField, DateField, EditFrame, FEaaSComponent, FEaaSComponentProps, FEaaSComponentParams, fetchFEaaSComponentServerProps, BYOCComponentParams, BYOCComponent, BYOCComponentProps, getComponentLibraryStylesheetLinks, File, FileField, RichTextField, DefaultEmptyFieldEditingComponentImage, DefaultEmptyFieldEditingComponentText, VisitorIdentification, PlaceholderComponentProps, SitecoreContext, SitecoreContextState, SitecoreContextValue, SitecoreContextReactContext, withSitecoreContext, useSitecoreContext, withEditorChromes, withPlaceholder, withDatasourceCheck, ImageSizeParameters, WithSitecoreContextOptions, WithSitecoreContextProps, WithSitecoreContextHocProps, withFieldMetadata, withEmptyFieldEditingComponent, EditingScripts, } from '@sitecore-jss/sitecore-jss-react';
|
|
26
|
+
export { ComponentFactory, Image, ImageField, ImageFieldValue, ImageProps, LinkField, LinkFieldValue, Text, TextField, DateField, EditFrame, FEaaSComponent, FEaaSComponentProps, FEaaSComponentParams, fetchFEaaSComponentServerProps, BYOCComponentParams, BYOCComponent, BYOCComponentProps, getComponentLibraryStylesheetLinks, File, FileField, RichTextField, ComponentLibraryLayout, DefaultEmptyFieldEditingComponentImage, DefaultEmptyFieldEditingComponentText, VisitorIdentification, PlaceholderComponentProps, SitecoreContext, SitecoreContextState, SitecoreContextValue, SitecoreContextReactContext, withSitecoreContext, useSitecoreContext, withEditorChromes, withPlaceholder, withDatasourceCheck, ImageSizeParameters, WithSitecoreContextOptions, WithSitecoreContextProps, WithSitecoreContextHocProps, withFieldMetadata, withEmptyFieldEditingComponent, EditingScripts, } from '@sitecore-jss/sitecore-jss-react';
|
|
@@ -54,15 +54,4 @@ export declare class RedirectsMiddleware extends MiddlewareBase {
|
|
|
54
54
|
* @returns {NextResponse<unknown>} The redirect response.
|
|
55
55
|
*/
|
|
56
56
|
private createRedirectResponse;
|
|
57
|
-
/**
|
|
58
|
-
* Checks if the current URL query matches the provided pattern, considering all permutations of query parameters.
|
|
59
|
-
* It constructs all possible query parameter permutations and tests them against the pattern.
|
|
60
|
-
* @param {object} params - The parameters for the URL match.
|
|
61
|
-
* @param {string} params.pathname - The current URL pathname.
|
|
62
|
-
* @param {string} params.queryString - The current URL query string.
|
|
63
|
-
* @param {string} params.pattern - The regex pattern to test the constructed URLs against.
|
|
64
|
-
* @param {string} [params.locale] - The locale prefix to include in the URL if present.
|
|
65
|
-
* @returns {string | undefined} - return query string if any of the query permutations match the provided pattern, undefined otherwise.
|
|
66
|
-
*/
|
|
67
|
-
private isPermutedQueryMatch;
|
|
68
57
|
}
|