@sitecore-content-sdk/nextjs 0.2.0-beta.4 → 0.2.0-beta.6

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.
@@ -49,7 +49,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
49
49
  Object.defineProperty(exports, "__esModule", { value: true });
50
50
  exports.Link = void 0;
51
51
  const react_1 = __importStar(require("react"));
52
- const prop_types_1 = __importDefault(require("prop-types"));
53
52
  const link_1 = __importDefault(require("next/link"));
54
53
  const react_2 = require("@sitecore-content-sdk/react");
55
54
  /**
@@ -90,4 +89,3 @@ exports.Link = (0, react_1.forwardRef)((props, ref) => {
90
89
  return (react_1.default.createElement(react_2.Link, Object.assign({}, reactLinkProps, { ref: ref }, (process.env.TEST ? { 'data-react-link': true } : {}))));
91
90
  });
92
91
  exports.Link.displayName = 'NextLink';
93
- exports.Link.propTypes = Object.assign({ internalLinkMatcher: prop_types_1.default.instanceOf(RegExp) }, react_2.LinkPropTypes);
@@ -16,15 +16,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.NextImage = void 0;
18
18
  const media_1 = require("@sitecore-content-sdk/core/media");
19
- const prop_types_1 = __importDefault(require("prop-types"));
20
19
  const react_1 = __importDefault(require("react"));
21
20
  const react_2 = require("@sitecore-content-sdk/react");
22
21
  const image_1 = __importDefault(require("next/image"));
23
- const react_3 = require("@sitecore-content-sdk/react");
24
- const react_4 = require("@sitecore-content-sdk/react");
25
22
  const layout_1 = require("@sitecore-content-sdk/core/layout");
26
- exports.NextImage = (0, react_2.withFieldMetadata)((0, react_3.withEmptyFieldEditingComponent)((_a) => {
27
- var _b;
23
+ exports.NextImage = (0, react_2.withFieldMetadata)((0, react_2.withEmptyFieldEditingComponent)((_a) => {
24
+ var _b, _c;
28
25
  var { editable = true, imageParams, field, mediaUrlPrefix, fill, priority } = _a, otherProps = __rest(_a, ["editable", "imageParams", "field", "mediaUrlPrefix", "fill", "priority"]);
29
26
  const sitecoreContext = react_1.default.useContext(react_2.SitecoreContextReactContext);
30
27
  // next handles src and we use a custom loader,
@@ -43,9 +40,10 @@ exports.NextImage = (0, react_2.withFieldMetadata)((0, react_3.withEmptyFieldEdi
43
40
  if (!img) {
44
41
  return null;
45
42
  }
46
- // disable image optimization for Edit and Preview, but preserve original value if true
43
+ // disable image optimization for Edit / Preview / Component rendering, but preserve original value if true
47
44
  const unoptimized = otherProps.unoptimized ||
48
- ((_b = sitecoreContext.context) === null || _b === void 0 ? void 0 : _b.pageState) !== layout_1.LayoutServicePageState.Normal;
45
+ ((_b = sitecoreContext.context) === null || _b === void 0 ? void 0 : _b.renderingType) === layout_1.RenderingType.Component ||
46
+ ((_c = sitecoreContext.context) === null || _c === void 0 ? void 0 : _c.pageState) !== layout_1.LayoutServicePageState.Normal;
49
47
  const attrs = Object.assign(Object.assign(Object.assign({}, img), otherProps), { fill,
50
48
  priority, src: media_1.mediaApi.updateImageUrl(img.src, imageParams, mediaUrlPrefix), unoptimized });
51
49
  const imageProps = Object.assign(Object.assign({}, attrs), {
@@ -61,22 +59,5 @@ exports.NextImage = (0, react_2.withFieldMetadata)((0, react_3.withEmptyFieldEdi
61
59
  return (react_1.default.createElement(image_1.default, Object.assign({ alt: "" }, imageProps, (process.env.TEST ? { 'data-unoptimized': unoptimized } : {}))));
62
60
  }
63
61
  return null; // we can't handle the truth
64
- }, { defaultEmptyFieldEditingComponent: react_4.DefaultEmptyFieldEditingComponentImage }));
65
- exports.NextImage.propTypes = {
66
- field: prop_types_1.default.oneOfType([
67
- prop_types_1.default.shape({
68
- src: prop_types_1.default.string.isRequired,
69
- }),
70
- prop_types_1.default.shape({
71
- value: prop_types_1.default.object,
72
- }),
73
- ]),
74
- editable: prop_types_1.default.bool,
75
- mediaUrlPrefix: prop_types_1.default.instanceOf(RegExp),
76
- imageParams: prop_types_1.default.objectOf(prop_types_1.default.oneOfType([prop_types_1.default.number.isRequired, prop_types_1.default.string.isRequired]).isRequired),
77
- emptyFieldEditingComponent: prop_types_1.default.oneOfType([
78
- prop_types_1.default.object,
79
- prop_types_1.default.func,
80
- ]),
81
- };
62
+ }, { defaultEmptyFieldEditingComponent: react_2.DefaultEmptyFieldEditingComponentImage }));
82
63
  exports.NextImage.displayName = 'NextImage';
@@ -43,13 +43,9 @@ var __rest = (this && this.__rest) || function (s, e) {
43
43
  }
44
44
  return t;
45
45
  };
46
- var __importDefault = (this && this.__importDefault) || function (mod) {
47
- return (mod && mod.__esModule) ? mod : { "default": mod };
48
- };
49
46
  Object.defineProperty(exports, "__esModule", { value: true });
50
47
  exports.RichText = exports.prefetched = void 0;
51
48
  const react_1 = __importStar(require("react"));
52
- const prop_types_1 = __importDefault(require("prop-types"));
53
49
  const router_1 = require("next/router");
54
50
  const react_2 = require("@sitecore-content-sdk/react");
55
51
  exports.prefetched = {};
@@ -103,5 +99,4 @@ const RichText = (props) => {
103
99
  return react_1.default.createElement(react_2.RichText, Object.assign({ ref: richTextRef, editable: editable }, rest));
104
100
  };
105
101
  exports.RichText = RichText;
106
- exports.RichText.propTypes = Object.assign({ internalLinksSelector: prop_types_1.default.string }, react_2.RichTextPropTypes);
107
102
  exports.RichText.displayName = 'NextRichText';
@@ -105,7 +105,7 @@ class EditingRenderMiddleware extends render_middleware_1.RenderMiddlewareBase {
105
105
  language: query.sc_lang,
106
106
  site: query.sc_site,
107
107
  mode: 'library',
108
- dataSourceId: query.sc_datasourceId,
108
+ dataSourceId: query.dataSourceId,
109
109
  version: query.sc_version,
110
110
  }, {
111
111
  maxAge: 3,
@@ -242,9 +242,9 @@ class RedirectsMiddleware extends middleware_1.MiddlewareBase {
242
242
  return false;
243
243
  })
244
244
  .join('&');
245
- const newUrl = new URL(`${url.pathname}?${newQueryString}`, url.origin);
245
+ const newUrl = new URL(`${url.pathname.toLowerCase()}?${newQueryString}`, url.origin);
246
246
  url.search = newUrl.search;
247
- url.pathname = newUrl.pathname;
247
+ url.pathname = newUrl.pathname.toLocaleLowerCase();
248
248
  url.href = newUrl.href;
249
249
  return url;
250
250
  }
@@ -0,0 +1,64 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.extractComponents = void 0;
16
+ const chalk_1 = __importDefault(require("chalk"));
17
+ const utils_1 = require("./utils");
18
+ const core_1 = require("@sitecore-content-sdk/core");
19
+ const tools_1 = require("@sitecore-content-sdk/core/tools");
20
+ /**
21
+ * Extracts components from the app folder and sends them to XMCloud.
22
+ * @param {ExtractComponentsConfig} args - Config for components extraction
23
+ */
24
+ const extractComponents = (args) => {
25
+ const authParams = {
26
+ clientId: process.env.SITECORE_AUTH_CLIENT_ID || '',
27
+ clientSecret: process.env.SITECORE_AUTH_CLIENT_SECRET || '',
28
+ endpoint: process.env.SITECORE_AUTH_ENDPOINT || core_1.constants.DEFAULT_SITECORE_AUTH_ENDPOINT,
29
+ audience: process.env.SITECORE_AUTH_AUDIENCE || core_1.constants.DEFAULT_SITECORE_AUTH_AUDIENCE,
30
+ };
31
+ return () => __awaiter(void 0, void 0, void 0, function* () {
32
+ if (!(0, utils_1.validateDeployContext)()) {
33
+ console.log(chalk_1.default.yellow('Skipping code extraction, not in deploy context'));
34
+ return;
35
+ }
36
+ if (!(0, utils_1.validateConsent)()) {
37
+ console.log(chalk_1.default.yellow('Skipping code extraction, consent not given'));
38
+ return;
39
+ }
40
+ const basePath = process.cwd();
41
+ try {
42
+ const bearer = yield (0, tools_1.fetchBearerToken)(authParams);
43
+ if (!bearer) {
44
+ console.error(chalk_1.default.red('Failed to get bearer token, aborting code extraction'));
45
+ return;
46
+ }
47
+ const componentPaths = yield (0, utils_1.resolveComponentImportFiles)(basePath, args.componentMapPath);
48
+ const codeDispatches = Array.from(componentPaths, (mapEntry) => (0, utils_1.sendCode)({
49
+ file: {
50
+ name: mapEntry[0],
51
+ path: mapEntry[1],
52
+ type: utils_1.ExtractedFileType.Component,
53
+ },
54
+ token: bearer,
55
+ edgeUrl: args.scConfig.api.edge.edgeUrl,
56
+ }));
57
+ yield Promise.all(codeDispatches);
58
+ }
59
+ catch (error) {
60
+ console.error(chalk_1.default.red('Error during component extraction:', error));
61
+ }
62
+ });
63
+ };
64
+ exports.extractComponents = extractComponents;
@@ -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;
@@ -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, LinkPropTypes, } from '@sitecore-content-sdk/react';
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 { withEmptyFieldEditingComponent } from '@sitecore-content-sdk/react';
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 and Preview, but preserve original value if true
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.pageState) !== LayoutServicePageState.Normal;
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, RichTextPropTypes, } from '@sitecore-content-sdk/react';
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';
@@ -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.sc_datasourceId,
104
+ dataSourceId: query.dataSourceId,
105
105
  version: query.sc_version,
