@sitecore-jss/sitecore-jss-nextjs 21.1.0-canary.6 → 21.1.0-canary.60
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/EditingComponentPlaceholder.js +12 -0
- package/dist/cjs/components/Link.js +2 -2
- package/dist/cjs/editing/editing-data-cache.js +15 -10
- package/dist/cjs/editing/editing-data-middleware.js +2 -2
- package/dist/cjs/editing/editing-data-service.js +2 -2
- package/dist/cjs/editing/editing-render-middleware.js +9 -1
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/middleware/personalize-middleware.js +4 -2
- package/dist/cjs/middleware/redirects-middleware.js +25 -7
- package/dist/cjs/monitoring/healthcheck-middleware.js +30 -0
- package/dist/cjs/monitoring/index.js +5 -0
- package/dist/esm/components/EditingComponentPlaceholder.js +5 -0
- package/dist/esm/components/Link.js +2 -2
- package/dist/esm/editing/editing-data-cache.js +15 -10
- package/dist/esm/editing/editing-data-middleware.js +2 -2
- package/dist/esm/editing/editing-data-service.js +2 -2
- package/dist/esm/editing/editing-render-middleware.js +9 -1
- package/dist/esm/index.js +3 -2
- package/dist/esm/middleware/personalize-middleware.js +4 -2
- package/dist/esm/middleware/redirects-middleware.js +25 -7
- package/dist/esm/monitoring/healthcheck-middleware.js +26 -0
- package/dist/esm/monitoring/index.js +1 -0
- package/monitoring.d.ts +1 -0
- package/monitoring.js +1 -0
- package/package.json +16 -15
- package/types/components/EditingComponentPlaceholder.d.ts +4 -0
- package/types/editing/editing-data-cache.d.ts +4 -4
- package/types/index.d.ts +3 -2
- package/types/middleware/redirects-middleware.d.ts +17 -0
- package/types/monitoring/healthcheck-middleware.d.ts +12 -0
- package/types/monitoring/index.d.ts +1 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.EditingComponentPlaceholder = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const layout_1 = require("@sitecore-jss/sitecore-jss/layout");
|
|
9
|
+
const Placeholder_1 = require("./Placeholder");
|
|
10
|
+
const EditingComponentPlaceholder = ({ rendering, }) => (react_1.default.createElement("div", { id: layout_1.EDITING_COMPONENT_ID },
|
|
11
|
+
react_1.default.createElement(Placeholder_1.Placeholder, { name: layout_1.EDITING_COMPONENT_PLACEHOLDER, rendering: rendering })));
|
|
12
|
+
exports.EditingComponentPlaceholder = EditingComponentPlaceholder;
|
|
@@ -43,13 +43,13 @@ exports.Link = react_1.forwardRef((props, ref) => {
|
|
|
43
43
|
const value = (field.href
|
|
44
44
|
? field
|
|
45
45
|
: field.value);
|
|
46
|
-
const { href, querystring } = value;
|
|
46
|
+
const { href, querystring, anchor } = value;
|
|
47
47
|
const isEditing = editable && field.editable;
|
|
48
48
|
if (href && !isEditing) {
|
|
49
49
|
const text = showLinkTextWithChildrenPresent || !children ? value.text || value.href : null;
|
|
50
50
|
// determine if a link is a route or not.
|
|
51
51
|
if (internalLinkMatcher.test(href)) {
|
|
52
|
-
return (react_1.default.createElement(link_1.default, { href: { pathname: href, query: querystring }, key: "link", locale: false },
|
|
52
|
+
return (react_1.default.createElement(link_1.default, { href: { pathname: href, query: querystring, hash: anchor }, key: "link", locale: false },
|
|
53
53
|
react_1.default.createElement("a", Object.assign({ title: value.title, target: value.target, className: value.class }, htmlLinkProps, { ref: ref }),
|
|
54
54
|
text,
|
|
55
55
|
children)));
|
|
@@ -22,19 +22,24 @@ class EditingDataDiskCache {
|
|
|
22
22
|
}
|
|
23
23
|
set(key, editingData) {
|
|
24
24
|
const filePath = this.cache.set(key, JSON.stringify(editingData));
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
if (!filePath || filePath.length === 0) {
|
|
27
|
+
reject(new Error(`Editing data cache not set for key ${key} at ${this.cache.root}`));
|
|
28
|
+
}
|
|
29
|
+
resolve();
|
|
30
|
+
});
|
|
28
31
|
}
|
|
29
32
|
get(key) {
|
|
30
33
|
const entry = this.cache.get(key);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
return new Promise((resolve) => {
|
|
35
|
+
if (!entry.isCached) {
|
|
36
|
+
console.warn(`Editing data cache miss for key ${key} at ${this.cache.root}`);
|
|
37
|
+
resolve(undefined);
|
|
38
|
+
}
|
|
39
|
+
// Remove to preserve disk-space (as a macrotask so as not to block current execution)
|
|
40
|
+
setTimeout(() => this.cache.remove(key));
|
|
41
|
+
resolve(JSON.parse(entry.value));
|
|
42
|
+
});
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
exports.EditingDataDiskCache = EditingDataDiskCache;
|
|
@@ -36,7 +36,7 @@ class EditingDataMiddleware {
|
|
|
36
36
|
switch (method) {
|
|
37
37
|
case 'GET': {
|
|
38
38
|
// Get cache value
|
|
39
|
-
const data = this.editingDataCache.get(key);
|
|
39
|
+
const data = yield this.editingDataCache.get(key);
|
|
40
40
|
res.status(200).json(data);
|
|
41
41
|
break;
|
|
42
42
|
}
|
|
@@ -46,7 +46,7 @@ class EditingDataMiddleware {
|
|
|
46
46
|
}
|
|
47
47
|
else {
|
|
48
48
|
// Set cache value
|
|
49
|
-
this.editingDataCache.set(key, body);
|
|
49
|
+
yield this.editingDataCache.set(key, body);
|
|
50
50
|
res.status(200).end();
|
|
51
51
|
}
|
|
52
52
|
break;
|
|
@@ -56,7 +56,7 @@ class BasicEditingDataService {
|
|
|
56
56
|
key,
|
|
57
57
|
};
|
|
58
58
|
sitecore_jss_1.debug.editing('storing editing data for %o: %o', previewData, data);
|
|
59
|
-
this.editingDataCache.set(key, data);
|
|
59
|
+
yield this.editingDataCache.set(key, data);
|
|
60
60
|
return { key };
|
|
61
61
|
});
|
|
62
62
|
}
|
|
@@ -69,7 +69,7 @@ class BasicEditingDataService {
|
|
|
69
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
70
|
const editingPreviewData = previewData;
|
|
71
71
|
sitecore_jss_1.debug.editing('retrieving editing data for %o', previewData);
|
|
72
|
-
return this.editingDataCache.get(editingPreviewData.key);
|
|
72
|
+
return yield this.editingDataCache.get(editingPreviewData.key);
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
}
|
|
@@ -12,6 +12,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.extractEditingData = exports.EditingRenderMiddleware = void 0;
|
|
13
13
|
const constants_1 = require("next/constants");
|
|
14
14
|
const sitecore_jss_1 = require("@sitecore-jss/sitecore-jss");
|
|
15
|
+
const layout_1 = require("@sitecore-jss/sitecore-jss/layout");
|
|
16
|
+
const node_html_parser_1 = require("node-html-parser");
|
|
15
17
|
const editing_data_service_1 = require("./editing-data-service");
|
|
16
18
|
const utils_1 = require("../utils");
|
|
17
19
|
/**
|
|
@@ -25,7 +27,7 @@ class EditingRenderMiddleware {
|
|
|
25
27
|
constructor(config) {
|
|
26
28
|
var _a, _b, _c, _d;
|
|
27
29
|
this.handler = (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
-
var _e;
|
|
30
|
+
var _e, _f;
|
|
29
31
|
const { method, query, body, headers } = req;
|
|
30
32
|
sitecore_jss_1.debug.editing('editing render middleware start: %o', {
|
|
31
33
|
method,
|
|
@@ -94,6 +96,12 @@ class EditingRenderMiddleware {
|
|
|
94
96
|
// certain route configurations (e.g. multiple catch-all routes).
|
|
95
97
|
// The following line will trick it into thinking we're SSR, thus avoiding any router.replace.
|
|
96
98
|
html = html.replace(constants_1.STATIC_PROPS_ID, constants_1.SERVER_PROPS_ID);
|
|
99
|
+
if (editingData.layoutData.sitecore.context.renderingType === layout_1.RenderingType.Component) {
|
|
100
|
+
// Handle component rendering. Extract component markup only
|
|
101
|
+
html = (_f = node_html_parser_1.parse(html).getElementById(layout_1.EDITING_COMPONENT_ID)) === null || _f === void 0 ? void 0 : _f.innerHTML;
|
|
102
|
+
if (!html)
|
|
103
|
+
throw new Error(`Failed to render component for ${requestUrl}`);
|
|
104
|
+
}
|
|
97
105
|
const body = { html };
|
|
98
106
|
// Return expected JSON result
|
|
99
107
|
sitecore_jss_1.debug.editing('editing render middleware end: %o', { status: 200, body });
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.useSitecoreContext = exports.withSitecoreContext = exports.SitecoreContextReactContext = exports.SitecoreContext = exports.VisitorIdentification = exports.File = exports.DateField = exports.Text = exports.Image = exports.NextImage = exports.EditingComponentPlaceholder = exports.Placeholder = exports.RichText = exports.Link = exports.getPublicUrl = exports.handleEditorFastRefresh = exports.useComponentProps = exports.ComponentPropsContext = exports.ComponentPropsReactContext = exports.GraphQLErrorPagesService = exports.GraphQLSitemapXmlService = exports.GraphQLSitemapService = exports.DisconnectedSitemapService = exports.ComponentPropsService = exports.GraphQLRequestClient = exports.GraphQLRobotsService = exports.CdpHelper = exports.normalizePersonalizedRewrite = exports.getPersonalizedRewriteData = exports.getPersonalizedRewrite = exports.personalizeLayout = exports.RestDictionaryService = exports.GraphQLDictionaryService = exports.trackingApi = exports.mediaApi = exports.EDITING_COMPONENT_ID = exports.EDITING_COMPONENT_PLACEHOLDER = exports.RenderingType = exports.getFieldValue = exports.getChildPlaceholder = exports.RestLayoutService = exports.GraphQLLayoutService = exports.LayoutServicePageState = exports.resolveUrl = exports.resetEditorChromes = exports.isEditorActive = exports.enableDebug = exports.NativeDataFetcher = exports.AxiosDataFetcher = exports.constants = void 0;
|
|
4
|
+
exports.withDatasourceCheck = exports.withPlaceholder = exports.withEditorChromes = void 0;
|
|
4
5
|
var sitecore_jss_1 = require("@sitecore-jss/sitecore-jss");
|
|
5
6
|
Object.defineProperty(exports, "constants", { enumerable: true, get: function () { return sitecore_jss_1.constants; } });
|
|
6
7
|
Object.defineProperty(exports, "AxiosDataFetcher", { enumerable: true, get: function () { return sitecore_jss_1.AxiosDataFetcher; } });
|
|
@@ -10,13 +11,15 @@ var utils_1 = require("@sitecore-jss/sitecore-jss/utils");
|
|
|
10
11
|
Object.defineProperty(exports, "isEditorActive", { enumerable: true, get: function () { return utils_1.isEditorActive; } });
|
|
11
12
|
Object.defineProperty(exports, "resetEditorChromes", { enumerable: true, get: function () { return utils_1.resetEditorChromes; } });
|
|
12
13
|
Object.defineProperty(exports, "resolveUrl", { enumerable: true, get: function () { return utils_1.resolveUrl; } });
|
|
13
|
-
Object.defineProperty(exports, "EnvHelper", { enumerable: true, get: function () { return utils_1.EnvHelper; } });
|
|
14
14
|
var layout_1 = require("@sitecore-jss/sitecore-jss/layout");
|
|
15
15
|
Object.defineProperty(exports, "LayoutServicePageState", { enumerable: true, get: function () { return layout_1.LayoutServicePageState; } });
|
|
16
16
|
Object.defineProperty(exports, "GraphQLLayoutService", { enumerable: true, get: function () { return layout_1.GraphQLLayoutService; } });
|
|
17
17
|
Object.defineProperty(exports, "RestLayoutService", { enumerable: true, get: function () { return layout_1.RestLayoutService; } });
|
|
18
18
|
Object.defineProperty(exports, "getChildPlaceholder", { enumerable: true, get: function () { return layout_1.getChildPlaceholder; } });
|
|
19
19
|
Object.defineProperty(exports, "getFieldValue", { enumerable: true, get: function () { return layout_1.getFieldValue; } });
|
|
20
|
+
Object.defineProperty(exports, "RenderingType", { enumerable: true, get: function () { return layout_1.RenderingType; } });
|
|
21
|
+
Object.defineProperty(exports, "EDITING_COMPONENT_PLACEHOLDER", { enumerable: true, get: function () { return layout_1.EDITING_COMPONENT_PLACEHOLDER; } });
|
|
22
|
+
Object.defineProperty(exports, "EDITING_COMPONENT_ID", { enumerable: true, get: function () { return layout_1.EDITING_COMPONENT_ID; } });
|
|
20
23
|
var media_1 = require("@sitecore-jss/sitecore-jss/media");
|
|
21
24
|
Object.defineProperty(exports, "mediaApi", { enumerable: true, get: function () { return media_1.mediaApi; } });
|
|
22
25
|
var tracking_1 = require("@sitecore-jss/sitecore-jss/tracking");
|
|
@@ -56,6 +59,8 @@ var RichText_1 = require("./components/RichText");
|
|
|
56
59
|
Object.defineProperty(exports, "RichText", { enumerable: true, get: function () { return RichText_1.RichText; } });
|
|
57
60
|
var Placeholder_1 = require("./components/Placeholder");
|
|
58
61
|
Object.defineProperty(exports, "Placeholder", { enumerable: true, get: function () { return Placeholder_1.Placeholder; } });
|
|
62
|
+
var EditingComponentPlaceholder_1 = require("./components/EditingComponentPlaceholder");
|
|
63
|
+
Object.defineProperty(exports, "EditingComponentPlaceholder", { enumerable: true, get: function () { return EditingComponentPlaceholder_1.EditingComponentPlaceholder; } });
|
|
59
64
|
var NextImage_1 = require("./components/NextImage");
|
|
60
65
|
Object.defineProperty(exports, "NextImage", { enumerable: true, get: function () { return NextImage_1.NextImage; } });
|
|
61
66
|
var sitecore_jss_react_1 = require("@sitecore-jss/sitecore-jss-react");
|
|
@@ -38,7 +38,8 @@ class PersonalizeMiddleware {
|
|
|
38
38
|
}
|
|
39
39
|
if (response.redirected || // Don't attempt to personalize a redirect
|
|
40
40
|
this.isPreview(req) || // No need to personalize for preview (layout data is already prepared for preview)
|
|
41
|
-
|
|
41
|
+
this.excludeRoute(pathname) ||
|
|
42
|
+
(this.config.excludeRoute && this.config.excludeRoute(pathname))) {
|
|
42
43
|
sitecore_jss_1.debug.personalize('skipped (%s)', response.redirected ? 'redirected' : this.isPreview(req) ? 'preview' : 'route excluded');
|
|
43
44
|
return response;
|
|
44
45
|
}
|
|
@@ -95,10 +96,11 @@ class PersonalizeMiddleware {
|
|
|
95
96
|
// (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
|
|
96
97
|
this.personalizeService = new personalize_1.GraphQLPersonalizeService(Object.assign(Object.assign({}, config.edgeConfig), { fetch: fetch }));
|
|
97
98
|
// NOTE: same here, we provide NativeDataFetcher for compatibility on Next.js Edge Runtime
|
|
98
|
-
this.cdpService = new personalize_1.CdpService(Object.assign(Object.assign({}, config.cdpConfig), { dataFetcherResolver: ({ timeout }) => {
|
|
99
|
+
this.cdpService = new personalize_1.CdpService(Object.assign(Object.assign({}, config.cdpConfig), { dataFetcherResolver: ({ timeout, headers, }) => {
|
|
99
100
|
const fetcher = new sitecore_jss_1.NativeDataFetcher({
|
|
100
101
|
debugger: sitecore_jss_1.debug.personalize,
|
|
101
102
|
timeout,
|
|
103
|
+
headers,
|
|
102
104
|
});
|
|
103
105
|
return (url, data) => fetcher.fetch(url, data);
|
|
104
106
|
} }));
|
|
@@ -25,7 +25,13 @@ class RedirectsMiddleware {
|
|
|
25
25
|
* @param {RedirectsMiddlewareConfig} [config] redirects middleware config
|
|
26
26
|
*/
|
|
27
27
|
constructor(config) {
|
|
28
|
+
this.config = config;
|
|
28
29
|
this.handler = (req) => __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
if ((this.config.disabled && this.config.disabled(req, server_1.NextResponse.next())) ||
|
|
31
|
+
this.excludeRoute(req.nextUrl.pathname) ||
|
|
32
|
+
(this.config.excludeRoute && this.config.excludeRoute(req.nextUrl.pathname))) {
|
|
33
|
+
return server_1.NextResponse.next();
|
|
34
|
+
}
|
|
29
35
|
// Find the redirect from result of RedirectService
|
|
30
36
|
const existsRedirect = yield this.getExistsRedirect(req);
|
|
31
37
|
if (!existsRedirect) {
|
|
@@ -73,6 +79,16 @@ class RedirectsMiddleware {
|
|
|
73
79
|
getHandler() {
|
|
74
80
|
return this.handler;
|
|
75
81
|
}
|
|
82
|
+
excludeRoute(pathname) {
|
|
83
|
+
if (pathname.includes('.') || // Ignore files
|
|
84
|
+
pathname.startsWith('/api/') || // Ignore Next.js API calls
|
|
85
|
+
pathname.startsWith('/sitecore/') || // Ignore Sitecore API calls
|
|
86
|
+
pathname.startsWith('/_next') // Ignore next service calls
|
|
87
|
+
) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
76
92
|
/**
|
|
77
93
|
* Method returns RedirectInfo when matches
|
|
78
94
|
* @param {NextRequest} req
|
|
@@ -82,13 +98,15 @@ class RedirectsMiddleware {
|
|
|
82
98
|
getExistsRedirect(req) {
|
|
83
99
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
100
|
const redirects = yield this.redirectsService.fetchRedirects();
|
|
85
|
-
return redirects.
|
|
86
|
-
|
|
87
|
-
regex_parser_1.default(redirect.pattern.toLowerCase()).test(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
101
|
+
return redirects.length
|
|
102
|
+
? redirects.find((redirect) => {
|
|
103
|
+
return ((regex_parser_1.default(redirect.pattern.toLowerCase()).test(req.nextUrl.pathname.toLowerCase()) ||
|
|
104
|
+
regex_parser_1.default(redirect.pattern.toLowerCase()).test(`/${req.nextUrl.locale}${req.nextUrl.pathname}`.toLowerCase())) &&
|
|
105
|
+
(redirect.locale
|
|
106
|
+
? redirect.locale.toLowerCase() === req.nextUrl.locale.toLowerCase()
|
|
107
|
+
: true));
|
|
108
|
+
})
|
|
109
|
+
: undefined;
|
|
92
110
|
});
|
|
93
111
|
}
|
|
94
112
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.HealthcheckMiddleware = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* Middleware / handler for use in healthcheck Next.js API route (e.g. '/api/healthz').
|
|
15
|
+
*/
|
|
16
|
+
class HealthcheckMiddleware {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.handler = (_req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
res.status(200).send('Healthy');
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Gets the Next.js API route handler
|
|
24
|
+
* @returns route handler
|
|
25
|
+
*/
|
|
26
|
+
getHandler() {
|
|
27
|
+
return this.handler;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.HealthcheckMiddleware = HealthcheckMiddleware;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HealthcheckMiddleware = void 0;
|
|
4
|
+
var healthcheck_middleware_1 = require("./healthcheck-middleware");
|
|
5
|
+
Object.defineProperty(exports, "HealthcheckMiddleware", { enumerable: true, get: function () { return healthcheck_middleware_1.HealthcheckMiddleware; } });
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { EDITING_COMPONENT_ID, EDITING_COMPONENT_PLACEHOLDER, } from '@sitecore-jss/sitecore-jss/layout';
|
|
3
|
+
import { Placeholder } from './Placeholder';
|
|
4
|
+
export const EditingComponentPlaceholder = ({ rendering, }) => (React.createElement("div", { id: EDITING_COMPONENT_ID },
|
|
5
|
+
React.createElement(Placeholder, { name: EDITING_COMPONENT_PLACEHOLDER, rendering: rendering })));
|
|
@@ -18,13 +18,13 @@ export const Link = forwardRef((props, ref) => {
|
|
|
18
18
|
const value = (field.href
|
|
19
19
|
? field
|
|
20
20
|
: field.value);
|
|
21
|
-
const { href, querystring } = value;
|
|
21
|
+
const { href, querystring, anchor } = value;
|
|
22
22
|
const isEditing = editable && field.editable;
|
|
23
23
|
if (href && !isEditing) {
|
|
24
24
|
const text = showLinkTextWithChildrenPresent || !children ? value.text || value.href : null;
|
|
25
25
|
// determine if a link is a route or not.
|
|
26
26
|
if (internalLinkMatcher.test(href)) {
|
|
27
|
-
return (React.createElement(NextLink, { href: { pathname: href, query: querystring }, key: "link", locale: false },
|
|
27
|
+
return (React.createElement(NextLink, { href: { pathname: href, query: querystring, hash: anchor }, key: "link", locale: false },
|
|
28
28
|
React.createElement("a", Object.assign({ title: value.title, target: value.target, className: value.class }, htmlLinkProps, { ref: ref }),
|
|
29
29
|
text,
|
|
30
30
|
children)));
|
|
@@ -16,19 +16,24 @@ export class EditingDataDiskCache {
|
|
|
16
16
|
}
|
|
17
17
|
set(key, editingData) {
|
|
18
18
|
const filePath = this.cache.set(key, JSON.stringify(editingData));
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
if (!filePath || filePath.length === 0) {
|
|
21
|
+
reject(new Error(`Editing data cache not set for key ${key} at ${this.cache.root}`));
|
|
22
|
+
}
|
|
23
|
+
resolve();
|
|
24
|
+
});
|
|
22
25
|
}
|
|
23
26
|
get(key) {
|
|
24
27
|
const entry = this.cache.get(key);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
if (!entry.isCached) {
|
|
30
|
+
console.warn(`Editing data cache miss for key ${key} at ${this.cache.root}`);
|
|
31
|
+
resolve(undefined);
|
|
32
|
+
}
|
|
33
|
+
// Remove to preserve disk-space (as a macrotask so as not to block current execution)
|
|
34
|
+
setTimeout(() => this.cache.remove(key));
|
|
35
|
+
resolve(JSON.parse(entry.value));
|
|
36
|
+
});
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
39
|
/** EditingDataDiskCache singleton */
|
|
@@ -33,7 +33,7 @@ export class EditingDataMiddleware {
|
|
|
33
33
|
switch (method) {
|
|
34
34
|
case 'GET': {
|
|
35
35
|
// Get cache value
|
|
36
|
-
const data = this.editingDataCache.get(key);
|
|
36
|
+
const data = yield this.editingDataCache.get(key);
|
|
37
37
|
res.status(200).json(data);
|
|
38
38
|
break;
|
|
39
39
|
}
|
|
@@ -43,7 +43,7 @@ export class EditingDataMiddleware {
|
|
|
43
43
|
}
|
|
44
44
|
else {
|
|
45
45
|
// Set cache value
|
|
46
|
-
this.editingDataCache.set(key, body);
|
|
46
|
+
yield this.editingDataCache.set(key, body);
|
|
47
47
|
res.status(200).end();
|
|
48
48
|
}
|
|
49
49
|
break;
|
|
@@ -52,7 +52,7 @@ export class BasicEditingDataService {
|
|
|
52
52
|
key,
|
|
53
53
|
};
|
|
54
54
|
debug.editing('storing editing data for %o: %o', previewData, data);
|
|
55
|
-
this.editingDataCache.set(key, data);
|
|
55
|
+
yield this.editingDataCache.set(key, data);
|
|
56
56
|
return { key };
|
|
57
57
|
});
|
|
58
58
|
}
|
|
@@ -65,7 +65,7 @@ export class BasicEditingDataService {
|
|
|
65
65
|
return __awaiter(this, void 0, void 0, function* () {
|
|
66
66
|
const editingPreviewData = previewData;
|
|
67
67
|
debug.editing('retrieving editing data for %o', previewData);
|
|
68
|
-
return this.editingDataCache.get(editingPreviewData.key);
|
|
68
|
+
return yield this.editingDataCache.get(editingPreviewData.key);
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -9,6 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { STATIC_PROPS_ID, SERVER_PROPS_ID } from 'next/constants';
|
|
11
11
|
import { AxiosDataFetcher, debug } from '@sitecore-jss/sitecore-jss';
|
|
12
|
+
import { EDITING_COMPONENT_ID, RenderingType } from '@sitecore-jss/sitecore-jss/layout';
|
|
13
|
+
import { parse } from 'node-html-parser';
|
|
12
14
|
import { editingDataService, QUERY_PARAM_EDITING_SECRET, } from './editing-data-service';
|
|
13
15
|
import { getJssEditingSecret } from '../utils';
|
|
14
16
|
/**
|
|
@@ -22,7 +24,7 @@ export class EditingRenderMiddleware {
|
|
|
22
24
|
constructor(config) {
|
|
23
25
|
var _a, _b, _c, _d;
|
|
24
26
|
this.handler = (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
25
|
-
var _e;
|
|
27
|
+
var _e, _f;
|
|
26
28
|
const { method, query, body, headers } = req;
|
|
27
29
|
debug.editing('editing render middleware start: %o', {
|
|
28
30
|
method,
|
|
@@ -91,6 +93,12 @@ export class EditingRenderMiddleware {
|
|
|
91
93
|
// certain route configurations (e.g. multiple catch-all routes).
|
|
92
94
|
// The following line will trick it into thinking we're SSR, thus avoiding any router.replace.
|
|
93
95
|
html = html.replace(STATIC_PROPS_ID, SERVER_PROPS_ID);
|
|
96
|
+
if (editingData.layoutData.sitecore.context.renderingType === RenderingType.Component) {
|
|
97
|
+
// Handle component rendering. Extract component markup only
|
|
98
|
+
html = (_f = parse(html).getElementById(EDITING_COMPONENT_ID)) === null || _f === void 0 ? void 0 : _f.innerHTML;
|
|
99
|
+
if (!html)
|
|
100
|
+
throw new Error(`Failed to render component for ${requestUrl}`);
|
|
101
|
+
}
|
|
94
102
|
const body = { html };
|
|
95
103
|
// Return expected JSON result
|
|
96
104
|
debug.editing('editing render middleware end: %o', { status: 200, body });
|
package/dist/esm/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { constants, AxiosDataFetcher, NativeDataFetcher, enableDebug, } from '@sitecore-jss/sitecore-jss';
|
|
2
|
-
export { isEditorActive, resetEditorChromes, resolveUrl
|
|
3
|
-
export { LayoutServicePageState, GraphQLLayoutService, RestLayoutService, getChildPlaceholder, getFieldValue, } from '@sitecore-jss/sitecore-jss/layout';
|
|
2
|
+
export { isEditorActive, resetEditorChromes, resolveUrl } from '@sitecore-jss/sitecore-jss/utils';
|
|
3
|
+
export { LayoutServicePageState, GraphQLLayoutService, RestLayoutService, getChildPlaceholder, getFieldValue, RenderingType, EDITING_COMPONENT_PLACEHOLDER, EDITING_COMPONENT_ID, } from '@sitecore-jss/sitecore-jss/layout';
|
|
4
4
|
export { mediaApi } from '@sitecore-jss/sitecore-jss/media';
|
|
5
5
|
export { trackingApi, } from '@sitecore-jss/sitecore-jss/tracking';
|
|
6
6
|
export { GraphQLDictionaryService, RestDictionaryService, } from '@sitecore-jss/sitecore-jss/i18n';
|
|
@@ -16,5 +16,6 @@ export { handleEditorFastRefresh, getPublicUrl } from './utils';
|
|
|
16
16
|
export { Link } from './components/Link';
|
|
17
17
|
export { RichText } from './components/RichText';
|
|
18
18
|
export { Placeholder } from './components/Placeholder';
|
|
19
|
+
export { EditingComponentPlaceholder } from './components/EditingComponentPlaceholder';
|
|
19
20
|
export { NextImage } from './components/NextImage';
|
|
20
21
|
export { Image, Text, DateField, File, VisitorIdentification, SitecoreContext, SitecoreContextReactContext, withSitecoreContext, useSitecoreContext, withEditorChromes, withPlaceholder, withDatasourceCheck, } from '@sitecore-jss/sitecore-jss-react';
|
|
@@ -35,7 +35,8 @@ export class PersonalizeMiddleware {
|
|
|
35
35
|
}
|
|
36
36
|
if (response.redirected || // Don't attempt to personalize a redirect
|
|
37
37
|
this.isPreview(req) || // No need to personalize for preview (layout data is already prepared for preview)
|
|
38
|
-
|
|
38
|
+
this.excludeRoute(pathname) ||
|
|
39
|
+
(this.config.excludeRoute && this.config.excludeRoute(pathname))) {
|
|
39
40
|
debug.personalize('skipped (%s)', response.redirected ? 'redirected' : this.isPreview(req) ? 'preview' : 'route excluded');
|
|
40
41
|
return response;
|
|
41
42
|
}
|
|
@@ -92,10 +93,11 @@ export class PersonalizeMiddleware {
|
|
|
92
93
|
// (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
|
|
93
94
|
this.personalizeService = new GraphQLPersonalizeService(Object.assign(Object.assign({}, config.edgeConfig), { fetch: fetch }));
|
|
94
95
|
// NOTE: same here, we provide NativeDataFetcher for compatibility on Next.js Edge Runtime
|
|
95
|
-
this.cdpService = new CdpService(Object.assign(Object.assign({}, config.cdpConfig), { dataFetcherResolver: ({ timeout }) => {
|
|
96
|
+
this.cdpService = new CdpService(Object.assign(Object.assign({}, config.cdpConfig), { dataFetcherResolver: ({ timeout, headers, }) => {
|
|
96
97
|
const fetcher = new NativeDataFetcher({
|
|
97
98
|
debugger: debug.personalize,
|
|
98
99
|
timeout,
|
|
100
|
+
headers,
|
|
99
101
|
});
|
|
100
102
|
return (url, data) => fetcher.fetch(url, data);
|
|
101
103
|
} }));
|
|
@@ -19,7 +19,13 @@ export class RedirectsMiddleware {
|
|
|
19
19
|
* @param {RedirectsMiddlewareConfig} [config] redirects middleware config
|
|
20
20
|
*/
|
|
21
21
|
constructor(config) {
|
|
22
|
+
this.config = config;
|
|
22
23
|
this.handler = (req) => __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
if ((this.config.disabled && this.config.disabled(req, NextResponse.next())) ||
|
|
25
|
+
this.excludeRoute(req.nextUrl.pathname) ||
|
|
26
|
+
(this.config.excludeRoute && this.config.excludeRoute(req.nextUrl.pathname))) {
|
|
27
|
+
return NextResponse.next();
|
|
28
|
+
}
|
|
23
29
|
// Find the redirect from result of RedirectService
|
|
24
30
|
const existsRedirect = yield this.getExistsRedirect(req);
|
|
25
31
|
if (!existsRedirect) {
|
|
@@ -67,6 +73,16 @@ export class RedirectsMiddleware {
|
|
|
67
73
|
getHandler() {
|
|
68
74
|
return this.handler;
|
|
69
75
|
}
|
|
76
|
+
excludeRoute(pathname) {
|
|
77
|
+
if (pathname.includes('.') || // Ignore files
|
|
78
|
+
pathname.startsWith('/api/') || // Ignore Next.js API calls
|
|
79
|
+
pathname.startsWith('/sitecore/') || // Ignore Sitecore API calls
|
|
80
|
+
pathname.startsWith('/_next') // Ignore next service calls
|
|
81
|
+
) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
70
86
|
/**
|
|
71
87
|
* Method returns RedirectInfo when matches
|
|
72
88
|
* @param {NextRequest} req
|
|
@@ -76,13 +92,15 @@ export class RedirectsMiddleware {
|
|
|
76
92
|
getExistsRedirect(req) {
|
|
77
93
|
return __awaiter(this, void 0, void 0, function* () {
|
|
78
94
|
const redirects = yield this.redirectsService.fetchRedirects();
|
|
79
|
-
return redirects.
|
|
80
|
-
|
|
81
|
-
regexParser(redirect.pattern.toLowerCase()).test(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
95
|
+
return redirects.length
|
|
96
|
+
? redirects.find((redirect) => {
|
|
97
|
+
return ((regexParser(redirect.pattern.toLowerCase()).test(req.nextUrl.pathname.toLowerCase()) ||
|
|
98
|
+
regexParser(redirect.pattern.toLowerCase()).test(`/${req.nextUrl.locale}${req.nextUrl.pathname}`.toLowerCase())) &&
|
|
99
|
+
(redirect.locale
|
|
100
|
+
? redirect.locale.toLowerCase() === req.nextUrl.locale.toLowerCase()
|
|
101
|
+
: true));
|
|
102
|
+
})
|
|
103
|
+
: undefined;
|
|
86
104
|
});
|
|
87
105
|
}
|
|
88
106
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
/**
|
|
11
|
+
* Middleware / handler for use in healthcheck Next.js API route (e.g. '/api/healthz').
|
|
12
|
+
*/
|
|
13
|
+
export class HealthcheckMiddleware {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.handler = (_req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
res.status(200).send('Healthy');
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Gets the Next.js API route handler
|
|
21
|
+
* @returns route handler
|
|
22
|
+
*/
|
|
23
|
+
getHandler() {
|
|
24
|
+
return this.handler;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { HealthcheckMiddleware } from './healthcheck-middleware';
|
package/monitoring.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types/monitoring/index';
|
package/monitoring.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/cjs/monitoring/index');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sitecore-jss/sitecore-jss-nextjs",
|
|
3
|
-
"version": "21.1.0-canary.
|
|
3
|
+
"version": "21.1.0-canary.60",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -11,7 +11,7 @@
|
|
|
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/editing/index.ts --entryPoints src/middleware/index.ts --githubPages false"
|
|
14
|
+
"generate-docs": "npx typedoc --plugin typedoc-plugin-markdown --readme none --out ../../ref-docs/sitecore-jss-nextjs --entryPoints src/index.ts --entryPoints src/monitoring/index.ts --entryPoints src/editing/index.ts --entryPoints src/middleware/index.ts --githubPages false"
|
|
15
15
|
},
|
|
16
16
|
"engines": {
|
|
17
17
|
"node": ">=12",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"@types/enzyme": "^3.10.12",
|
|
37
37
|
"@types/mocha": "^9.0.0",
|
|
38
38
|
"@types/node": "17.0.40",
|
|
39
|
-
"@types/prop-types": "^15.7.
|
|
40
|
-
"@types/react": "^18.0.
|
|
39
|
+
"@types/prop-types": "^15.7.5",
|
|
40
|
+
"@types/react": "^18.0.25",
|
|
41
41
|
"@types/react-dom": "^18.0.5",
|
|
42
42
|
"@types/sinon": "^7.5.0",
|
|
43
43
|
"@types/sinon-chai": "^3.2.5",
|
|
@@ -54,32 +54,33 @@
|
|
|
54
54
|
"eslint-plugin-react": "^7.21.5",
|
|
55
55
|
"jsdom": "^15.1.1",
|
|
56
56
|
"mocha": "^9.1.3",
|
|
57
|
-
"next": "^12.
|
|
57
|
+
"next": "^12.3.1",
|
|
58
58
|
"nock": "^13.0.5",
|
|
59
59
|
"nyc": "^15.1.0",
|
|
60
|
-
"react": "^18.
|
|
61
|
-
"react-dom": "^18.
|
|
60
|
+
"react": "^18.2.0",
|
|
61
|
+
"react-dom": "^18.2.0",
|
|
62
62
|
"sinon": "^7.5.0",
|
|
63
63
|
"sinon-chai": "^3.7.0",
|
|
64
64
|
"ts-node": "^9.0.0",
|
|
65
65
|
"typescript": "~4.3.5"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
|
-
"next": "^12.
|
|
69
|
-
"react": "^18.
|
|
70
|
-
"react-dom": "^18.
|
|
68
|
+
"next": "^12.3.1",
|
|
69
|
+
"react": "^18.2.0",
|
|
70
|
+
"react-dom": "^18.2.0"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@sitecore-jss/sitecore-jss": "^21.1.0-canary.
|
|
74
|
-
"@sitecore-jss/sitecore-jss-dev-tools": "^21.1.0-canary.
|
|
75
|
-
"@sitecore-jss/sitecore-jss-react": "^21.1.0-canary.
|
|
76
|
-
"
|
|
73
|
+
"@sitecore-jss/sitecore-jss": "^21.1.0-canary.60",
|
|
74
|
+
"@sitecore-jss/sitecore-jss-dev-tools": "^21.1.0-canary.60",
|
|
75
|
+
"@sitecore-jss/sitecore-jss-react": "^21.1.0-canary.60",
|
|
76
|
+
"node-html-parser": "^6.0.0",
|
|
77
|
+
"prop-types": "^15.8.1",
|
|
77
78
|
"regex-parser": "^2.2.11",
|
|
78
79
|
"sync-disk-cache": "^2.1.0"
|
|
79
80
|
},
|
|
80
81
|
"description": "",
|
|
81
82
|
"types": "types/index.d.ts",
|
|
82
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "1ae8f48c196cd6780cc95c08ddaf63b59084377c",
|
|
83
84
|
"files": [
|
|
84
85
|
"dist",
|
|
85
86
|
"types",
|
|
@@ -3,8 +3,8 @@ import { EditingData } from './editing-data';
|
|
|
3
3
|
* Defines an editing data cache implementation
|
|
4
4
|
*/
|
|
5
5
|
export interface EditingDataCache {
|
|
6
|
-
set(key: string, editingData: EditingData): void
|
|
7
|
-
get(key: string): EditingData | undefined
|
|
6
|
+
set(key: string, editingData: EditingData): Promise<void>;
|
|
7
|
+
get(key: string): Promise<EditingData | undefined>;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* A disk-based editing data cache implementation (required for hosting on Vercel via Serverless Functions)
|
|
@@ -16,8 +16,8 @@ export declare class EditingDataDiskCache implements EditingDataCache {
|
|
|
16
16
|
* @param {string} [tmpDir] Temp directory to use. Default is the OS temp directory (os.tmpdir()).
|
|
17
17
|
*/
|
|
18
18
|
constructor(tmpDir?: string);
|
|
19
|
-
set(key: string, editingData: EditingData): void
|
|
20
|
-
get(key: string): EditingData | undefined
|
|
19
|
+
set(key: string, editingData: EditingData): Promise<void>;
|
|
20
|
+
get(key: string): Promise<EditingData | undefined>;
|
|
21
21
|
}
|
|
22
22
|
/** EditingDataDiskCache singleton */
|
|
23
23
|
export declare const editingDataDiskCache: EditingDataDiskCache;
|
package/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { constants, HttpDataFetcher, HttpResponse, AxiosDataFetcher, AxiosDataFetcherConfig, NativeDataFetcher, NativeDataFetcherConfig, enableDebug, } from '@sitecore-jss/sitecore-jss';
|
|
2
|
-
export { isEditorActive, resetEditorChromes, resolveUrl
|
|
3
|
-
export { LayoutService, LayoutServiceData, LayoutServicePageState, LayoutServiceContext, LayoutServiceContextData, GraphQLLayoutService, GraphQLLayoutServiceConfig, RestLayoutService, RestLayoutServiceConfig, PlaceholderData, PlaceholdersData, RouteData, Field, Item, HtmlElementRendering, getChildPlaceholder, getFieldValue, ComponentRendering, ComponentFields, ComponentParams, } from '@sitecore-jss/sitecore-jss/layout';
|
|
2
|
+
export { isEditorActive, resetEditorChromes, resolveUrl } from '@sitecore-jss/sitecore-jss/utils';
|
|
3
|
+
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';
|
|
4
4
|
export { mediaApi } from '@sitecore-jss/sitecore-jss/media';
|
|
5
5
|
export { trackingApi, TrackingRequestOptions, CampaignInstance, GoalInstance, OutcomeInstance, EventInstance, PageViewInstance, } from '@sitecore-jss/sitecore-jss/tracking';
|
|
6
6
|
export { DictionaryPhrases, DictionaryService, GraphQLDictionaryService, GraphQLDictionaryServiceConfig, RestDictionaryService, RestDictionaryServiceConfig, } from '@sitecore-jss/sitecore-jss/i18n';
|
|
@@ -19,5 +19,6 @@ export { handleEditorFastRefresh, getPublicUrl } from './utils';
|
|
|
19
19
|
export { Link, LinkProps } from './components/Link';
|
|
20
20
|
export { RichText, RichTextProps } from './components/RichText';
|
|
21
21
|
export { Placeholder } from './components/Placeholder';
|
|
22
|
+
export { EditingComponentPlaceholder } from './components/EditingComponentPlaceholder';
|
|
22
23
|
export { NextImage } from './components/NextImage';
|
|
23
24
|
export { ComponentFactory, Image, ImageField, ImageFieldValue, ImageProps, LinkField, LinkFieldValue, Text, TextField, DateField, File, FileField, RichTextField, VisitorIdentification, PlaceholderComponentProps, SitecoreContext, SitecoreContextState, SitecoreContextValue, SitecoreContextReactContext, withSitecoreContext, useSitecoreContext, withEditorChromes, withPlaceholder, withDatasourceCheck, ImageSizeParameters, ComponentConsumerProps, WithSitecoreContextOptions, WithSitecoreContextProps, } from '@sitecore-jss/sitecore-jss-react';
|
|
@@ -5,12 +5,28 @@ import { GraphQLRedirectsServiceConfig } from '@sitecore-jss/sitecore-jss/site';
|
|
|
5
5
|
*/
|
|
6
6
|
export declare type RedirectsMiddlewareConfig = Omit<GraphQLRedirectsServiceConfig, 'fetch'> & {
|
|
7
7
|
locales: string[];
|
|
8
|
+
/**
|
|
9
|
+
* Function used to determine if route should be excluded from RedirectsMiddleware.
|
|
10
|
+
* By default, files (pathname.includes('.')), Next.js API routes (pathname.startsWith('/api/')), and Sitecore API routes (pathname.startsWith('/sitecore/')) are ignored.
|
|
11
|
+
* This is an important performance consideration since Next.js Edge middleware runs on every request.
|
|
12
|
+
* @param {string} pathname The pathname
|
|
13
|
+
* @returns {boolean} Whether to exclude the route from RedirectsMiddleware
|
|
14
|
+
*/
|
|
15
|
+
excludeRoute?: (pathname: string) => boolean;
|
|
16
|
+
/**
|
|
17
|
+
* function, determines if middleware should be turned off, based on cookie, header, or other considerations
|
|
18
|
+
* @param {NextRequest} [req] optional: request object from middleware handler
|
|
19
|
+
* @param {NextResponse} [res] optional: response object from middleware handler
|
|
20
|
+
* @returns {boolean} false by default
|
|
21
|
+
*/
|
|
22
|
+
disabled?: (req?: NextRequest, res?: NextResponse) => boolean;
|
|
8
23
|
};
|
|
9
24
|
/**
|
|
10
25
|
* Middleware / handler fetches all redirects from Sitecore instance by grapqhl service
|
|
11
26
|
* compares with current url and redirects to target url
|
|
12
27
|
*/
|
|
13
28
|
export declare class RedirectsMiddleware {
|
|
29
|
+
protected config: RedirectsMiddlewareConfig;
|
|
14
30
|
private redirectsService;
|
|
15
31
|
private locales;
|
|
16
32
|
/**
|
|
@@ -22,6 +38,7 @@ export declare class RedirectsMiddleware {
|
|
|
22
38
|
* @returns route handler
|
|
23
39
|
*/
|
|
24
40
|
getHandler(): (req: NextRequest) => Promise<NextResponse>;
|
|
41
|
+
protected excludeRoute(pathname: string): boolean;
|
|
25
42
|
private handler;
|
|
26
43
|
/**
|
|
27
44
|
* Method returns RedirectInfo when matches
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { NextApiResponse, NextApiRequest } from 'next';
|
|
2
|
+
/**
|
|
3
|
+
* Middleware / handler for use in healthcheck Next.js API route (e.g. '/api/healthz').
|
|
4
|
+
*/
|
|
5
|
+
export declare class HealthcheckMiddleware {
|
|
6
|
+
/**
|
|
7
|
+
* Gets the Next.js API route handler
|
|
8
|
+
* @returns route handler
|
|
9
|
+
*/
|
|
10
|
+
getHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
|
|
11
|
+
private handler;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { HealthcheckMiddleware } from './healthcheck-middleware';
|