@sitecore-jss/sitecore-jss-nextjs 22.1.0-canary.9 → 22.2.0-canary.1
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/Link.js +7 -3
- package/dist/cjs/components/NextImage.js +10 -5
- package/dist/cjs/components/RichText.js +2 -2
- package/dist/cjs/editing/constants.js +12 -3
- package/dist/cjs/editing/editing-config-middleware.js +8 -0
- package/dist/cjs/editing/editing-data-middleware.js +6 -0
- package/dist/cjs/editing/editing-render-middleware.js +229 -103
- package/dist/cjs/editing/feaas-render-middleware.js +8 -0
- package/dist/cjs/editing/index.js +4 -1
- package/dist/cjs/editing/render-middleware.js +18 -4
- package/dist/cjs/index.js +9 -7
- package/dist/cjs/middleware/middleware.js +12 -0
- package/dist/cjs/middleware/personalize-middleware.js +85 -25
- package/dist/cjs/services/base-graphql-sitemap-service.js +5 -4
- package/dist/cjs/utils/index.js +4 -3
- package/dist/cjs/utils/utils.js +3 -3
- package/dist/esm/components/Link.js +7 -3
- package/dist/esm/components/NextImage.js +11 -5
- package/dist/esm/components/RichText.js +2 -2
- package/dist/esm/editing/constants.js +11 -2
- package/dist/esm/editing/editing-config-middleware.js +9 -1
- package/dist/esm/editing/editing-data-middleware.js +7 -1
- package/dist/esm/editing/editing-render-middleware.js +227 -103
- package/dist/esm/editing/feaas-render-middleware.js +9 -1
- package/dist/esm/editing/index.js +2 -1
- package/dist/esm/editing/render-middleware.js +19 -5
- package/dist/esm/index.js +3 -4
- package/dist/esm/middleware/middleware.js +12 -0
- package/dist/esm/middleware/personalize-middleware.js +86 -26
- package/dist/esm/services/base-graphql-sitemap-service.js +5 -4
- package/dist/esm/utils/index.js +2 -1
- package/dist/esm/utils/utils.js +1 -1
- package/package.json +10 -11
- package/types/ComponentBuilder.d.ts +3 -5
- package/types/components/Placeholder.d.ts +7 -2
- package/types/components/RichText.d.ts +6 -0
- package/types/editing/constants.d.ts +11 -2
- package/types/editing/editing-config-middleware.d.ts +7 -0
- package/types/editing/editing-data-service.d.ts +1 -0
- package/types/editing/editing-render-middleware.d.ts +111 -23
- package/types/editing/index.d.ts +2 -1
- package/types/editing/render-middleware.d.ts +9 -0
- package/types/index.d.ts +3 -4
- package/types/middleware/middleware.d.ts +6 -0
- package/types/middleware/personalize-middleware.d.ts +22 -2
- package/types/services/base-graphql-sitemap-service.d.ts +3 -2
- package/types/utils/index.d.ts +2 -1
- package/dist/cjs/components/EditingComponentPlaceholder.js +0 -12
- package/dist/esm/components/EditingComponentPlaceholder.js +0 -5
- package/types/components/EditingComponentPlaceholder.d.ts +0 -4
package/dist/cjs/index.js
CHANGED
|
@@ -23,8 +23,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.DateField = exports.Text = exports.Image = exports.Context = exports.ComponentBuilder = exports.BYOCWrapper = exports.FEaaSWrapper = exports.NextImage = exports.
|
|
27
|
-
exports.withDatasourceCheck = exports.withPlaceholder = exports.withEditorChromes = exports.useSitecoreContext = exports.withSitecoreContext = exports.SitecoreContextReactContext = exports.SitecoreContext = exports.VisitorIdentification = exports.
|
|
26
|
+
exports.FEaaSComponent = exports.EditFrame = exports.DateField = exports.Text = exports.Image = exports.Context = 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.debug = exports.enableDebug = exports.NativeDataFetcher = exports.AxiosDataFetcher = 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.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
30
|
Object.defineProperty(exports, "AxiosDataFetcher", { enumerable: true, get: function () { return sitecore_jss_1.AxiosDataFetcher; } });
|
|
@@ -37,10 +37,8 @@ Object.defineProperty(exports, "GraphQLLayoutService", { enumerable: true, get:
|
|
|
37
37
|
Object.defineProperty(exports, "RestLayoutService", { enumerable: true, get: function () { return layout_1.RestLayoutService; } });
|
|
38
38
|
Object.defineProperty(exports, "getChildPlaceholder", { enumerable: true, get: function () { return layout_1.getChildPlaceholder; } });
|
|
39
39
|
Object.defineProperty(exports, "getFieldValue", { enumerable: true, get: function () { return layout_1.getFieldValue; } });
|
|
40
|
-
Object.defineProperty(exports, "RenderingType", { enumerable: true, get: function () { return layout_1.RenderingType; } });
|
|
41
|
-
Object.defineProperty(exports, "EDITING_COMPONENT_PLACEHOLDER", { enumerable: true, get: function () { return layout_1.EDITING_COMPONENT_PLACEHOLDER; } });
|
|
42
|
-
Object.defineProperty(exports, "EDITING_COMPONENT_ID", { enumerable: true, get: function () { return layout_1.EDITING_COMPONENT_ID; } });
|
|
43
40
|
Object.defineProperty(exports, "getContentStylesheetLink", { enumerable: true, get: function () { return layout_1.getContentStylesheetLink; } });
|
|
41
|
+
Object.defineProperty(exports, "EditMode", { enumerable: true, get: function () { return layout_1.EditMode; } });
|
|
44
42
|
var media_1 = require("@sitecore-jss/sitecore-jss/media");
|
|
45
43
|
Object.defineProperty(exports, "mediaApi", { enumerable: true, get: function () { return media_1.mediaApi; } });
|
|
46
44
|
var tracking_1 = require("@sitecore-jss/sitecore-jss/tracking");
|
|
@@ -52,6 +50,7 @@ var personalize_1 = require("@sitecore-jss/sitecore-jss/personalize");
|
|
|
52
50
|
Object.defineProperty(exports, "personalizeLayout", { enumerable: true, get: function () { return personalize_1.personalizeLayout; } });
|
|
53
51
|
Object.defineProperty(exports, "getPersonalizedRewrite", { enumerable: true, get: function () { return personalize_1.getPersonalizedRewrite; } });
|
|
54
52
|
Object.defineProperty(exports, "getPersonalizedRewriteData", { enumerable: true, get: function () { return personalize_1.getPersonalizedRewriteData; } });
|
|
53
|
+
Object.defineProperty(exports, "getGroomedVariantIds", { enumerable: true, get: function () { return personalize_1.getGroomedVariantIds; } });
|
|
55
54
|
Object.defineProperty(exports, "normalizePersonalizedRewrite", { enumerable: true, get: function () { return personalize_1.normalizePersonalizedRewrite; } });
|
|
56
55
|
Object.defineProperty(exports, "CdpHelper", { enumerable: true, get: function () { return personalize_1.CdpHelper; } });
|
|
57
56
|
var component_props_service_1 = require("./services/component-props-service");
|
|
@@ -81,8 +80,6 @@ var RichText_1 = require("./components/RichText");
|
|
|
81
80
|
Object.defineProperty(exports, "RichText", { enumerable: true, get: function () { return RichText_1.RichText; } });
|
|
82
81
|
var Placeholder_1 = require("./components/Placeholder");
|
|
83
82
|
Object.defineProperty(exports, "Placeholder", { enumerable: true, get: function () { return Placeholder_1.Placeholder; } });
|
|
84
|
-
var EditingComponentPlaceholder_1 = require("./components/EditingComponentPlaceholder");
|
|
85
|
-
Object.defineProperty(exports, "EditingComponentPlaceholder", { enumerable: true, get: function () { return EditingComponentPlaceholder_1.EditingComponentPlaceholder; } });
|
|
86
83
|
var NextImage_1 = require("./components/NextImage");
|
|
87
84
|
Object.defineProperty(exports, "NextImage", { enumerable: true, get: function () { return NextImage_1.NextImage; } });
|
|
88
85
|
const FEaaSWrapper = __importStar(require("./components/FEaaSWrapper"));
|
|
@@ -103,6 +100,8 @@ Object.defineProperty(exports, "fetchFEaaSComponentServerProps", { enumerable: t
|
|
|
103
100
|
Object.defineProperty(exports, "BYOCComponent", { enumerable: true, get: function () { return sitecore_jss_react_1.BYOCComponent; } });
|
|
104
101
|
Object.defineProperty(exports, "getComponentLibraryStylesheetLinks", { enumerable: true, get: function () { return sitecore_jss_react_1.getComponentLibraryStylesheetLinks; } });
|
|
105
102
|
Object.defineProperty(exports, "File", { enumerable: true, get: function () { return sitecore_jss_react_1.File; } });
|
|
103
|
+
Object.defineProperty(exports, "DefaultEmptyFieldEditingComponentImage", { enumerable: true, get: function () { return sitecore_jss_react_1.DefaultEmptyFieldEditingComponentImage; } });
|
|
104
|
+
Object.defineProperty(exports, "DefaultEmptyFieldEditingComponentText", { enumerable: true, get: function () { return sitecore_jss_react_1.DefaultEmptyFieldEditingComponentText; } });
|
|
106
105
|
Object.defineProperty(exports, "VisitorIdentification", { enumerable: true, get: function () { return sitecore_jss_react_1.VisitorIdentification; } });
|
|
107
106
|
Object.defineProperty(exports, "SitecoreContext", { enumerable: true, get: function () { return sitecore_jss_react_1.SitecoreContext; } });
|
|
108
107
|
Object.defineProperty(exports, "SitecoreContextReactContext", { enumerable: true, get: function () { return sitecore_jss_react_1.SitecoreContextReactContext; } });
|
|
@@ -111,3 +110,6 @@ Object.defineProperty(exports, "useSitecoreContext", { enumerable: true, get: fu
|
|
|
111
110
|
Object.defineProperty(exports, "withEditorChromes", { enumerable: true, get: function () { return sitecore_jss_react_1.withEditorChromes; } });
|
|
112
111
|
Object.defineProperty(exports, "withPlaceholder", { enumerable: true, get: function () { return sitecore_jss_react_1.withPlaceholder; } });
|
|
113
112
|
Object.defineProperty(exports, "withDatasourceCheck", { enumerable: true, get: function () { return sitecore_jss_react_1.withDatasourceCheck; } });
|
|
113
|
+
Object.defineProperty(exports, "withFieldMetadata", { enumerable: true, get: function () { return sitecore_jss_react_1.withFieldMetadata; } });
|
|
114
|
+
Object.defineProperty(exports, "withEmptyFieldEditingComponent", { enumerable: true, get: function () { return sitecore_jss_react_1.withEmptyFieldEditingComponent; } });
|
|
115
|
+
Object.defineProperty(exports, "EditingScripts", { enumerable: true, get: function () { return sitecore_jss_react_1.EditingScripts; } });
|
|
@@ -18,6 +18,18 @@ class MiddlewareBase {
|
|
|
18
18
|
var _a, _b;
|
|
19
19
|
return !!(((_a = req.cookies.get('__prerender_bypass')) === null || _a === void 0 ? void 0 : _a.value) || ((_b = req.cookies.get('__next_preview_data')) === null || _b === void 0 ? void 0 : _b.value));
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Determines if the request is a Next.js (next/link) prefetch request
|
|
23
|
+
* @param {NextRequest} req request
|
|
24
|
+
* @returns {boolean} is prefetch
|
|
25
|
+
*/
|
|
26
|
+
isPrefetch(req) {
|
|
27
|
+
return (
|
|
28
|
+
// eslint-disable-next-line prettier/prettier
|
|
29
|
+
req.headers.get('purpose') === 'prefetch' || // Pages Router
|
|
30
|
+
req.headers.get('Next-Router-Prefetch') === '1' // App Router
|
|
31
|
+
);
|
|
32
|
+
}
|
|
21
33
|
excludeRoute(pathname) {
|
|
22
34
|
var _a, _b;
|
|
23
35
|
return (pathname.startsWith('/api/') || // Ignore Next.js API calls
|
|
@@ -61,6 +61,15 @@ class PersonalizeMiddleware extends middleware_1.MiddlewareBase {
|
|
|
61
61
|
sitecore_jss_1.debug.personalize('skipped (no personalization configured)');
|
|
62
62
|
return response;
|
|
63
63
|
}
|
|
64
|
+
if (this.isPrefetch(req)) {
|
|
65
|
+
sitecore_jss_1.debug.personalize('skipped (prefetch)');
|
|
66
|
+
// Personalized, but this is a prefetch request.
|
|
67
|
+
// In this case, don't execute a personalize request; otherwise, the metrics for component A/B experiments would be inaccurate.
|
|
68
|
+
// Disable preflight caching to force revalidation on client-side navigation (personalization WILL be influenced).
|
|
69
|
+
// Note the reason we don't move this any earlier in the middleware is that we would then be sacrificing performance for non-personalized pages.
|
|
70
|
+
response.headers.set('x-middleware-cache', 'no-cache');
|
|
71
|
+
return response;
|
|
72
|
+
}
|
|
64
73
|
yield this.initPersonalizeServer({
|
|
65
74
|
hostname,
|
|
66
75
|
siteName: site.name,
|
|
@@ -68,32 +77,36 @@ class PersonalizeMiddleware extends middleware_1.MiddlewareBase {
|
|
|
68
77
|
response,
|
|
69
78
|
});
|
|
70
79
|
const params = this.getExperienceParams(req);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
80
|
+
const executions = this.getPersonalizeExecutions(personalizeInfo, language);
|
|
81
|
+
const identifiedVariantIds = [];
|
|
82
|
+
yield Promise.all(executions.map((execution) => this.personalize({
|
|
83
|
+
friendlyId: execution.friendlyId,
|
|
84
|
+
variantIds: execution.variantIds,
|
|
85
|
+
params,
|
|
86
|
+
language,
|
|
87
|
+
timeout,
|
|
88
|
+
}, req).then((personalization) => {
|
|
89
|
+
const variantId = personalization.variantId;
|
|
90
|
+
if (variantId) {
|
|
91
|
+
if (!execution.variantIds.includes(variantId)) {
|
|
92
|
+
sitecore_jss_1.debug.personalize('invalid variant %s', variantId);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
identifiedVariantIds.push(variantId);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
})));
|
|
99
|
+
if (identifiedVariantIds.length === 0) {
|
|
100
|
+
sitecore_jss_1.debug.personalize('skipped (no variant(s) identified)');
|
|
88
101
|
return response;
|
|
89
102
|
}
|
|
90
103
|
// Path can be rewritten by previously executed middleware
|
|
91
104
|
const basePath = (res === null || res === void 0 ? void 0 : res.headers.get('x-sc-rewrite')) || pathname;
|
|
92
105
|
// Rewrite to persononalized path
|
|
93
|
-
const rewritePath = (0, personalize_1.getPersonalizedRewrite)(basePath,
|
|
106
|
+
const rewritePath = (0, personalize_1.getPersonalizedRewrite)(basePath, identifiedVariantIds);
|
|
94
107
|
response = this.rewrite(rewritePath, req, response);
|
|
95
|
-
// Disable preflight caching to force revalidation on client-side navigation (personalization
|
|
96
|
-
// See https://github.com/vercel/next.js/
|
|
108
|
+
// Disable preflight caching to force revalidation on client-side navigation (personalization MAY be influenced).
|
|
109
|
+
// See https://github.com/vercel/next.js/pull/32767
|
|
97
110
|
response.headers.set('x-middleware-cache', 'no-cache');
|
|
98
111
|
sitecore_jss_1.debug.personalize('personalize middleware end in %dms: %o', Date.now() - startTimestamp, {
|
|
99
112
|
rewritePath,
|
|
@@ -132,17 +145,18 @@ class PersonalizeMiddleware extends middleware_1.MiddlewareBase {
|
|
|
132
145
|
});
|
|
133
146
|
});
|
|
134
147
|
}
|
|
135
|
-
personalize({ params,
|
|
148
|
+
personalize({ params, friendlyId, language, timeout, variantIds, }, request) {
|
|
136
149
|
var _a;
|
|
137
150
|
return __awaiter(this, void 0, void 0, function* () {
|
|
138
|
-
|
|
151
|
+
sitecore_jss_1.debug.personalize('executing experience for %s %o', friendlyId, params);
|
|
152
|
+
return (yield (0, server_2.personalize)(request, {
|
|
139
153
|
channel: this.config.cdpConfig.channel || 'WEB',
|
|
140
154
|
currency: (_a = this.config.cdpConfig.currency) !== null && _a !== void 0 ? _a : 'USD',
|
|
141
|
-
friendlyId
|
|
155
|
+
friendlyId,
|
|
142
156
|
params,
|
|
143
157
|
language,
|
|
144
|
-
|
|
145
|
-
|
|
158
|
+
pageVariantIds: variantIds,
|
|
159
|
+
}, { timeout }));
|
|
146
160
|
});
|
|
147
161
|
}
|
|
148
162
|
getExperienceParams(req) {
|
|
@@ -164,5 +178,51 @@ class PersonalizeMiddleware extends middleware_1.MiddlewareBase {
|
|
|
164
178
|
// ignore files
|
|
165
179
|
return pathname.includes('.') || super.excludeRoute(pathname);
|
|
166
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Aggregates personalize executions based on the provided route personalize information and language
|
|
183
|
+
* @param {PersonalizeInfo} personalizeInfo the route personalize information
|
|
184
|
+
* @param {string} language the language
|
|
185
|
+
* @returns An array of personalize executions
|
|
186
|
+
*/
|
|
187
|
+
getPersonalizeExecutions(personalizeInfo, language) {
|
|
188
|
+
if (personalizeInfo.variantIds.length === 0) {
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
const results = [];
|
|
192
|
+
return personalizeInfo.variantIds.reduce((results, variantId) => {
|
|
193
|
+
if (variantId.includes('_')) {
|
|
194
|
+
// Component-level personalization in format "<ComponentID>_<VariantID>"
|
|
195
|
+
const componentId = variantId.split('_')[0];
|
|
196
|
+
const friendlyId = personalize_1.CdpHelper.getComponentFriendlyId(personalizeInfo.pageId, componentId, language, this.config.scope || this.config.edgeConfig.scope);
|
|
197
|
+
const execution = results.find((x) => x.friendlyId === friendlyId);
|
|
198
|
+
if (execution) {
|
|
199
|
+
execution.variantIds.push(variantId);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
// The default/control variant (format "<ComponentID>_default") is also a valid value returned by the execution
|
|
203
|
+
const defaultVariant = `${componentId}${personalize_1.DEFAULT_VARIANT}`;
|
|
204
|
+
results.push({
|
|
205
|
+
friendlyId,
|
|
206
|
+
variantIds: [defaultVariant, variantId],
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
// Embedded (page-level) personalization in format "<VariantID>"
|
|
212
|
+
const friendlyId = personalize_1.CdpHelper.getPageFriendlyId(personalizeInfo.pageId, language, this.config.scope || this.config.edgeConfig.scope);
|
|
213
|
+
const execution = results.find((x) => x.friendlyId === friendlyId);
|
|
214
|
+
if (execution) {
|
|
215
|
+
execution.variantIds.push(variantId);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
results.push({
|
|
219
|
+
friendlyId,
|
|
220
|
+
variantIds: [variantId],
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return results;
|
|
225
|
+
}, results);
|
|
226
|
+
}
|
|
167
227
|
}
|
|
168
228
|
exports.PersonalizeMiddleware = PersonalizeMiddleware;
|
|
@@ -148,13 +148,14 @@ class BaseGraphQLSitemapService {
|
|
|
148
148
|
const formatPath = (path) => formatStaticPath(path.replace(/^\/|\/$/g, '').split('/'), language);
|
|
149
149
|
const aggregatedPaths = [];
|
|
150
150
|
sitePaths.forEach((item) => {
|
|
151
|
-
var _a, _b, _c
|
|
151
|
+
var _a, _b, _c;
|
|
152
152
|
if (!item)
|
|
153
153
|
return;
|
|
154
154
|
aggregatedPaths.push(formatPath(item.path));
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
const variantIds = (_c = (_b = (_a = item.route) === null || _a === void 0 ? void 0 : _a.personalization) === null || _b === void 0 ? void 0 : _b.variantIds) === null || _c === void 0 ? void 0 : _c.filter((variantId) => !variantId.includes('_') // exclude component A/B test variants
|
|
156
|
+
);
|
|
157
|
+
if (variantIds === null || variantIds === void 0 ? void 0 : variantIds.length) {
|
|
158
|
+
aggregatedPaths.push(...variantIds.map((varId) => formatPath((0, personalize_1.getPersonalizedRewrite)(item.path, [varId]))));
|
|
158
159
|
}
|
|
159
160
|
});
|
|
160
161
|
return aggregatedPaths;
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.resetEditorChromes = exports.isEditorActive = exports.resolveUrl = exports.tryParseEnvValue = exports.handleEditorFastRefresh = exports.getPublicUrl = void 0;
|
|
4
4
|
var utils_1 = require("./utils");
|
|
5
5
|
Object.defineProperty(exports, "getPublicUrl", { enumerable: true, get: function () { return utils_1.getPublicUrl; } });
|
|
6
6
|
Object.defineProperty(exports, "handleEditorFastRefresh", { enumerable: true, get: function () { return utils_1.handleEditorFastRefresh; } });
|
|
7
7
|
var utils_2 = require("@sitecore-jss/sitecore-jss/utils");
|
|
8
8
|
Object.defineProperty(exports, "tryParseEnvValue", { enumerable: true, get: function () { return utils_2.tryParseEnvValue; } });
|
|
9
|
-
Object.defineProperty(exports, "isEditorActive", { enumerable: true, get: function () { return utils_2.isEditorActive; } });
|
|
10
|
-
Object.defineProperty(exports, "resetEditorChromes", { enumerable: true, get: function () { return utils_2.resetEditorChromes; } });
|
|
11
9
|
Object.defineProperty(exports, "resolveUrl", { enumerable: true, get: function () { return utils_2.resolveUrl; } });
|
|
10
|
+
var editing_1 = require("@sitecore-jss/sitecore-jss/editing");
|
|
11
|
+
Object.defineProperty(exports, "isEditorActive", { enumerable: true, get: function () { return editing_1.isEditorActive; } });
|
|
12
|
+
Object.defineProperty(exports, "resetEditorChromes", { enumerable: true, get: function () { return editing_1.resetEditorChromes; } });
|
package/dist/cjs/utils/utils.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getJssEditingSecret = exports.handleEditorFastRefresh = exports.getPublicUrl = void 0;
|
|
4
|
-
const
|
|
4
|
+
const editing_1 = require("@sitecore-jss/sitecore-jss/editing");
|
|
5
5
|
/**
|
|
6
6
|
* Get the publicUrl.
|
|
7
7
|
* This is used primarily to enable compatibility with Sitecore editors.
|
|
@@ -32,7 +32,7 @@ exports.getPublicUrl = getPublicUrl;
|
|
|
32
32
|
* @default forceReload false
|
|
33
33
|
*/
|
|
34
34
|
const handleEditorFastRefresh = (forceReload = false) => {
|
|
35
|
-
if (process.env.NODE_ENV !== 'development' || !(0,
|
|
35
|
+
if (process.env.NODE_ENV !== 'development' || !(0, editing_1.isEditorActive)()) {
|
|
36
36
|
// Only run if development mode and editor is active
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
@@ -50,7 +50,7 @@ const handleEditorFastRefresh = (forceReload = false) => {
|
|
|
50
50
|
return window.location.reload();
|
|
51
51
|
setTimeout(() => {
|
|
52
52
|
console.log('[Sitecore Editor HMR Listener] Sitecore editor does not support Fast Refresh, reloading chromes...');
|
|
53
|
-
(0,
|
|
53
|
+
(0, editing_1.resetEditorChromes)();
|
|
54
54
|
}, 500);
|
|
55
55
|
};
|
|
56
56
|
};
|
|
@@ -16,14 +16,18 @@ import { Link as ReactLink, LinkPropTypes, } from '@sitecore-jss/sitecore-jss-re
|
|
|
16
16
|
export const Link = forwardRef((props, ref) => {
|
|
17
17
|
const { field, editable = true, children, internalLinkMatcher = /^\//g, showLinkTextWithChildrenPresent } = props, htmlLinkProps = __rest(props, ["field", "editable", "children", "internalLinkMatcher", "showLinkTextWithChildrenPresent"]);
|
|
18
18
|
if (!field ||
|
|
19
|
-
(!field.editable &&
|
|
19
|
+
(!field.editable &&
|
|
20
|
+
!field.value &&
|
|
21
|
+
!field.href &&
|
|
22
|
+
!field.metadata)) {
|
|
20
23
|
return null;
|
|
21
24
|
}
|
|
22
25
|
const value = (field.href
|
|
23
26
|
? field
|
|
24
27
|
: field.value);
|
|
25
|
-
|
|
26
|
-
const
|
|
28
|
+
// fallback to {} if value is undefined; could happen if field is LinkFieldValue, href is empty in metadata mode
|
|
29
|
+
const { href, querystring, anchor } = value || {};
|
|
30
|
+
const isEditing = editable && (field.editable || field.metadata);
|
|
27
31
|
if (href && !isEditing) {
|
|
28
32
|
const text = showLinkTextWithChildrenPresent || !children ? value.text || value.href : null;
|
|
29
33
|
// determine if a link is a route or not.
|
|
@@ -12,9 +12,12 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
import { mediaApi } from '@sitecore-jss/sitecore-jss/media';
|
|
13
13
|
import PropTypes from 'prop-types';
|
|
14
14
|
import React from 'react';
|
|
15
|
-
import { getEEMarkup, } from '@sitecore-jss/sitecore-jss-react';
|
|
15
|
+
import { getEEMarkup, withFieldMetadata, } from '@sitecore-jss/sitecore-jss-react';
|
|
16
16
|
import Image from 'next/image';
|
|
17
|
-
|
|
17
|
+
import { withEmptyFieldEditingComponent } from '@sitecore-jss/sitecore-jss-react';
|
|
18
|
+
import { DefaultEmptyFieldEditingComponentImage } from '@sitecore-jss/sitecore-jss-react';
|
|
19
|
+
import { isFieldValueEmpty } from '@sitecore-jss/sitecore-jss/layout';
|
|
20
|
+
export const NextImage = withFieldMetadata(withEmptyFieldEditingComponent((_a) => {
|
|
18
21
|
var { editable = true, imageParams, field, mediaUrlPrefix, fill, priority } = _a, otherProps = __rest(_a, ["editable", "imageParams", "field", "mediaUrlPrefix", "fill", "priority"]);
|
|
19
22
|
// next handles src and we use a custom loader,
|
|
20
23
|
// throw error if these are present
|
|
@@ -22,8 +25,7 @@ export const NextImage = (_a) => {
|
|
|
22
25
|
throw new Error('Detected src prop. If you wish to use src, use next/image directly.');
|
|
23
26
|
}
|
|
24
27
|
const dynamicMedia = field;
|
|
25
|
-
if (!field ||
|
|
26
|
-
(!dynamicMedia.editable && !dynamicMedia.value && !dynamicMedia.src)) {
|
|
28
|
+
if (!field || (!dynamicMedia.editable && isFieldValueEmpty(dynamicMedia))) {
|
|
27
29
|
return null;
|
|
28
30
|
}
|
|
29
31
|
const imageField = dynamicMedia;
|
|
@@ -53,7 +55,7 @@ export const NextImage = (_a) => {
|
|
|
53
55
|
return React.createElement(Image, Object.assign({ alt: "" }, imageProps));
|
|
54
56
|
}
|
|
55
57
|
return null; // we can't handle the truth
|
|
56
|
-
};
|
|
58
|
+
}, { defaultEmptyFieldEditingComponent: DefaultEmptyFieldEditingComponentImage }));
|
|
57
59
|
NextImage.propTypes = {
|
|
58
60
|
field: PropTypes.oneOfType([
|
|
59
61
|
PropTypes.shape({
|
|
@@ -67,5 +69,9 @@ NextImage.propTypes = {
|
|
|
67
69
|
editable: PropTypes.bool,
|
|
68
70
|
mediaUrlPrefix: PropTypes.instanceOf(RegExp),
|
|
69
71
|
imageParams: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.number.isRequired, PropTypes.string.isRequired]).isRequired),
|
|
72
|
+
emptyFieldEditingComponent: PropTypes.oneOfType([
|
|
73
|
+
PropTypes.object,
|
|
74
|
+
PropTypes.func,
|
|
75
|
+
]),
|
|
70
76
|
};
|
|
71
77
|
NextImage.displayName = 'NextImage';
|
|
@@ -17,7 +17,7 @@ const prefetched = {};
|
|
|
17
17
|
export const RichText = (props) => {
|
|
18
18
|
const { internalLinksSelector = 'a[href^="/"]', prefetchLinks = true, editable = true } = props, rest = __rest(props, ["internalLinksSelector", "prefetchLinks", "editable"]);
|
|
19
19
|
const hasText = props.field && props.field.value;
|
|
20
|
-
const isEditing = editable && props.field && props.field.editable;
|
|
20
|
+
const isEditing = editable && props.field && (props.field.editable || props.field.metadata);
|
|
21
21
|
const router = useRouter();
|
|
22
22
|
const richTextRef = useRef(null);
|
|
23
23
|
useEffect(() => {
|
|
@@ -49,7 +49,7 @@ export const RichText = (props) => {
|
|
|
49
49
|
link.addEventListener('click', routeHandler, false);
|
|
50
50
|
});
|
|
51
51
|
};
|
|
52
|
-
return React.createElement(ReactRichText, Object.assign({ ref: richTextRef }, rest));
|
|
52
|
+
return React.createElement(ReactRichText, Object.assign({ ref: richTextRef, editable: editable }, rest));
|
|
53
53
|
};
|
|
54
54
|
RichText.propTypes = Object.assign({ internalLinksSelector: PropTypes.string }, RichTextPropTypes);
|
|
55
55
|
RichText.displayName = 'NextRichText';
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
export const QUERY_PARAM_EDITING_SECRET = 'secret';
|
|
2
|
-
export const
|
|
3
|
-
export const
|
|
2
|
+
export const QUERY_PARAM_VERCEL_PROTECTION_BYPASS = 'x-vercel-protection-bypass';
|
|
3
|
+
export const QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE = 'x-vercel-set-bypass-cookie';
|
|
4
|
+
/**
|
|
5
|
+
* Headers that should be passed along to (Editing Chromes handler) SSR request.
|
|
6
|
+
* Note these are in lowercase format to match expected `IncomingHttpHeaders`.
|
|
7
|
+
*/
|
|
8
|
+
export const EDITING_PASS_THROUGH_HEADERS = ['authorization', 'cookie'];
|
|
9
|
+
/**
|
|
10
|
+
* Default allowed origins for editing requests. This is used to enforce CORS, CSP headers.
|
|
11
|
+
*/
|
|
12
|
+
export const EDITING_ALLOWED_ORIGINS = ['https://pages*.cloud', 'https://pages.sitecorecloud.io'];
|
|
@@ -7,9 +7,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { QUERY_PARAM_EDITING_SECRET } from './constants';
|
|
10
|
+
import { EDITING_ALLOWED_ORIGINS, QUERY_PARAM_EDITING_SECRET } from './constants';
|
|
11
11
|
import { getJssEditingSecret } from '../utils/utils';
|
|
12
12
|
import { debug } from '@sitecore-jss/sitecore-jss';
|
|
13
|
+
import { EditMode } from '@sitecore-jss/sitecore-jss/layout';
|
|
14
|
+
import { enforceCors } from '@sitecore-jss/sitecore-jss/utils';
|
|
13
15
|
/**
|
|
14
16
|
* Middleware / handler used in the editing config API route in xmcloud add on (e.g. '/api/editing/config')
|
|
15
17
|
* provides configuration information to determine feature compatibility on Pages side.
|
|
@@ -22,6 +24,10 @@ export class EditingConfigMiddleware {
|
|
|
22
24
|
this.config = config;
|
|
23
25
|
this.handler = (_req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
24
26
|
const secret = _req.query[QUERY_PARAM_EDITING_SECRET];
|
|
27
|
+
if (!enforceCors(_req, res, EDITING_ALLOWED_ORIGINS)) {
|
|
28
|
+
debug.editing('invalid origin host - set allowed origins in JSS_ALLOWED_ORIGINS environment variable');
|
|
29
|
+
return res.status(401).json({ message: 'Invalid origin' });
|
|
30
|
+
}
|
|
25
31
|
if (secret !== getJssEditingSecret()) {
|
|
26
32
|
debug.editing('invalid editing secret - sent "%s" expected "%s"', secret, getJssEditingSecret());
|
|
27
33
|
return res.status(401).json({ message: 'Missing or invalid editing secret' });
|
|
@@ -29,9 +35,11 @@ export class EditingConfigMiddleware {
|
|
|
29
35
|
const components = Array.isArray(this.config.components)
|
|
30
36
|
? this.config.components
|
|
31
37
|
: Array.from(this.config.components.keys());
|
|
38
|
+
const editMode = this.config.pagesEditMode || EditMode.Metadata;
|
|
32
39
|
return res.status(200).json({
|
|
33
40
|
components,
|
|
34
41
|
packages: this.config.metadata.packages,
|
|
42
|
+
editMode,
|
|
35
43
|
});
|
|
36
44
|
});
|
|
37
45
|
}
|
|
@@ -9,8 +9,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { editingDataDiskCache } from './editing-data-cache';
|
|
11
11
|
import { isEditingData } from './editing-data';
|
|
12
|
-
import { QUERY_PARAM_EDITING_SECRET } from './constants';
|
|
12
|
+
import { EDITING_ALLOWED_ORIGINS, QUERY_PARAM_EDITING_SECRET } from './constants';
|
|
13
13
|
import { getJssEditingSecret } from '../utils/utils';
|
|
14
|
+
import { enforceCors } from '@sitecore-jss/sitecore-jss/utils';
|
|
15
|
+
import { debug } from '@sitecore-jss/sitecore-jss';
|
|
14
16
|
/**
|
|
15
17
|
* Middleware / handler for use in the editing data Next.js API dynamic route (e.g. '/api/editing/data/[key]')
|
|
16
18
|
* which is required for Sitecore editing support.
|
|
@@ -25,6 +27,10 @@ export class EditingDataMiddleware {
|
|
|
25
27
|
const { method, query, body } = req;
|
|
26
28
|
const secret = query[QUERY_PARAM_EDITING_SECRET];
|
|
27
29
|
const key = query[this.queryParamKey];
|
|
30
|
+
if (!enforceCors(req, res, EDITING_ALLOWED_ORIGINS)) {
|
|
31
|
+
debug.editing('invalid origin host - set allowed origins in JSS_ALLOWED_ORIGINS environment variable');
|
|
32
|
+
return res.status(401).json({ message: 'Invalid origin' });
|
|
33
|
+
}
|
|
28
34
|
// Validate secret
|
|
29
35
|
if (secret !== getJssEditingSecret()) {
|
|
30
36
|
res.status(401).end('Missing or invalid secret');
|