@sitecore-content-sdk/nextjs 0.1.0 → 0.2.0-beta.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/components/Link.js +0 -2
- package/dist/cjs/components/NextImage.js +6 -25
- package/dist/cjs/components/RichText.js +0 -5
- package/dist/cjs/config/define-config.js +25 -0
- package/dist/cjs/config/index.js +3 -3
- package/dist/cjs/editing/editing-render-middleware.js +1 -1
- package/dist/cjs/index.js +9 -4
- package/dist/cjs/middleware/index.js +10 -1
- package/dist/cjs/middleware/middleware.js +4 -0
- package/dist/cjs/middleware/personalize-middleware.js +32 -25
- package/dist/cjs/middleware/redirects-middleware.js +14 -3
- package/dist/cjs/middleware/robots-middleware.js +42 -0
- package/dist/cjs/tools/codegen/extract-components.js +64 -0
- package/dist/cjs/tools/codegen/utils.js +255 -0
- package/dist/cjs/tools/index.js +3 -1
- package/dist/esm/components/Link.js +1 -3
- package/dist/esm/components/NextImage.js +6 -25
- package/dist/esm/components/RichText.js +1 -3
- package/dist/esm/config/define-config.js +20 -0
- package/dist/esm/config/index.js +1 -1
- package/dist/esm/editing/editing-render-middleware.js +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/middleware/index.js +3 -0
- package/dist/esm/middleware/middleware.js +4 -0
- package/dist/esm/middleware/personalize-middleware.js +32 -25
- package/dist/esm/middleware/redirects-middleware.js +14 -3
- package/dist/esm/middleware/robots-middleware.js +38 -0
- package/dist/esm/tools/codegen/extract-components.js +57 -0
- package/dist/esm/tools/codegen/utils.js +212 -0
- package/dist/esm/tools/index.js +1 -0
- package/package.json +40 -38
- package/types/components/ComponentPropsContext.d.ts +1 -1
- package/types/components/RichText.d.ts +1 -14
- package/types/config/define-config.d.ts +33 -0
- package/types/config/index.d.ts +1 -1
- package/types/index.d.ts +4 -4
- package/types/middleware/index.d.ts +3 -0
- package/types/middleware/middleware.d.ts +3 -0
- package/types/middleware/personalize-middleware.d.ts +6 -29
- package/types/middleware/redirects-middleware.d.ts +13 -6
- package/types/middleware/robots-middleware.d.ts +11 -0
- package/types/tools/codegen/extract-components.d.ts +10 -0
- package/types/tools/codegen/utils.d.ts +40 -0
- package/types/tools/index.d.ts +1 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.sendCode = exports.resolveComponentImportFiles = exports.validateDeployContext = exports.validateConsent = exports.ExtractedFileType = void 0;
|
|
49
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
50
|
+
const path_1 = __importDefault(require("path"));
|
|
51
|
+
const fs_1 = __importDefault(require("fs"));
|
|
52
|
+
const ts = __importStar(require("typescript"));
|
|
53
|
+
const core_1 = require("@sitecore-content-sdk/core");
|
|
54
|
+
/**
|
|
55
|
+
* Type of file to be sent to the mesh endpoint
|
|
56
|
+
*/
|
|
57
|
+
var ExtractedFileType;
|
|
58
|
+
(function (ExtractedFileType) {
|
|
59
|
+
ExtractedFileType["Component"] = "component";
|
|
60
|
+
ExtractedFileType["Json"] = "json";
|
|
61
|
+
ExtractedFileType["Package"] = "package.json";
|
|
62
|
+
})(ExtractedFileType || (exports.ExtractedFileType = ExtractedFileType = {}));
|
|
63
|
+
/**
|
|
64
|
+
* Validates consent for code extraction procedures
|
|
65
|
+
* @returns {boolean} - true if consent is given, false otherwise
|
|
66
|
+
*/
|
|
67
|
+
const validateConsent = () => {
|
|
68
|
+
if (!process.env.EXTRACT_CONSENT) {
|
|
69
|
+
console.log(chalk_1.default.yellow('EXTRACT_CONSENT is not set'));
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
};
|
|
74
|
+
exports.validateConsent = validateConsent;
|
|
75
|
+
/**
|
|
76
|
+
* Validates if the current operation is done in Vercel, Netlify or XMCloud
|
|
77
|
+
* deploy context
|
|
78
|
+
* @returns {boolean} - true if in deploy context, false otherwise
|
|
79
|
+
*/
|
|
80
|
+
const validateDeployContext = () => {
|
|
81
|
+
if (process.env.NETLIFY && process.env.BUILD_ID) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
// workaround, Vercel does not have variables that are only accessible at build time
|
|
85
|
+
if (process.env.VERCEL && !process.env.VERCEL_REGION) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
if (process.env.SITECORE && process.env.BuildMetadata_BuildId) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
};
|
|
93
|
+
exports.validateDeployContext = validateDeployContext;
|
|
94
|
+
/**
|
|
95
|
+
* Parses the componentBuilder.ts file and returns a map of component names
|
|
96
|
+
* and their respective import strings
|
|
97
|
+
* @param {string} appPath path to the JSS app root
|
|
98
|
+
* @param {string} [componentMapPath] path to the app's component map file. Default: 'src/lib/componentMap.ts'
|
|
99
|
+
* @returns map of component names and their respective import strings
|
|
100
|
+
*/
|
|
101
|
+
const resolveComponentImportFiles = (appPath, componentMapPath = './src/lib/componentMap.ts') => {
|
|
102
|
+
appPath = path_1.default.isAbsolute(appPath) ? appPath : path_1.default.resolve(process.cwd(), appPath);
|
|
103
|
+
const tsConfig = ts.readConfigFile(path_1.default.resolve(appPath, 'tsconfig.json'), ts.sys.readFile);
|
|
104
|
+
if (tsConfig.error) {
|
|
105
|
+
throw new Error(`Error reading tsconfig.json from JSS app root: ${tsConfig.error.messageText}`);
|
|
106
|
+
}
|
|
107
|
+
const componentMapFullPath = path_1.default.isAbsolute(componentMapPath)
|
|
108
|
+
? componentMapPath
|
|
109
|
+
: path_1.default.resolve(appPath, componentMapPath);
|
|
110
|
+
const cliCompilerOptions = Object.assign(Object.assign({}, tsConfig.config.compilerOptions), { baseUrl: appPath });
|
|
111
|
+
const tsHost = ts.createCompilerHost(cliCompilerOptions, true);
|
|
112
|
+
const componentMapSourceFile = tsHost.getSourceFile(componentMapFullPath, ts.ScriptTarget.Latest, (msg) => {
|
|
113
|
+
throw new Error(`Failed to parse ${componentMapFullPath}: ${msg}`);
|
|
114
|
+
});
|
|
115
|
+
if (!componentMapSourceFile)
|
|
116
|
+
throw ReferenceError(`Failed to find file ${componentMapFullPath}`);
|
|
117
|
+
// this map matches all raw import strings (i.e. * as component) to import strings
|
|
118
|
+
const importStringsMap = {};
|
|
119
|
+
// this map will match component names only to full resolved source file paths
|
|
120
|
+
const componentImportsMap = new Map();
|
|
121
|
+
let mapExportName = '';
|
|
122
|
+
// all new xyz() statements in file
|
|
123
|
+
const newAssignments = [];
|
|
124
|
+
// all map.set() assignments in file
|
|
125
|
+
const mapAssignments = [];
|
|
126
|
+
// this function will traverse the map = new Map([/values/]) statement
|
|
127
|
+
// and get the component names registered in map from it
|
|
128
|
+
const traverseNewStatement = (node) => {
|
|
129
|
+
// going through map invocation, we're looking for outer array value
|
|
130
|
+
if (ts.isArrayLiteralExpression(node)) {
|
|
131
|
+
ts.forEachChild(node, (childNode) => {
|
|
132
|
+
// and then parse each individual array pair (i.e. ['MyComp', MyComp])
|
|
133
|
+
if (!ts.isArrayLiteralExpression(childNode)) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const componentKey = childNode.elements[1].getText();
|
|
137
|
+
const componentImport = Object.keys(importStringsMap).find((importStatement) => {
|
|
138
|
+
const matcher = new RegExp(`\\b(${componentKey})\\b`);
|
|
139
|
+
return importStatement.match(matcher) !== null;
|
|
140
|
+
});
|
|
141
|
+
if (componentImport) {
|
|
142
|
+
const componentValue = importStringsMap[componentImport];
|
|
143
|
+
componentImportsMap.set(componentKey, componentValue);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else if (node.getChildCount() > 0) {
|
|
148
|
+
ts.forEachChild(node, (childNode) => {
|
|
149
|
+
traverseNewStatement(childNode);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
// step 1: get all import statements, map assignments (map.set) and map inits (map = new Map()) from componentMap file
|
|
154
|
+
ts.forEachChild(componentMapSourceFile, (childNode) => {
|
|
155
|
+
var _a;
|
|
156
|
+
// first, all import statements are parsed
|
|
157
|
+
if (ts.isImportDeclaration(childNode) && childNode.importClause) {
|
|
158
|
+
// import path is extracted
|
|
159
|
+
const moduleName = childNode.moduleSpecifier.getText().replace(/['"]/g, '');
|
|
160
|
+
// unless the import is a nodeJS one, or points to dependency package, resolve full path to the imported source file
|
|
161
|
+
if (moduleName.startsWith('node:') || moduleName.indexOf('/node_modules') > -1) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const resolvedModule = ts.nodeModuleNameResolver(moduleName, componentMapFullPath, cliCompilerOptions, tsHost);
|
|
165
|
+
const resolvedFile = (_a = resolvedModule === null || resolvedModule === void 0 ? void 0 : resolvedModule.resolvedModule) === null || _a === void 0 ? void 0 : _a.resolvedFileName;
|
|
166
|
+
// module imports will be resolved to /node_modules location - we don't support that yet
|
|
167
|
+
if (resolvedFile && resolvedFile.indexOf('node_modules') === -1) {
|
|
168
|
+
importStringsMap[childNode.importClause.getText()] = path_1.default.resolve(resolvedFile);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
console.warn('Could not resolve a file for import %s', moduleName);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else if (ts.isExpressionStatement(childNode)) {
|
|
175
|
+
// parse map assignments (map.set(..)) to get registered components
|
|
176
|
+
ts.forEachChild(childNode, (expressionNode) => {
|
|
177
|
+
if (ts.isCallExpression(expressionNode) &&
|
|
178
|
+
expressionNode.expression.getText().indexOf('set') !== -1) {
|
|
179
|
+
// get map.set assignments
|
|
180
|
+
mapAssignments.push(expressionNode);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
else if (ts.isExportAssignment(childNode)) {
|
|
185
|
+
// get component map export variable
|
|
186
|
+
mapExportName = childNode.expression.getText();
|
|
187
|
+
}
|
|
188
|
+
else if (childNode.kind === ts.SyntaxKind.FirstStatement) {
|
|
189
|
+
// get potential map = new Map() assignments to extract initial component values from
|
|
190
|
+
newAssignments.push(childNode);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
// step 2: parse map assignments (from map.set and the new Map()) and retrieve import paths
|
|
194
|
+
// only for components registered into component map
|
|
195
|
+
for (const mapAssignment of newAssignments) {
|
|
196
|
+
// parse new Map() statement first
|
|
197
|
+
// only consider variable name for map that is exported
|
|
198
|
+
if (
|
|
199
|
+
// get the (maybe) exported new Map() statement
|
|
200
|
+
// matches i.e. export const map.. / export default const map.. / let map = .. / etc
|
|
201
|
+
mapAssignment
|
|
202
|
+
.getText()
|
|
203
|
+
.match(`^((export )|(export default ))?\\b(var|let|const)\\b\\s{1}\\b(${mapExportName})\\b`)) {
|
|
204
|
+
traverseNewStatement(mapAssignment);
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
for (const mapAssignment of mapAssignments) {
|
|
209
|
+
// only consider the map variable that is exported
|
|
210
|
+
if (mapAssignment.getText().startsWith(mapExportName)) {
|
|
211
|
+
const componentKey = mapAssignment.arguments[1].getText();
|
|
212
|
+
const componentImport = Object.keys(importStringsMap).find((importStatement) => {
|
|
213
|
+
const matcher = new RegExp(`\\b(${componentKey})\\b`);
|
|
214
|
+
return importStatement.match(matcher) !== null;
|
|
215
|
+
});
|
|
216
|
+
if (componentImport) {
|
|
217
|
+
const componentValue = importStringsMap[componentImport];
|
|
218
|
+
componentImportsMap.set(componentKey, componentValue);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return componentImportsMap;
|
|
223
|
+
};
|
|
224
|
+
exports.resolveComponentImportFiles = resolveComponentImportFiles;
|
|
225
|
+
const sendCode = (_a) => __awaiter(void 0, [_a], void 0, function* ({ file, token, edgeUrl, }) {
|
|
226
|
+
const meshEndpoint = `${edgeUrl || core_1.constants.SITECORE_EDGE_URL_DEFAULT}/api/v1/mesh`;
|
|
227
|
+
if (!fs_1.default.existsSync(file.path)) {
|
|
228
|
+
console.error(chalk_1.default.red(`Component file not found: ${file.path}`));
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const code = fs_1.default.readFileSync(file.path);
|
|
232
|
+
const response = yield fetch(meshEndpoint, {
|
|
233
|
+
method: 'POST',
|
|
234
|
+
headers: {
|
|
235
|
+
Authorization: `Bearer ${token}`,
|
|
236
|
+
'Content-Type': 'application/json',
|
|
237
|
+
},
|
|
238
|
+
body: JSON.stringify({
|
|
239
|
+
name: file.name,
|
|
240
|
+
content: code.toString(),
|
|
241
|
+
labels: {
|
|
242
|
+
properties: {
|
|
243
|
+
type: file.type,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
}),
|
|
247
|
+
});
|
|
248
|
+
if (!response.ok) {
|
|
249
|
+
console.error(chalk_1.default.red(`Failed to send extracted code from ${file.path}: ${response.statusText}`));
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
console.log(chalk_1.default.green(`Code from ${file.path} extracted and sent to mesh endpoint`));
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
exports.sendCode = sendCode;
|
package/dist/cjs/tools/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ModuleType = exports.generatePlugins = exports.getComponentList = exports.generateMetadata = exports.generateSites = void 0;
|
|
3
|
+
exports.extractComponents = exports.ModuleType = exports.generatePlugins = exports.getComponentList = exports.generateMetadata = exports.generateSites = void 0;
|
|
4
4
|
var tools_1 = require("@sitecore-content-sdk/core/tools");
|
|
5
5
|
Object.defineProperty(exports, "generateSites", { enumerable: true, get: function () { return tools_1.generateSites; } });
|
|
6
6
|
Object.defineProperty(exports, "generateMetadata", { enumerable: true, get: function () { return tools_1.generateMetadata; } });
|
|
7
7
|
Object.defineProperty(exports, "getComponentList", { enumerable: true, get: function () { return tools_1.getComponentList; } });
|
|
8
8
|
Object.defineProperty(exports, "generatePlugins", { enumerable: true, get: function () { return tools_1.generatePlugins; } });
|
|
9
9
|
Object.defineProperty(exports, "ModuleType", { enumerable: true, get: function () { return tools_1.ModuleType; } });
|
|
10
|
+
var extract_components_1 = require("./codegen/extract-components");
|
|
11
|
+
Object.defineProperty(exports, "extractComponents", { enumerable: true, get: function () { return extract_components_1.extractComponents; } });
|
|
@@ -10,9 +10,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import React, { forwardRef } from 'react';
|
|
13
|
-
import PropTypes from 'prop-types';
|
|
14
13
|
import NextLink from 'next/link';
|
|
15
|
-
import { Link as ReactLink,
|
|
14
|
+
import { Link as ReactLink, } from '@sitecore-content-sdk/react';
|
|
16
15
|
/**
|
|
17
16
|
* Matches relative URLs that end with a file extension.
|
|
18
17
|
*/
|
|
@@ -51,4 +50,3 @@ export const Link = forwardRef((props, ref) => {
|
|
|
51
50
|
return (React.createElement(ReactLink, Object.assign({}, reactLinkProps, { ref: ref }, (process.env.TEST ? { 'data-react-link': true } : {}))));
|
|
52
51
|
});
|
|
53
52
|
Link.displayName = 'NextLink';
|
|
54
|
-
Link.propTypes = Object.assign({ internalLinkMatcher: PropTypes.instanceOf(RegExp) }, LinkPropTypes);
|
|
@@ -10,15 +10,12 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { mediaApi } from '@sitecore-content-sdk/core/media';
|
|
13
|
-
import PropTypes from 'prop-types';
|
|
14
13
|
import React from 'react';
|
|
15
|
-
import { withFieldMetadata, SitecoreContextReactContext, } from '@sitecore-content-sdk/react';
|
|
14
|
+
import { withFieldMetadata, SitecoreContextReactContext, DefaultEmptyFieldEditingComponentImage, withEmptyFieldEditingComponent, } from '@sitecore-content-sdk/react';
|
|
16
15
|
import Image from 'next/image';
|
|
17
|
-
import {
|
|
18
|
-
import { DefaultEmptyFieldEditingComponentImage } from '@sitecore-content-sdk/react';
|
|
19
|
-
import { isFieldValueEmpty, LayoutServicePageState } from '@sitecore-content-sdk/core/layout';
|
|
16
|
+
import { isFieldValueEmpty, LayoutServicePageState, RenderingType, } from '@sitecore-content-sdk/core/layout';
|
|
20
17
|
export const NextImage = withFieldMetadata(withEmptyFieldEditingComponent((_a) => {
|
|
21
|
-
var _b;
|
|
18
|
+
var _b, _c;
|
|
22
19
|
var { editable = true, imageParams, field, mediaUrlPrefix, fill, priority } = _a, otherProps = __rest(_a, ["editable", "imageParams", "field", "mediaUrlPrefix", "fill", "priority"]);
|
|
23
20
|
const sitecoreContext = React.useContext(SitecoreContextReactContext);
|
|
24
21
|
// next handles src and we use a custom loader,
|
|
@@ -37,9 +34,10 @@ export const NextImage = withFieldMetadata(withEmptyFieldEditingComponent((_a) =
|
|
|
37
34
|
if (!img) {
|
|
38
35
|
return null;
|
|
39
36
|
}
|
|
40
|
-
// disable image optimization for Edit
|
|
37
|
+
// disable image optimization for Edit / Preview / Component rendering, but preserve original value if true
|
|
41
38
|
const unoptimized = otherProps.unoptimized ||
|
|
42
|
-
((_b = sitecoreContext.context) === null || _b === void 0 ? void 0 : _b.
|
|
39
|
+
((_b = sitecoreContext.context) === null || _b === void 0 ? void 0 : _b.renderingType) === RenderingType.Component ||
|
|
40
|
+
((_c = sitecoreContext.context) === null || _c === void 0 ? void 0 : _c.pageState) !== LayoutServicePageState.Normal;
|
|
43
41
|
const attrs = Object.assign(Object.assign(Object.assign({}, img), otherProps), { fill,
|
|
44
42
|
priority, src: mediaApi.updateImageUrl(img.src, imageParams, mediaUrlPrefix), unoptimized });
|
|
45
43
|
const imageProps = Object.assign(Object.assign({}, attrs), {
|
|
@@ -56,21 +54,4 @@ export const NextImage = withFieldMetadata(withEmptyFieldEditingComponent((_a) =
|
|
|
56
54
|
}
|
|
57
55
|
return null; // we can't handle the truth
|
|
58
56
|
}, { defaultEmptyFieldEditingComponent: DefaultEmptyFieldEditingComponentImage }));
|
|
59
|
-
NextImage.propTypes = {
|
|
60
|
-
field: PropTypes.oneOfType([
|
|
61
|
-
PropTypes.shape({
|
|
62
|
-
src: PropTypes.string.isRequired,
|
|
63
|
-
}),
|
|
64
|
-
PropTypes.shape({
|
|
65
|
-
value: PropTypes.object,
|
|
66
|
-
}),
|
|
67
|
-
]),
|
|
68
|
-
editable: PropTypes.bool,
|
|
69
|
-
mediaUrlPrefix: PropTypes.instanceOf(RegExp),
|
|
70
|
-
imageParams: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.number.isRequired, PropTypes.string.isRequired]).isRequired),
|
|
71
|
-
emptyFieldEditingComponent: PropTypes.oneOfType([
|
|
72
|
-
PropTypes.object,
|
|
73
|
-
PropTypes.func,
|
|
74
|
-
]),
|
|
75
|
-
};
|
|
76
57
|
NextImage.displayName = 'NextImage';
|
|
@@ -10,9 +10,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import React, { useEffect, useRef } from 'react';
|
|
13
|
-
import PropTypes from 'prop-types';
|
|
14
13
|
import { useRouter } from 'next/router';
|
|
15
|
-
import { RichText as ReactRichText,
|
|
14
|
+
import { RichText as ReactRichText, } from '@sitecore-content-sdk/react';
|
|
16
15
|
export const prefetched = {};
|
|
17
16
|
export const RichText = (props) => {
|
|
18
17
|
const { internalLinksSelector = 'a[href^="/"]', prefetchLinks = true, editable = true } = props, rest = __rest(props, ["internalLinksSelector", "prefetchLinks", "editable"]);
|
|
@@ -63,5 +62,4 @@ export const RichText = (props) => {
|
|
|
63
62
|
};
|
|
64
63
|
return React.createElement(ReactRichText, Object.assign({ ref: richTextRef, editable: editable }, rest));
|
|
65
64
|
};
|
|
66
|
-
RichText.propTypes = Object.assign({ internalLinksSelector: PropTypes.string }, RichTextPropTypes);
|
|
67
65
|
RichText.displayName = 'NextRichText';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig as defineConfigCore, } from '@sitecore-content-sdk/core/config';
|
|
2
|
+
/**
|
|
3
|
+
* Provides default NextJs initial values from env variables for SitecoreConfig
|
|
4
|
+
* @param {SitecoreConfigInput} config optional override values to be written over default config settings
|
|
5
|
+
* @returns default nextjs input config
|
|
6
|
+
*/
|
|
7
|
+
export const getNextFallbackConfig = (config) => {
|
|
8
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
9
|
+
return Object.assign(Object.assign({}, config), { api: Object.assign(Object.assign({}, config === null || config === void 0 ? void 0 : config.api), { edge: Object.assign(Object.assign({}, (_a = config === null || config === void 0 ? void 0 : config.api) === null || _a === void 0 ? void 0 : _a.edge), { contextId: ((_c = (_b = config === null || config === void 0 ? void 0 : config.api) === null || _b === void 0 ? void 0 : _b.edge) === null || _c === void 0 ? void 0 : _c.contextId) || process.env.NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID || '', clientContextId: ((_e = (_d = config === null || config === void 0 ? void 0 : config.api) === null || _d === void 0 ? void 0 : _d.edge) === null || _e === void 0 ? void 0 : _e.clientContextId) || process.env.NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID, edgeUrl: ((_g = (_f = config === null || config === void 0 ? void 0 : config.api) === null || _f === void 0 ? void 0 : _f.edge) === null || _g === void 0 ? void 0 : _g.edgeUrl) || process.env.NEXT_PUBLIC_SITECORE_EDGE_URL }), local: Object.assign(Object.assign({}, (_h = config === null || config === void 0 ? void 0 : config.api) === null || _h === void 0 ? void 0 : _h.local), { apiKey: ((_k = (_j = config === null || config === void 0 ? void 0 : config.api) === null || _j === void 0 ? void 0 : _j.local) === null || _k === void 0 ? void 0 : _k.apiKey) || process.env.NEXT_PUBLIC_SITECORE_API_KEY || '', apiHost: ((_m = (_l = config === null || config === void 0 ? void 0 : config.api) === null || _l === void 0 ? void 0 : _l.local) === null || _m === void 0 ? void 0 : _m.apiHost) || process.env.NEXT_PUBLIC_SITECORE_API_HOST || '' }) }), defaultSite: (config === null || config === void 0 ? void 0 : config.defaultSite) || process.env.NEXT_PUBLIC_SITECORE_SITE_NAME || '', defaultLanguage: (config === null || config === void 0 ? void 0 : config.defaultLanguage) || process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE || 'en', multisite: Object.assign(Object.assign({}, config === null || config === void 0 ? void 0 : config.multisite), { useCookieResolution: (_p = (_o = config === null || config === void 0 ? void 0 : config.multisite) === null || _o === void 0 ? void 0 : _o.useCookieResolution) !== null && _p !== void 0 ? _p : (() => process.env.VERCEL_ENV === 'preview') }), personalize: Object.assign(Object.assign({}, config === null || config === void 0 ? void 0 : config.personalize), { scope: ((_q = config === null || config === void 0 ? void 0 : config.personalize) === null || _q === void 0 ? void 0 : _q.scope) || process.env.NEXT_PUBLIC_PERSONALIZE_SCOPE }), disableStaticPaths: process.env.DISABLE_SSG_FETCH !== undefined
|
|
10
|
+
? process.env.DISABLE_SSG_FETCH.toLowerCase() === 'true'
|
|
11
|
+
: (_r = config === null || config === void 0 ? void 0 : config.disableStaticPaths) !== null && _r !== void 0 ? _r : false });
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Accepts a SitecoreConfigInput object and returns full sitecore configuration
|
|
15
|
+
* @param {SitecoreConfigInput} config override values to be written over default config settings
|
|
16
|
+
* @returns {SitecoreConfig} full sitecore configuration to use in application
|
|
17
|
+
*/
|
|
18
|
+
export const defineConfig = (config) => {
|
|
19
|
+
return defineConfigCore(getNextFallbackConfig(config));
|
|
20
|
+
};
|
package/dist/esm/config/index.js
CHANGED
|
@@ -101,7 +101,7 @@ export class EditingRenderMiddleware extends RenderMiddlewareBase {
|
|
|
101
101
|
language: query.sc_lang,
|
|
102
102
|
site: query.sc_site,
|
|
103
103
|
mode: 'library',
|
|
104
|
-
dataSourceId: query.
|
|
104
|
+
dataSourceId: query.dataSourceId,
|
|
105
105
|
version: query.sc_version,
|
|
106
106
|
}, {
|
|
107
107
|
maxAge: 3,
|
package/dist/esm/index.js
CHANGED
|
@@ -5,10 +5,10 @@ export { LayoutServicePageState, GraphQLLayoutService, getChildPlaceholder, getF
|
|
|
5
5
|
export { RestComponentLayoutService } from '@sitecore-content-sdk/core/editing';
|
|
6
6
|
export { mediaApi } from '@sitecore-content-sdk/core/media';
|
|
7
7
|
export { GraphQLDictionaryService, } from '@sitecore-content-sdk/core/i18n';
|
|
8
|
-
export { personalizeLayout, getPersonalizedRewrite, getPersonalizedRewriteData, getGroomedVariantIds, normalizePersonalizedRewrite, CdpHelper, } from '@sitecore-content-sdk/core/personalize';
|
|
9
|
-
export {
|
|
10
|
-
export { GraphQLSitePathService, } from '@sitecore-content-sdk/core/site';
|
|
8
|
+
export { personalizeLayout, getPersonalizedRewrite, getPersonalizedRewriteData, getGroomedVariantIds, normalizePersonalizedRewrite, CdpHelper, GraphQLPersonalizeService, } from '@sitecore-content-sdk/core/personalize';
|
|
9
|
+
export { GraphQLSitePathService, GraphQLRedirectsService, REDIRECT_TYPE_301, REDIRECT_TYPE_302, REDIRECT_TYPE_SERVER_TRANSFER, } from '@sitecore-content-sdk/core/site';
|
|
11
10
|
export { GraphQLSitemapXmlService, GraphQLErrorPagesService, GraphQLRobotsService, SiteResolver, GraphQLSiteInfoService, getSiteRewrite, getSiteRewriteData, normalizeSiteRewrite, } from '@sitecore-content-sdk/core/site';
|
|
11
|
+
export { ComponentPropsService } from './services/component-props-service';
|
|
12
12
|
export { ComponentPropsReactContext, ComponentPropsContext, useComponentProps, } from './components/ComponentPropsContext';
|
|
13
13
|
export { Link } from './components/Link';
|
|
14
14
|
export { RichText } from './components/RichText';
|
|
@@ -4,3 +4,6 @@ export { RedirectsMiddleware } from './redirects-middleware';
|
|
|
4
4
|
export { PersonalizeMiddleware } from './personalize-middleware';
|
|
5
5
|
export { MultisiteMiddleware } from './multisite-middleware';
|
|
6
6
|
export { SitemapMiddleware } from './sitemap-middleware';
|
|
7
|
+
export { RobotsMiddleware } from './robots-middleware';
|
|
8
|
+
export { GraphQLPersonalizeService, } from '@sitecore-content-sdk/core/personalize';
|
|
9
|
+
export { GraphQLRedirectsService, REDIRECT_TYPE_301, REDIRECT_TYPE_302, REDIRECT_TYPE_SERVER_TRANSFER, } from '@sitecore-content-sdk/core/site';
|
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { SITE_KEY, SiteResolver } from '@sitecore-content-sdk/core/site';
|
|
11
11
|
import { debug } from '@sitecore-content-sdk/core';
|
|
12
12
|
import { NextResponse } from 'next/server';
|
|
13
|
+
import { createGraphQLClientFactory, } from '@sitecore-content-sdk/core/client';
|
|
13
14
|
export const REWRITE_HEADER_NAME = 'x-sc-rewrite';
|
|
14
15
|
/**
|
|
15
16
|
* Middleware class to be extended by all middleware implementations
|
|
@@ -104,6 +105,9 @@ export class MiddlewareBase extends Middleware {
|
|
|
104
105
|
}
|
|
105
106
|
return this.siteResolver.getByHost(hostname);
|
|
106
107
|
}
|
|
108
|
+
getClientFactory(graphQLOptions) {
|
|
109
|
+
return createGraphQLClientFactory(graphQLOptions);
|
|
110
|
+
}
|
|
107
111
|
/**
|
|
108
112
|
* Create a rewrite response
|
|
109
113
|
* @param {string} rewritePath the destionation path
|
|
@@ -20,6 +20,7 @@ export class PersonalizeMiddleware extends MiddlewareBase {
|
|
|
20
20
|
* @param {PersonalizeMiddlewareConfig} [config] Personalize middleware config
|
|
21
21
|
*/
|
|
22
22
|
constructor(config) {
|
|
23
|
+
var _a;
|
|
23
24
|
super(config);
|
|
24
25
|
this.config = config;
|
|
25
26
|
this.handle = (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -120,14 +121,39 @@ export class PersonalizeMiddleware extends MiddlewareBase {
|
|
|
120
121
|
return res;
|
|
121
122
|
}
|
|
122
123
|
});
|
|
124
|
+
const graphQLOptions = {
|
|
125
|
+
api: {
|
|
126
|
+
edge: {
|
|
127
|
+
contextId: this.config.contextId,
|
|
128
|
+
clientContextId: this.config.clientContextId,
|
|
129
|
+
edgeUrl: this.config.edgeUrl,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
};
|
|
123
133
|
// NOTE: we provide native fetch for compatibility on Next.js Edge Runtime
|
|
124
134
|
// (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
|
|
125
|
-
this.personalizeService =
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
135
|
+
this.personalizeService =
|
|
136
|
+
(_a = this.config.personalizeService) !== null && _a !== void 0 ? _a : new GraphQLPersonalizeService({
|
|
137
|
+
clientFactory: this.getClientFactory(graphQLOptions),
|
|
138
|
+
timeout: this.config.edgeTimeout,
|
|
139
|
+
scope: this.config.scope,
|
|
140
|
+
fetch: fetch,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
getExperienceParams(req) {
|
|
144
|
+
const extraParams = this.config.getExtraUtmParams ? this.config.getExtraUtmParams(req) : {};
|
|
145
|
+
const utm = Object.assign({ campaign: req.nextUrl.searchParams.get('utm_campaign') || undefined, content: req.nextUrl.searchParams.get('utm_content') || undefined, medium: req.nextUrl.searchParams.get('utm_medium') || undefined, source: req.nextUrl.searchParams.get('utm_source') || undefined }, extraParams);
|
|
146
|
+
return {
|
|
147
|
+
// It's expected that the header name "referer" is actually a misspelling of the word "referrer"
|
|
148
|
+
// req.referrer is used during fetching to determine the value of the Referer header of the request being made,
|
|
149
|
+
// used as a fallback
|
|
150
|
+
referrer: req.headers.get('referer') || req.referrer,
|
|
151
|
+
utm,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
disabled(req, res) {
|
|
155
|
+
// ignore files
|
|
156
|
+
return req.nextUrl.pathname.includes('.') || super.disabled(req, res);
|
|
131
157
|
}
|
|
132
158
|
initPersonalizeServer(_a) {
|
|
133
159
|
return __awaiter(this, arguments, void 0, function* ({ hostname, siteName, request, response, }) {
|
|
@@ -156,25 +182,6 @@ export class PersonalizeMiddleware extends MiddlewareBase {
|
|
|
156
182
|
}, { timeout }));
|
|
157
183
|
});
|
|
158
184
|
}
|
|
159
|
-
getExperienceParams(req) {
|
|
160
|
-
const utm = {
|
|
161
|
-
campaign: req.nextUrl.searchParams.get('utm_campaign') || undefined,
|
|
162
|
-
content: req.nextUrl.searchParams.get('utm_content') || undefined,
|
|
163
|
-
medium: req.nextUrl.searchParams.get('utm_medium') || undefined,
|
|
164
|
-
source: req.nextUrl.searchParams.get('utm_source') || undefined,
|
|
165
|
-
};
|
|
166
|
-
return {
|
|
167
|
-
// It's expected that the header name "referer" is actually a misspelling of the word "referrer"
|
|
168
|
-
// req.referrer is used during fetching to determine the value of the Referer header of the request being made,
|
|
169
|
-
// used as a fallback
|
|
170
|
-
referrer: req.headers.get('referer') || req.referrer,
|
|
171
|
-
utm: utm,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
disabled(req, res) {
|
|
175
|
-
// ignore files
|
|
176
|
-
return req.nextUrl.pathname.includes('.') || super.disabled(req, res);
|
|
177
|
-
}
|
|
178
185
|
/**
|
|
179
186
|
* Aggregates personalize executions based on the provided route personalize information and language
|
|
180
187
|
* @param {PersonalizeInfo} personalizeInfo the route personalize information
|
|
@@ -24,6 +24,7 @@ export class RedirectsMiddleware extends MiddlewareBase {
|
|
|
24
24
|
* @param {RedirectsMiddlewareConfig} [config] redirects middleware config
|
|
25
25
|
*/
|
|
26
26
|
constructor(config) {
|
|
27
|
+
var _a;
|
|
27
28
|
super(config);
|
|
28
29
|
this.config = config;
|
|
29
30
|
this.handle = (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -134,9 +135,19 @@ export class RedirectsMiddleware extends MiddlewareBase {
|
|
|
134
135
|
return res;
|
|
135
136
|
}
|
|
136
137
|
});
|
|
138
|
+
const graphQLOptions = {
|
|
139
|
+
api: {
|
|
140
|
+
edge: {
|
|
141
|
+
contextId: this.config.contextId,
|
|
142
|
+
clientContextId: this.config.clientContextId,
|
|
143
|
+
edgeUrl: this.config.edgeUrl,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
};
|
|
137
147
|
// NOTE: we provide native fetch for compatibility on Next.js Edge Runtime
|
|
138
148
|
// (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
|
|
139
|
-
this.redirectsService =
|
|
149
|
+
this.redirectsService =
|
|
150
|
+
(_a = this.config.redirectsService) !== null && _a !== void 0 ? _a : new GraphQLRedirectsService(Object.assign(Object.assign({}, config), { clientFactory: this.getClientFactory(graphQLOptions), fetch: fetch }));
|
|
140
151
|
this.locales = config.locales;
|
|
141
152
|
}
|
|
142
153
|
/**
|
|
@@ -236,9 +247,9 @@ export class RedirectsMiddleware extends MiddlewareBase {
|
|
|
236
247
|
return false;
|
|
237
248
|
})
|
|
238
249
|
.join('&');
|
|
239
|
-
const newUrl = new URL(`${url.pathname}?${newQueryString}`, url.origin);
|
|
250
|
+
const newUrl = new URL(`${url.pathname.toLowerCase()}?${newQueryString}`, url.origin);
|
|
240
251
|
url.search = newUrl.search;
|
|
241
|
-
url.pathname = newUrl.pathname;
|
|
252
|
+
url.pathname = newUrl.pathname.toLocaleLowerCase();
|
|
242
253
|
url.href = newUrl.href;
|
|
243
254
|
return url;
|
|
244
255
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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 for handling robots.txt requests in a Next.js application.
|
|
12
|
+
*/
|
|
13
|
+
export class RobotsMiddleware {
|
|
14
|
+
constructor(client) {
|
|
15
|
+
this.client = client;
|
|
16
|
+
}
|
|
17
|
+
getHandler() {
|
|
18
|
+
return this.handler.bind(this);
|
|
19
|
+
}
|
|
20
|
+
handler(req, res) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
var _a;
|
|
23
|
+
res.setHeader('Content-Type', 'text/plain');
|
|
24
|
+
const hostName = ((_a = req.headers.host) === null || _a === void 0 ? void 0 : _a.split(':')[0]) || 'localhost';
|
|
25
|
+
const site = this.client.resolveSite(hostName);
|
|
26
|
+
try {
|
|
27
|
+
const robotsContent = yield this.client.getRobots(site.name);
|
|
28
|
+
if (!robotsContent) {
|
|
29
|
+
return res.status(404).send('User-agent: *\nDisallow: /');
|
|
30
|
+
}
|
|
31
|
+
res.status(200).send(robotsContent);
|
|
32
|
+
}
|
|
33
|
+
catch (_b) {
|
|
34
|
+
res.status(500).send('Internal Server Error');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|