106
106
  }, {
107
107
  maxAge: 3,
@@ -236,9 +236,9 @@ export class RedirectsMiddleware extends MiddlewareBase {
236
236
  return false;
237
237
  })
238
238
  .join('&');
239
- const newUrl = new URL(`${url.pathname}?${newQueryString}`, url.origin);
239
+ const newUrl = new URL(`${url.pathname.toLowerCase()}?${newQueryString}`, url.origin);
240
240
  url.search = newUrl.search;
241
- url.pathname = newUrl.pathname;
241
+ url.pathname = newUrl.pathname.toLocaleLowerCase();
242
242
  url.href = newUrl.href;
243
243
  return url;
244
244
  }
@@ -0,0 +1,57 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import chalk from 'chalk';
11
+ import { ExtractedFileType, resolveComponentImportFiles, sendCode, validateConsent, validateDeployContext, } from './utils';
12
+ import { constants } from '@sitecore-content-sdk/core';
13
+ import { fetchBearerToken } from '@sitecore-content-sdk/core/tools';
14
+ /**
15
+ * Extracts components from the app folder and sends them to XMCloud.
16
+ * @param {ExtractComponentsConfig} args - Config for components extraction
17
+ */
18
+ export const extractComponents = (args) => {
19
+ const authParams = {
20
+ clientId: process.env.SITECORE_AUTH_CLIENT_ID || '',
21
+ clientSecret: process.env.SITECORE_AUTH_CLIENT_SECRET || '',
22
+ endpoint: process.env.SITECORE_AUTH_ENDPOINT || constants.DEFAULT_SITECORE_AUTH_ENDPOINT,
23
+ audience: process.env.SITECORE_AUTH_AUDIENCE || constants.DEFAULT_SITECORE_AUTH_AUDIENCE,
24
+ };
25
+ return () => __awaiter(void 0, void 0, void 0, function* () {
26
+ if (!validateDeployContext()) {
27
+ console.log(chalk.yellow('Skipping code extraction, not in deploy context'));
28
+ return;
29
+ }
30
+ if (!validateConsent()) {
31
+ console.log(chalk.yellow('Skipping code extraction, consent not given'));
32
+ return;
33
+ }
34
+ const basePath = process.cwd();
35
+ try {
36
+ const bearer = yield fetchBearerToken(authParams);
37
+ if (!bearer) {
38
+ console.error(chalk.red('Failed to get bearer token, aborting code extraction'));
39
+ return;
40
+ }
41
+ const componentPaths = yield resolveComponentImportFiles(basePath, args.componentMapPath);
42
+ const codeDispatches = Array.from(componentPaths, (mapEntry) => sendCode({
43
+ file: {
44
+ name: mapEntry[0],
45
+ path: mapEntry[1],
46
+ type: ExtractedFileType.Component,
47
+ },
48
+ token: bearer,
49
+ edgeUrl: args.scConfig.api.edge.edgeUrl,
50
+ }));
51
+ yield Promise.all(codeDispatches);
52
+ }
53
+ catch (error) {
54
+ console.error(chalk.red('Error during component extraction:', error));
55
+ }
56
+ });
57
+ };
@@ -0,0 +1,212 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import chalk from 'chalk';
11
+ import path from 'path';
12
+ import fs from 'fs';
13
+ import * as ts from 'typescript';
14
+ import { constants } from '@sitecore-content-sdk/core';
15
+ /**
16
+ * Type of file to be sent to the mesh endpoint
17
+ */
18
+ export var ExtractedFileType;
19
+ (function (ExtractedFileType) {
20
+ ExtractedFileType["Component"] = "component";
21
+ ExtractedFileType["Json"] = "json";
22
+ ExtractedFileType["Package"] = "package.json";
23
+ })(ExtractedFileType || (ExtractedFileType = {}));
24
+ /**
25
+ * Validates consent for code extraction procedures
26
+ * @returns {boolean} - true if consent is given, false otherwise
27
+ */
28
+ export const validateConsent = () => {
29
+ if (!process.env.EXTRACT_CONSENT) {
30
+ console.log(chalk.yellow('EXTRACT_CONSENT is not set'));
31
+ return false;
32
+ }
33
+ return true;
34
+ };
35
+ /**
36
+ * Validates if the current operation is done in Vercel, Netlify or XMCloud
37
+ * deploy context
38
+ * @returns {boolean} - true if in deploy context, false otherwise
39
+ */
40
+ export const validateDeployContext = () => {
41
+ if (process.env.NETLIFY && process.env.BUILD_ID) {
42
+ return true;
43
+ }
44
+ // workaround, Vercel does not have variables that are only accessible at build time
45
+ if (process.env.VERCEL && !process.env.VERCEL_REGION) {
46
+ return true;
47
+ }
48
+ if (process.env.SITECORE && process.env.BuildMetadata_BuildId) {
49
+ return true;
50
+ }
51
+ return false;
52
+ };
53
+ /**
54
+ * Parses the componentBuilder.ts file and returns a map of component names
55
+ * and their respective import strings
56
+ * @param {string} appPath path to the JSS app root
57
+ * @param {string} [componentMapPath] path to the app's component map file. Default: 'src/lib/componentMap.ts'
58
+ * @returns map of component names and their respective import strings
59
+ */
60
+ export const resolveComponentImportFiles = (appPath, componentMapPath = './src/lib/componentMap.ts') => {
61
+ appPath = path.isAbsolute(appPath) ? appPath : path.resolve(process.cwd(), appPath);
62
+ const tsConfig = ts.readConfigFile(path.resolve(appPath, 'tsconfig.json'), ts.sys.readFile);
63
+ if (tsConfig.error) {
64
+ throw new Error(`Error reading tsconfig.json from JSS app root: ${tsConfig.error.messageText}`);
65
+ }
66
+ const componentMapFullPath = path.isAbsolute(componentMapPath)
67
+ ? componentMapPath
68
+ : path.resolve(appPath, componentMapPath);
69
+ const cliCompilerOptions = Object.assign(Object.assign({}, tsConfig.config.compilerOptions), { baseUrl: appPath });
70
+ const tsHost = ts.createCompilerHost(cliCompilerOptions, true);
71
+ const componentMapSourceFile = tsHost.getSourceFile(componentMapFullPath, ts.ScriptTarget.Latest, (msg) => {
72
+ throw new Error(`Failed to parse ${componentMapFullPath}: ${msg}`);
73
+ });
74
+ if (!componentMapSourceFile)
75
+ throw ReferenceError(`Failed to find file ${componentMapFullPath}`);
76
+ // this map matches all raw import strings (i.e. * as component) to import strings
77
+ const importStringsMap = {};
78
+ // this map will match component names only to full resolved source file paths
79
+ const componentImportsMap = new Map();
80
+ let mapExportName = '';
81
+ // all new xyz() statements in file
82
+ const newAssignments = [];
83
+ // all map.set() assignments in file
84
+ const mapAssignments = [];
85
+ // this function will traverse the map = new Map([/values/]) statement
86
+ // and get the component names registered in map from it
87
+ const traverseNewStatement = (node) => {
88
+ // going through map invocation, we're looking for outer array value
89
+ if (ts.isArrayLiteralExpression(node)) {
90
+ ts.forEachChild(node, (childNode) => {
91
+ // and then parse each individual array pair (i.e. ['MyComp', MyComp])
92
+ if (!ts.isArrayLiteralExpression(childNode)) {
93
+ return;
94
+ }
95
+ const componentKey = childNode.elements[1].getText();
96
+ const componentImport = Object.keys(importStringsMap).find((importStatement) => {
97
+ const matcher = new RegExp(`\\b(${componentKey})\\b`);
98
+ return importStatement.match(matcher) !== null;
99
+ });
100
+ if (componentImport) {
101
+ const componentValue = importStringsMap[componentImport];
102
+ componentImportsMap.set(componentKey, componentValue);
103
+ }
104
+ });
105
+ }
106
+ else if (node.getChildCount() > 0) {
107
+ ts.forEachChild(node, (childNode) => {
108
+ traverseNewStatement(childNode);
109
+ });
110
+ }
111
+ };
112
+ // step 1: get all import statements, map assignments (map.set) and map inits (map = new Map()) from componentMap file
113
+ ts.forEachChild(componentMapSourceFile, (childNode) => {
114
+ var _a;
115
+ // first, all import statements are parsed
116
+ if (ts.isImportDeclaration(childNode) && childNode.importClause) {
117
+ // import path is extracted
118
+ const moduleName = childNode.moduleSpecifier.getText().replace(/['"]/g, '');
119
+ // unless the import is a nodeJS one, or points to dependency package, resolve full path to the imported source file
120
+ if (moduleName.startsWith('node:') || moduleName.indexOf('/node_modules') > -1) {
121
+ return;
122
+ }
123
+ const resolvedModule = ts.nodeModuleNameResolver(moduleName, componentMapFullPath, cliCompilerOptions, tsHost);
124
+ const resolvedFile = (_a = resolvedModule === null || resolvedModule === void 0 ? void 0 : resolvedModule.resolvedModule) === null || _a === void 0 ? void 0 : _a.resolvedFileName;
125
+ // module imports will be resolved to /node_modules location - we don't support that yet
126
+ if (resolvedFile && resolvedFile.indexOf('node_modules') === -1) {
127
+ importStringsMap[childNode.importClause.getText()] = path.resolve(resolvedFile);
128
+ }
129
+ else {
130
+ console.warn('Could not resolve a file for import %s', moduleName);
131
+ }
132
+ }
133
+ else if (ts.isExpressionStatement(childNode)) {
134
+ // parse map assignments (map.set(..)) to get registered components
135
+ ts.forEachChild(childNode, (expressionNode) => {
136
+ if (ts.isCallExpression(expressionNode) &&
137
+ expressionNode.expression.getText().indexOf('set') !== -1) {
138
+ // get map.set assignments
139
+ mapAssignments.push(expressionNode);
140
+ }
141
+ });
142
+ }
143
+ else if (ts.isExportAssignment(childNode)) {
144
+ // get component map export variable
145
+ mapExportName = childNode.expression.getText();
146
+ }
147
+ else if (childNode.kind === ts.SyntaxKind.FirstStatement) {
148
+ // get potential map = new Map() assignments to extract initial component values from
149
+ newAssignments.push(childNode);
150
+ }
151
+ });
152
+ // step 2: parse map assignments (from map.set and the new Map()) and retrieve import paths
153
+ // only for components registered into component map
154
+ for (const mapAssignment of newAssignments) {
155
+ // parse new Map() statement first
156
+ // only consider variable name for map that is exported
157
+ if (
158
+ // get the (maybe) exported new Map() statement
159
+ // matches i.e. export const map.. / export default const map.. / let map = .. / etc
160
+ mapAssignment
161
+ .getText()
162
+ .match(`^((export )|(export default ))?\\b(var|let|const)\\b\\s{1}\\b(${mapExportName})\\b`)) {
163
+ traverseNewStatement(mapAssignment);
164
+ break;
165
+ }
166
+ }
167
+ for (const mapAssignment of mapAssignments) {
168
+ // only consider the map variable that is exported
169
+ if (mapAssignment.getText().startsWith(mapExportName)) {
170
+ const componentKey = mapAssignment.arguments[1].getText();
171
+ const componentImport = Object.keys(importStringsMap).find((importStatement) => {
172
+ const matcher = new RegExp(`\\b(${componentKey})\\b`);
173
+ return importStatement.match(matcher) !== null;
174
+ });
175
+ if (componentImport) {
176
+ const componentValue = importStringsMap[componentImport];
177
+ componentImportsMap.set(componentKey, componentValue);
178
+ }
179
+ }
180
+ }
181
+ return componentImportsMap;
182
+ };
183
+ export const sendCode = (_a) => __awaiter(void 0, [_a], void 0, function* ({ file, token, edgeUrl, }) {
184
+ const meshEndpoint = `${edgeUrl || constants.SITECORE_EDGE_URL_DEFAULT}/api/v1/mesh`;
185
+ if (!fs.existsSync(file.path)) {
186
+ console.error(chalk.red(`Component file not found: ${file.path}`));
187
+ return;
188
+ }
189
+ const code = fs.readFileSync(file.path);
190
+ const response = yield fetch(meshEndpoint, {
191
+ method: 'POST',
192
+ headers: {
193
+ Authorization: `Bearer ${token}`,
194
+ 'Content-Type': 'application/json',
195
+ },
196
+ body: JSON.stringify({
197
+ name: file.name,
198
+ content: code.toString(),
199
+ labels: {
200
+ properties: {
201
+ type: file.type,
202
+ },
203
+ },
204
+ }),
205
+ });
206
+ if (!response.ok) {
207
+ console.error(chalk.red(`Failed to send extracted code from ${file.path}: ${response.statusText}`));
208
+ }
209
+ else {
210
+ console.log(chalk.green(`Code from ${file.path} extracted and sent to mesh endpoint`));
211
+ }
212
+ });
@@ -1 +1,2 @@
1
1
  export { generateSites, generateMetadata, getComponentList, generatePlugins, ModuleType, } from '@sitecore-content-sdk/core/tools';
2
+ export { extractComponents } from './codegen/extract-components';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sitecore-content-sdk/nextjs",
3
- "version": "0.2.0-beta.4",
3
+ "version": "0.2.0-beta.6",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "sideEffects": false,
@@ -33,15 +33,14 @@
33
33
  "@sitecore-cloudsdk/core": "^0.5.0",
34
34
  "@sitecore-cloudsdk/personalize": "^0.5.0",
35
35
  "@testing-library/dom": "^10.4.0",
36
- "@testing-library/react": "^16.2.0",
36
+ "@testing-library/react": "^16.3.0",
37
37
  "@types/chai": "^4.3.4",
38
38
  "@types/chai-as-promised": "^7.1.5",
39
39
  "@types/chai-string": "^1.4.2",
40
40
  "@types/mocha": "^10.0.1",
41
41
  "@types/node": "~22.9.0",
42
- "@types/prop-types": "^15.7.5",
43
- "@types/react": "^18.2.45",
44
- "@types/react-dom": "^18.0.10",
42
+ "@types/react": "^19.1.2",
43
+ "@types/react-dom": "^19.1.3",
45
44
  "@types/sinon": "^10.0.13",
46
45
  "@types/sinon-chai": "^3.2.9",
47
46
  "chai": "^4.3.7",
@@ -51,15 +50,15 @@
51
50
  "cross-fetch": "^4.1.0",
52
51
  "del-cli": "^6.0.0",
53
52
  "eslint": "^8.56.0",
54
- "eslint-plugin-react": "^7.32.1",
53
+ "eslint-plugin-react": "^7.37.5",
55
54
  "jsdom": "^26.0.0",
56
55
  "mocha": "^11.1.0",
57
- "next": "^14.2.18",
56
+ "next": "^15.3.1",
58
57
  "nock": "14.0.0-beta.7",
59
58
  "nyc": "^17.1.0",
60
59
  "proxyquire": "^2.1.3",
61
- "react": "^18.2.0",
62
- "react-dom": "^18.2.0",
60
+ "react": "^19.0.0",
61
+ "react-dom": "^19.0.0",
63
62
  "sinon": "^19.0.2",
64
63
  "sinon-chai": "^3.7.0",
65
64
  "ts-node": "^10.9.1",
@@ -69,23 +68,28 @@
69
68
  "@sitecore-cloudsdk/core": "^0.5.0",
70
69
  "@sitecore-cloudsdk/events": "^0.5.0",
71
70
  "@sitecore-cloudsdk/personalize": "^0.5.0",
72
- "next": "^14.2.18",
73
- "react": "^18.2.0",
74
- "react-dom": "^18.2.0"
71
+ "next": "^15.3.1",
72
+ "react": "^19.1.0",
73
+ "react-dom": "^19.1.0",
74
+ "typescript": "^5.4.0"
75
+ },
76
+ "peerDependenciesMeta": {
77
+ "typescript": {
78
+ "optional": true
79
+ }
75
80
  },
76
81
  "dependencies": {
77
82
  "@babel/parser": "^7.26.10",
78
- "@sitecore-content-sdk/core": "0.2.0-beta.4",
79
- "@sitecore-content-sdk/react": "0.2.0-beta.4",
83
+ "@sitecore-content-sdk/core": "0.2.0-beta.6",
84
+ "@sitecore-content-sdk/react": "0.2.0-beta.6",
80
85
  "@vercel/kv": "^3.0.0",
81
- "prop-types": "^15.8.1",
82
86
  "recast": "^0.23.11",
83
87
  "regex-parser": "^2.3.0",
84
88
  "sync-disk-cache": "^2.1.0"
85
89
  },
86
90
  "description": "",
87
91
  "types": "types/index.d.ts",
88
- "gitHead": "750ea744c6ba45e5480c921acf549ec48c53b303",
92
+ "gitHead": "a56ee0c0a3897b5f9915329e20469fa427ee13a8",
89
93
  "files": [
90
94
  "dist",
91
95
  "types",
@@ -1,4 +1,4 @@
1
- import React, { ReactNode } from 'react';
1
+ import React, { ReactNode, JSX } from 'react';
2
2
  import { ComponentPropsCollection } from '../sharedTypes/component-props';
3
3
  /**
4
4
  * Component props context which we are using in order to store data fetched on components level (getStaticProps/getServerSideProps)
@@ -1,5 +1,4 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
1
+ import { JSX } from 'react';
3
2
  import { RichTextProps as ReactRichTextProps } from '@sitecore-content-sdk/react';
4
3
  export type RichTextProps = ReactRichTextProps & {
5
4
  /**
@@ -22,17 +21,5 @@ export declare const prefetched: {
22
21
  };
23
22
  export declare const RichText: {
24
23
  (props: RichTextProps): JSX.Element;
25
- propTypes: {
26
- field: PropTypes.Requireable<PropTypes.InferProps<{
27
- value: PropTypes.Requireable<string>;
28
- metadata: PropTypes.Requireable<{
29
- [x: string]: any;
30
- }>;
31
- }>>;
32
- tag: PropTypes.Requireable<string>;
33
- editable: PropTypes.Requireable<boolean>;
34
- emptyFieldEditingComponent: PropTypes.Requireable<NonNullable<React.ComponentClass<unknown, any> | React.FC<unknown>>>;
35
- internalLinksSelector: PropTypes.Requireable<string>;
36
- };
37
24
  displayName: string;
38
25
  };
@@ -0,0 +1,10 @@
1
+ import { SitecoreConfig } from '@sitecore-content-sdk/core/config';
2
+ export type ExtractComponentsConfig = {
3
+ scConfig: SitecoreConfig;
4
+ componentMapPath?: string;
5
+ };
6
+ /**
7
+ * Extracts components from the app folder and sends them to XMCloud.
8
+ * @param {ExtractComponentsConfig} args - Config for components extraction
9
+ */
10
+ export declare const extractComponents: (args: ExtractComponentsConfig) => () => Promise<void>;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Description properties for the files sent to the mesh endpoint
3
+ */
4
+ export type ExtractedFile = {
5
+ name: string;
6
+ path: string;
7
+ type: ExtractedFileType;
8
+ };
9
+ /**
10
+ * Type of file to be sent to the mesh endpoint
11
+ */
12
+ export declare enum ExtractedFileType {
13
+ Component = "component",
14
+ Json = "json",
15
+ Package = "package.json"
16
+ }
17
+ /**
18
+ * Validates consent for code extraction procedures
19
+ * @returns {boolean} - true if consent is given, false otherwise
20
+ */
21
+ export declare const validateConsent: () => boolean;
22
+ /**
23
+ * Validates if the current operation is done in Vercel, Netlify or XMCloud
24
+ * deploy context
25
+ * @returns {boolean} - true if in deploy context, false otherwise
26
+ */
27
+ export declare const validateDeployContext: () => boolean;
28
+ /**
29
+ * Parses the componentBuilder.ts file and returns a map of component names
30
+ * and their respective import strings
31
+ * @param {string} appPath path to the JSS app root
32
+ * @param {string} [componentMapPath] path to the app's component map file. Default: 'src/lib/componentMap.ts'
33
+ * @returns map of component names and their respective import strings
34
+ */
35
+ export declare const resolveComponentImportFiles: (appPath: string, componentMapPath?: string) => Map<string, string>;
36
+ export declare const sendCode: ({ file, token, edgeUrl, }: {
37
+ file: ExtractedFile;
38
+ token: string;
39
+ edgeUrl?: string;
40
+ }) => Promise<void>;
@@ -1 +1,2 @@
1
1
  export { generateSites, GenerateSitesConfig, generateMetadata, ComponentFile, PackageDefinition, getComponentList, PluginDefinition, generatePlugins, ModuleType, } from '@sitecore-content-sdk/core/tools';
2
+ export { extractComponents } from './codegen/extract-components';