@sitecore-jss/sitecore-jss 22.4.1 → 22.5.0-beta.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.
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RestComponentLayoutService = void 0;
4
+ const rest_layout_service_1 = require("../layout/rest-layout-service");
5
+ const __1 = require("..");
6
+ /**
7
+ * REST service that enables Component Library functioality
8
+ * Makes a request to /sitecore/api/layout/component in 'library' mode in Pages.
9
+ * Returns layoutData for one single rendered component
10
+ */
11
+ class RestComponentLayoutService extends rest_layout_service_1.RestLayoutService {
12
+ constructor(config) {
13
+ super(config);
14
+ this.config = config;
15
+ }
16
+ fetchComponentData(params, req, res) {
17
+ params.siteName = params.siteName || this.config.siteName;
18
+ const querystringParams = this.getComponentFetchParams(params);
19
+ __1.debug.layout('fetching component with uid %s for %s %s %s', params.componentUid, params.itemId, params.language, params.siteName);
20
+ const fetcher = this.getFetcher(req, res);
21
+ const fetchUrl = this.resolveLayoutServiceUrl('component');
22
+ return (0, __1.fetchData)(fetchUrl, fetcher, querystringParams).catch((error) => {
23
+ var _a;
24
+ if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
25
+ return error.response.data;
26
+ }
27
+ throw error;
28
+ });
29
+ }
30
+ getComponentFetchParams(params) {
31
+ // exclude undefined params with this one simple trick
32
+ return JSON.parse(JSON.stringify({
33
+ sc_apikey: this.config.apiKey,
34
+ item: params.itemId,
35
+ uid: params.componentUid,
36
+ dataSourceId: params.dataSourceId,
37
+ renderingItemId: params.renderingId,
38
+ version: params.version,
39
+ sc_site: params.siteName,
40
+ sc_lang: params.language || 'en',
41
+ sc_mode: params.editMode,
42
+ }));
43
+ }
44
+ }
45
+ exports.RestComponentLayoutService = RestComponentLayoutService;
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getComponentLibraryStylesheetLinks = exports.GRAPHQL_LAYOUT_QUERY_NAME = exports.GraphQLLayoutService = exports.RestLayoutService = exports.getContentStylesheetLink = exports.EMPTY_DATE_FIELD_VALUE = exports.getDynamicPlaceholderPattern = exports.isDynamicPlaceholder = exports.isFieldValueEmpty = exports.getChildPlaceholder = exports.getFieldValue = exports.EditMode = exports.LayoutServicePageState = void 0;
3
+ exports.getComponentLibraryStylesheetLinks = exports.GRAPHQL_LAYOUT_QUERY_NAME = exports.GraphQLLayoutService = exports.RestLayoutService = exports.getContentStylesheetLink = exports.EMPTY_DATE_FIELD_VALUE = exports.getDynamicPlaceholderPattern = exports.isDynamicPlaceholder = exports.isFieldValueEmpty = exports.getChildPlaceholder = exports.getFieldValue = exports.EDITING_COMPONENT_ID = exports.EDITING_COMPONENT_PLACEHOLDER = exports.RenderingType = exports.EditMode = exports.LayoutServicePageState = void 0;
4
4
  // layout
5
5
  var models_1 = require("./models");
6
6
  Object.defineProperty(exports, "LayoutServicePageState", { enumerable: true, get: function () { return models_1.LayoutServicePageState; } });
7
7
  Object.defineProperty(exports, "EditMode", { enumerable: true, get: function () { return models_1.EditMode; } });
8
+ Object.defineProperty(exports, "RenderingType", { enumerable: true, get: function () { return models_1.RenderingType; } });
9
+ Object.defineProperty(exports, "EDITING_COMPONENT_PLACEHOLDER", { enumerable: true, get: function () { return models_1.EDITING_COMPONENT_PLACEHOLDER; } });
10
+ Object.defineProperty(exports, "EDITING_COMPONENT_ID", { enumerable: true, get: function () { return models_1.EDITING_COMPONENT_ID; } });
8
11
  var utils_1 = require("./utils");
9
12
  Object.defineProperty(exports, "getFieldValue", { enumerable: true, get: function () { return utils_1.getFieldValue; } });
10
13
  Object.defineProperty(exports, "getChildPlaceholder", { enumerable: true, get: function () { return utils_1.getChildPlaceholder; } });
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EditMode = exports.LayoutServicePageState = void 0;
3
+ exports.EDITING_COMPONENT_ID = exports.EDITING_COMPONENT_PLACEHOLDER = exports.RenderingType = exports.EditMode = exports.LayoutServicePageState = void 0;
4
4
  /**
5
5
  * Layout Service page state enum
6
+ * library mode would render a single component
6
7
  */
7
8
  var LayoutServicePageState;
8
9
  (function (LayoutServicePageState) {
@@ -20,3 +21,18 @@ var EditMode;
20
21
  EditMode["Chromes"] = "chromes";
21
22
  EditMode["Metadata"] = "metadata";
22
23
  })(EditMode || (exports.EditMode = EditMode = {}));
24
+ /**
25
+ * Editing rendering type
26
+ */
27
+ var RenderingType;
28
+ (function (RenderingType) {
29
+ RenderingType["Component"] = "component";
30
+ })(RenderingType || (exports.RenderingType = RenderingType = {}));
31
+ /**
32
+ * Static placeholder name used for component rendering
33
+ */
34
+ exports.EDITING_COMPONENT_PLACEHOLDER = 'editing-componentmode-placeholder';
35
+ /**
36
+ * Id of wrapper for component rendering
37
+ */
38
+ exports.EDITING_COMPONENT_ID = 'editing-component';
@@ -40,6 +40,11 @@ class RestLayoutService extends layout_service_1.LayoutServiceBase {
40
40
  tracking: (_a = this.serviceConfig.tracking) !== null && _a !== void 0 ? _a : true,
41
41
  };
42
42
  };
43
+ this.getFetcher = (req, res) => {
44
+ return this.serviceConfig.dataFetcherResolver
45
+ ? this.serviceConfig.dataFetcherResolver(req, res)
46
+ : this.getDefaultFetcher(req, res);
47
+ };
43
48
  /**
44
49
  * Returns a fetcher function pre-configured with headers from the incoming request.
45
50
  * Provides default @see NativeDataFetcher data fetcher
@@ -77,9 +82,7 @@ class RestLayoutService extends layout_service_1.LayoutServiceBase {
77
82
  var _a;
78
83
  const querystringParams = this.getFetchParams(language);
79
84
  debug_1.default.layout('fetching layout data for %s %s %s', itemPath, language, this.serviceConfig.siteName);
80
- const fetcher = this.serviceConfig.dataFetcherResolver
81
- ? this.serviceConfig.dataFetcherResolver(req, res)
82
- : this.getDefaultFetcher(req, res);
85
+ const fetcher = this.getFetcher(req, res);
83
86
  const fetchUrl = this.resolveLayoutServiceUrl('render');
84
87
  try {
85
88
  return yield (0, data_fetcher_1.fetchData)(fetchUrl, fetcher, Object.assign({ item: itemPath }, querystringParams));
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Event to be sent when report status to component library
3
+ */
4
+ export const COMPONENT_LIBRARY_STATUS_EVENT_NAME = 'component:status';
5
+ /**
6
+ * Enumeration of statuses for the component library.
7
+ */
8
+ export var ComponentLibraryStatus;
9
+ (function (ComponentLibraryStatus) {
10
+ ComponentLibraryStatus["READY"] = "ready";
11
+ ComponentLibraryStatus["RENDERED"] = "rendered";
12
+ })(ComponentLibraryStatus || (ComponentLibraryStatus = {}));
13
+ /**
14
+ * Adds the browser-side event handler for 'component:update' message used in Component Library
15
+ * The event should update a component on page by uid, with fields and params from event args
16
+ * @param {ComponentRendering} rootComponent root component displayed for Component Library page
17
+ * @param {Function} successCallback callback to be called after successful component update
18
+ */
19
+ export const addComponentUpdateHandler = (rootComponent, successCallback) => {
20
+ if (!window)
21
+ return;
22
+ const handler = (e) => updateComponentHandler(e, rootComponent, successCallback);
23
+ window.addEventListener('message', handler);
24
+ // the power to remove handler outside of this function, if needed
25
+ const unsubscribe = () => {
26
+ window.removeEventListener('message', handler);
27
+ };
28
+ return unsubscribe;
29
+ };
30
+ const validateOrigin = (event) => {
31
+ // TODO: use `EDITING_ALLOWED_ORIGINS.concat(getAllowedOriginsFromEnv())` later
32
+ // nextjs's JSS_ALLOWED_ORIGINS is not available on the client, need to use NEXT_PUBLIC_ variable, but it's a breaking change for Deploy
33
+ const allowedOrigins = ['*'];
34
+ return allowedOrigins.some((origin) => origin === event.origin ||
35
+ new RegExp('^' + origin.replace('.', '\\.').replace(/\*/g, '.*') + '$').test(event.origin));
36
+ };
37
+ export const updateComponentHandler = (e, rootComponent, successCallback) => {
38
+ var _a;
39
+ const eventArgs = e.data;
40
+ if (!e.origin || !eventArgs || eventArgs.name !== 'component:update') {
41
+ // avoid extra noise in logs
42
+ if (!validateOrigin(e)) {
43
+ console.debug('Component Library: event skipped: message %s from origin %s', eventArgs.name, e.origin);
44
+ }
45
+ return;
46
+ }
47
+ if (!((_a = eventArgs.details) === null || _a === void 0 ? void 0 : _a.uid)) {
48
+ console.debug('Received component:update event without uid, aborting event handler...');
49
+ return;
50
+ }
51
+ const findComponent = (root) => {
52
+ var _a, _b;
53
+ if (((_a = root.uid) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === ((_b = eventArgs.details) === null || _b === void 0 ? void 0 : _b.uid.toLowerCase()))
54
+ return root;
55
+ if (root.placeholders) {
56
+ for (const plhName of Object.keys(root.placeholders)) {
57
+ for (const rendering of root.placeholders[plhName]) {
58
+ const result = findComponent(rendering);
59
+ if (result)
60
+ return result;
61
+ }
62
+ }
63
+ }
64
+ return null;
65
+ };
66
+ const updateComponent = findComponent(rootComponent);
67
+ if (updateComponent) {
68
+ console.debug('Found component with uid %s to update. Update fields: %o. Update params: %o.', eventArgs.details.uid, eventArgs.details.fields, eventArgs.details.params);
69
+ if (eventArgs.details.fields) {
70
+ updateComponent.fields = Object.assign(Object.assign({}, updateComponent.fields), eventArgs.details.fields);
71
+ }
72
+ if (eventArgs.details.params) {
73
+ updateComponent.params = Object.assign(Object.assign({}, updateComponent.params), eventArgs.details.params);
74
+ }
75
+ if (successCallback)
76
+ successCallback(rootComponent);
77
+ }
78
+ else {
79
+ console.debug('Rendering with uid %s not found', eventArgs.details.uid);
80
+ }
81
+ // strictly for testing
82
+ return rootComponent;
83
+ };
84
+ /**
85
+ * Generates a ComponentLibraryStatusEvent with the given status and uid.
86
+ * @param {ComponentLibraryStatus} status - The status of rendering.
87
+ * @param {string} uid - The unique identifier for the event.
88
+ * @returns An object representing the ComponentLibraryStatusEvent.
89
+ */
90
+ export function getComponentLibraryStatusEvent(status, uid) {
91
+ return {
92
+ name: COMPONENT_LIBRARY_STATUS_EVENT_NAME,
93
+ message: {
94
+ status,
95
+ uid,
96
+ },
97
+ };
98
+ }
@@ -97,7 +97,7 @@ export class GraphQLEditingService {
97
97
  */
98
98
  fetchEditingData(_a) {
99
99
  return __awaiter(this, arguments, void 0, function* ({ siteName, itemId, language, version, layoutKind = LayoutKind.Final, }) {
100
- var _b, _c, _d, _e, _f;
100
+ var _b, _c, _d;
101
101
  debug.editing('fetching editing data for %s %s %s %s', siteName, itemId, language, version, layoutKind);
102
102
  if (!siteName) {
103
103
  throw new RangeError('The site name must be a non-empty string');
@@ -105,7 +105,6 @@ export class GraphQLEditingService {
105
105
  if (!language) {
106
106
  throw new RangeError('The language must be a non-empty string');
107
107
  }
108
- const dictionary = {};
109
108
  let dictionaryResults = [];
110
109
  let hasNext = true;
111
110
  let after = '';
@@ -127,13 +126,30 @@ export class GraphQLEditingService {
127
126
  else {
128
127
  hasNext = false;
129
128
  }
129
+ const dictionary = yield this.fetchDictionaryData({ siteName, language }, dictionaryResults, hasNext, after);
130
+ return {
131
+ layoutData: ((_d = editingData === null || editingData === void 0 ? void 0 : editingData.item) === null || _d === void 0 ? void 0 : _d.rendered) || {
132
+ sitecore: {
133
+ context: { pageEditing: true, language, editMode: EditMode.Metadata },
134
+ route: null,
135
+ },
136
+ },
137
+ dictionary,
138
+ };
139
+ });
140
+ }
141
+ fetchDictionaryData(_a) {
142
+ return __awaiter(this, arguments, void 0, function* ({ siteName, language, }, initDictionary = [], hasNext = true, after) {
143
+ var _b, _c;
144
+ let dictionaryResults = initDictionary;
145
+ const dictionary = {};
130
146
  while (hasNext) {
131
147
  const data = yield this.graphQLClient.request(dictionaryQuery, {
132
148
  siteName,
133
149
  language,
134
150
  after,
135
151
  });
136
- if ((_e = (_d = data === null || data === void 0 ? void 0 : data.site) === null || _d === void 0 ? void 0 : _d.siteInfo) === null || _e === void 0 ? void 0 : _e.dictionary) {
152
+ if ((_c = (_b = data === null || data === void 0 ? void 0 : data.site) === null || _b === void 0 ? void 0 : _b.siteInfo) === null || _c === void 0 ? void 0 : _c.dictionary) {
137
153
  dictionaryResults = dictionaryResults.concat(data.site.siteInfo.dictionary.results);
138
154
  hasNext = data.site.siteInfo.dictionary.pageInfo.hasNext;
139
155
  after = data.site.siteInfo.dictionary.pageInfo.endCursor;
@@ -143,15 +159,7 @@ export class GraphQLEditingService {
143
159
  }
144
160
  }
145
161
  dictionaryResults.forEach((item) => (dictionary[item.key] = item.value));
146
- return {
147
- layoutData: ((_f = editingData === null || editingData === void 0 ? void 0 : editingData.item) === null || _f === void 0 ? void 0 : _f.rendered) || {
148
- sitecore: {
149
- context: { pageEditing: true, language, editMode: EditMode.Metadata },
150
- route: null,
151
- },
152
- },
153
- dictionary,
154
- };
162
+ return dictionary;
155
163
  });
156
164
  }
157
165
  /**
@@ -1,4 +1,6 @@
1
1
  export { GraphQLEditingService } from './graphql-editing-service';
2
2
  export { DEFAULT_PLACEHOLDER_UID, ExperienceEditor, HorizonEditor, isEditorActive, resetEditorChromes, handleEditorAnchors, getJssPagesClientData, EDITING_ALLOWED_ORIGINS, QUERY_PARAM_EDITING_SECRET, PAGES_EDITING_MARKER, } from './utils';
3
+ export { RestComponentLayoutService, } from './rest-component-layout-service';
3
4
  export { DefaultEditFrameButton, DefaultEditFrameButtons, DefaultEditFrameButtonIds, mapButtonToCommand, } from './edit-frame';
4
5
  export { LayoutKind, MetadataKind } from './models';
6
+ export { addComponentUpdateHandler, ComponentLibraryStatus, getComponentLibraryStatusEvent, } from './component-library';
@@ -0,0 +1,41 @@
1
+ import { RestLayoutService } from '../layout/rest-layout-service';
2
+ import { debug, fetchData } from '..';
3
+ /**
4
+ * REST service that enables Component Library functioality
5
+ * Makes a request to /sitecore/api/layout/component in 'library' mode in Pages.
6
+ * Returns layoutData for one single rendered component
7
+ */
8
+ export class RestComponentLayoutService extends RestLayoutService {
9
+ constructor(config) {
10
+ super(config);
11
+ this.config = config;
12
+ }
13
+ fetchComponentData(params, req, res) {
14
+ params.siteName = params.siteName || this.config.siteName;
15
+ const querystringParams = this.getComponentFetchParams(params);
16
+ debug.layout('fetching component with uid %s for %s %s %s', params.componentUid, params.itemId, params.language, params.siteName);
17
+ const fetcher = this.getFetcher(req, res);
18
+ const fetchUrl = this.resolveLayoutServiceUrl('component');
19
+ return fetchData(fetchUrl, fetcher, querystringParams).catch((error) => {
20
+ var _a;
21
+ if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
22
+ return error.response.data;
23
+ }
24
+ throw error;
25
+ });
26
+ }
27
+ getComponentFetchParams(params) {
28
+ // exclude undefined params with this one simple trick
29
+ return JSON.parse(JSON.stringify({
30
+ sc_apikey: this.config.apiKey,
31
+ item: params.itemId,
32
+ uid: params.componentUid,
33
+ dataSourceId: params.dataSourceId,
34
+ renderingItemId: params.renderingId,
35
+ version: params.version,
36
+ sc_site: params.siteName,
37
+ sc_lang: params.language || 'en',
38
+ sc_mode: params.editMode,
39
+ }));
40
+ }
41
+ }
@@ -1,5 +1,5 @@
1
1
  // layout
2
- export { LayoutServicePageState, EditMode, } from './models';
2
+ export { LayoutServicePageState, EditMode, RenderingType, EDITING_COMPONENT_PLACEHOLDER, EDITING_COMPONENT_ID, } from './models';
3
3
  export { getFieldValue, getChildPlaceholder, isFieldValueEmpty, isDynamicPlaceholder, getDynamicPlaceholderPattern, EMPTY_DATE_FIELD_VALUE, } from './utils';
4
4
  export { getContentStylesheetLink } from './content-styles';
5
5
  export { RestLayoutService, } from './rest-layout-service';
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Layout Service page state enum
3
+ * library mode would render a single component
3
4
  */
4
5
  export var LayoutServicePageState;
5
6
  (function (LayoutServicePageState) {
@@ -17,3 +18,18 @@ export var EditMode;
17
18
  EditMode["Chromes"] = "chromes";
18
19
  EditMode["Metadata"] = "metadata";
19
20
  })(EditMode || (EditMode = {}));
21
+ /**
22
+ * Editing rendering type
23
+ */
24
+ export var RenderingType;
25
+ (function (RenderingType) {
26
+ RenderingType["Component"] = "component";
27
+ })(RenderingType || (RenderingType = {}));
28
+ /**
29
+ * Static placeholder name used for component rendering
30
+ */
31
+ export const EDITING_COMPONENT_PLACEHOLDER = 'editing-componentmode-placeholder';
32
+ /**
33
+ * Id of wrapper for component rendering
34
+ */
35
+ export const EDITING_COMPONENT_ID = 'editing-component';
@@ -34,6 +34,11 @@ export class RestLayoutService extends LayoutServiceBase {
34
34
  tracking: (_a = this.serviceConfig.tracking) !== null && _a !== void 0 ? _a : true,
35
35
  };
36
36
  };
37
+ this.getFetcher = (req, res) => {
38
+ return this.serviceConfig.dataFetcherResolver
39
+ ? this.serviceConfig.dataFetcherResolver(req, res)
40
+ : this.getDefaultFetcher(req, res);
41
+ };
37
42
  /**
38
43
  * Returns a fetcher function pre-configured with headers from the incoming request.
39
44
  * Provides default @see NativeDataFetcher data fetcher
@@ -71,9 +76,7 @@ export class RestLayoutService extends LayoutServiceBase {
71
76
  var _a;
72
77
  const querystringParams = this.getFetchParams(language);
73
78
  debug.layout('fetching layout data for %s %s %s', itemPath, language, this.serviceConfig.siteName);
74
- const fetcher = this.serviceConfig.dataFetcherResolver
75
- ? this.serviceConfig.dataFetcherResolver(req, res)
76
- : this.getDefaultFetcher(req, res);
79
+ const fetcher = this.getFetcher(req, res);
77
80
  const fetchUrl = this.resolveLayoutServiceUrl('render');
78
81
  try {
79
82
  return yield fetchData(fetchUrl, fetcher, Object.assign({ item: itemPath }, querystringParams));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sitecore-jss/sitecore-jss",
3
- "version": "22.4.1",
3
+ "version": "22.5.0-beta.1",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "sideEffects": false,
@@ -65,7 +65,7 @@
65
65
  },
66
66
  "description": "",
67
67
  "types": "types/index.d.ts",
68
- "gitHead": "627a7190d59f910247e54329198d7bf842d97916",
68
+ "gitHead": "e080916b354c36e63f29f01fbcb87688d7f2b4cd",
69
69
  "files": [
70
70
  "dist",
71
71
  "types",
@@ -0,0 +1,48 @@
1
+ import { ComponentRendering, Field, GenericFieldValue } from '../layout/models';
2
+ /**
3
+ * Event to be sent when report status to component library
4
+ */
5
+ export declare const COMPONENT_LIBRARY_STATUS_EVENT_NAME = "component:status";
6
+ /**
7
+ * Represents an event indicating the status of a component in the library.
8
+ */
9
+ export interface ComponentLibraryStatusEvent {
10
+ name: typeof COMPONENT_LIBRARY_STATUS_EVENT_NAME;
11
+ message: {
12
+ status: 'ready' | 'rendered';
13
+ uid: string;
14
+ };
15
+ }
16
+ /**
17
+ * Enumeration of statuses for the component library.
18
+ */
19
+ export declare enum ComponentLibraryStatus {
20
+ READY = "ready",
21
+ RENDERED = "rendered"
22
+ }
23
+ /**
24
+ * Event args for Component Library `update` event
25
+ */
26
+ export interface ComponentUpdateEventArgs {
27
+ name: string;
28
+ details?: {
29
+ uid: string;
30
+ params?: Record<string, string>;
31
+ fields?: Record<string, Field<GenericFieldValue>>;
32
+ };
33
+ }
34
+ /**
35
+ * Adds the browser-side event handler for 'component:update' message used in Component Library
36
+ * The event should update a component on page by uid, with fields and params from event args
37
+ * @param {ComponentRendering} rootComponent root component displayed for Component Library page
38
+ * @param {Function} successCallback callback to be called after successful component update
39
+ */
40
+ export declare const addComponentUpdateHandler: (rootComponent: ComponentRendering, successCallback?: (updatedRootComponent: ComponentRendering) => void) => (() => void) | undefined;
41
+ export declare const updateComponentHandler: (e: MessageEvent, rootComponent: ComponentRendering, successCallback?: (updatedRootComponent: ComponentRendering) => void) => ComponentRendering<import("../layout/models").ComponentFields> | undefined;
42
+ /**
43
+ * Generates a ComponentLibraryStatusEvent with the given status and uid.
44
+ * @param {ComponentLibraryStatus} status - The status of rendering.
45
+ * @param {string} uid - The unique identifier for the event.
46
+ * @returns An object representing the ComponentLibraryStatusEvent.
47
+ */
48
+ export declare function getComponentLibraryStatusEvent(status: ComponentLibraryStatus, uid: string): ComponentLibraryStatusEvent;
@@ -75,6 +75,13 @@ export declare class GraphQLEditingService {
75
75
  layoutData: LayoutServiceData;
76
76
  dictionary: DictionaryPhrases;
77
77
  }>;
78
+ fetchDictionaryData({ siteName, language, }: {
79
+ siteName: string;
80
+ language: string;
81
+ }, initDictionary?: {
82
+ key: string;
83
+ value: string;
84
+ }[], hasNext?: boolean, after?: string): Promise<DictionaryPhrases>;
78
85
  /**
79
86
  * Gets a GraphQL client that can make requests to the API.
80
87
  * @returns {GraphQLClient} implementation
@@ -1,5 +1,7 @@
1
1
  export { GraphQLEditingService } from './graphql-editing-service';
2
- export { DEFAULT_PLACEHOLDER_UID, ExperienceEditor, HorizonEditor, isEditorActive, resetEditorChromes, handleEditorAnchors, Metadata, getJssPagesClientData, EDITING_ALLOWED_ORIGINS, QUERY_PARAM_EDITING_SECRET, PAGES_EDITING_MARKER, } from './utils';
2
+ export { DEFAULT_PLACEHOLDER_UID, ExperienceEditor, HorizonEditor, isEditorActive, resetEditorChromes, handleEditorAnchors, Metadata, getJssPagesClientData, EDITING_ALLOWED_ORIGINS, QUERY_PARAM_EDITING_SECRET, PAGES_EDITING_MARKER, ComponentUpdateEventArgs, } from './utils';
3
+ export { RestComponentLayoutService, ComponentLayoutRequestParams, } from './rest-component-layout-service';
3
4
  export { DefaultEditFrameButton, DefaultEditFrameButtons, DefaultEditFrameButtonIds, EditFrameDataSource, ChromeCommand, FieldEditButton, WebEditButton, EditButtonTypes, mapButtonToCommand, } from './edit-frame';
4
- export { RenderMetadataQueryParams } from './models';
5
+ export { RenderMetadataQueryParams, RenderComponentQueryParams } from './models';
5
6
  export { LayoutKind, MetadataKind } from './models';
7
+ export { addComponentUpdateHandler, ComponentLibraryStatus, ComponentLibraryStatusEvent, getComponentLibraryStatusEvent, } from './component-library';
@@ -2,6 +2,7 @@ import { LayoutServicePageState } from '../layout';
2
2
  /**
3
3
  * Query parameters appended to the page route URL
4
4
  * Appended when XMCloud Pages preview (editing) Metadata Edit Mode is used
5
+ * `mode` is a special case as it serves editing and component library both
5
6
  */
6
7
  export interface RenderMetadataQueryParams {
7
8
  [key: string]: unknown;
@@ -10,11 +11,27 @@ export interface RenderMetadataQueryParams {
10
11
  sc_itemid: string;
11
12
  sc_site: string;
12
13
  route: string;
13
- mode: Exclude<LayoutServicePageState, 'normal'>;
14
+ mode: Exclude<LayoutServicePageState, 'normal'> | 'library';
14
15
  sc_layoutKind?: LayoutKind;
15
16
  sc_variant?: string;
16
17
  sc_version?: string;
17
18
  }
19
+ /**
20
+ * Query parameters appended for Component Library functionaity.
21
+ * Used when a single component is rendered in Pages.
22
+ */
23
+ export interface RenderComponentQueryParams {
24
+ [key: string]: unknown;
25
+ secret: string;
26
+ sc_lang: string;
27
+ sc_itemid: string;
28
+ sc_renderingId: string;
29
+ sc_uid: string;
30
+ sc_site: string;
31
+ mode: 'library';
32
+ sc_variant?: string;
33
+ sc_version?: string;
34
+ }
18
35
  /**
19
36
  * Represents the Editing Layout variant.
20
37
  * - shared - shared layout
@@ -0,0 +1,52 @@
1
+ import { RestLayoutServiceConfig, RestLayoutService } from '../layout/rest-layout-service';
2
+ import { LayoutServiceData, EditMode } from '../layout/models';
3
+ import { IncomingMessage, ServerResponse } from 'http';
4
+ /**
5
+ * Params for requesting component data from service in Component Library mode
6
+ */
7
+ export interface ComponentLayoutRequestParams {
8
+ /**
9
+ * Item id to be used as context for rendering the component
10
+ */
11
+ itemId: string;
12
+ /**
13
+ * Component identifier. Can be either taken from item's layout details or
14
+ * an arbitrary one (component renderingId and datasource would be used for identification then)
15
+ */
16
+ componentUid: string;
17
+ /**
18
+ * language to render component in
19
+ */
20
+ language?: string;
21
+ /**
22
+ * optional component datasource
23
+ */
24
+ dataSourceId?: string;
25
+ /**
26
+ * ID of the component definition rendering item in Sitecore
27
+ */
28
+ renderingId?: string;
29
+ /**
30
+ * version of the context item (latest by default)
31
+ */
32
+ version?: string;
33
+ /**
34
+ * edit mode (edit, preview) to be rendered component in. Component is rendered in normal mode by default
35
+ */
36
+ editMode?: EditMode;
37
+ /**
38
+ * site name to be used as context for rendering the component
39
+ */
40
+ siteName?: string;
41
+ }
42
+ /**
43
+ * REST service that enables Component Library functioality
44
+ * Makes a request to /sitecore/api/layout/component in 'library' mode in Pages.
45
+ * Returns layoutData for one single rendered component
46
+ */
47
+ export declare class RestComponentLayoutService extends RestLayoutService {
48
+ private config;
49
+ constructor(config: RestLayoutServiceConfig);
50
+ fetchComponentData(params: ComponentLayoutRequestParams, req?: IncomingMessage, res?: ServerResponse): Promise<LayoutServiceData>;
51
+ protected getComponentFetchParams(params: ComponentLayoutRequestParams): any;
52
+ }
@@ -1,3 +1,4 @@
1
+ import { Field, GenericFieldValue } from '../layout/models';
1
2
  /**
2
3
  * Default value of uid for root placeholder when uid is not present.
3
4
  */
@@ -15,6 +16,17 @@ export declare const PAGES_EDITING_MARKER = "jss-hrz-editing";
15
16
  * Default allowed origins for editing requests. This is used to enforce CORS, CSP headers.
16
17
  */
17
18
  export declare const EDITING_ALLOWED_ORIGINS: string[];
19
+ /**
20
+ * Event args for Component Library `update` event
21
+ */
22
+ export interface ComponentUpdateEventArgs {
23
+ name: string;
24
+ details?: {
25
+ uid: string;
26
+ params?: Record<string, string>;
27
+ fields?: Record<string, Field<GenericFieldValue>>;
28
+ };
29
+ }
18
30
  /**
19
31
  * Application metadata
20
32
  */
@@ -1,4 +1,4 @@
1
- export { LayoutServiceData, LayoutServicePageState, LayoutServiceContext, LayoutServiceContextData, RouteData, PlaceholderData, ComponentRendering, HtmlElementRendering, Field, GenericFieldValue, Item, PlaceholdersData, ComponentFields, ComponentParams, EditMode, FieldMetadata, } from './models';
1
+ export { LayoutServiceData, LayoutServicePageState, LayoutServiceContext, LayoutServiceContextData, RouteData, PlaceholderData, ComponentRendering, HtmlElementRendering, Field, GenericFieldValue, Item, PlaceholdersData, ComponentFields, ComponentParams, EditMode, FieldMetadata, RenderingType, EDITING_COMPONENT_PLACEHOLDER, EDITING_COMPONENT_ID, } from './models';
2
2
  export { getFieldValue, getChildPlaceholder, isFieldValueEmpty, isDynamicPlaceholder, getDynamicPlaceholderPattern, EMPTY_DATE_FIELD_VALUE, } from './utils';
3
3
  export { getContentStylesheetLink } from './content-styles';
4
4
  export { LayoutService } from './layout-service';
@@ -8,6 +8,7 @@ export interface LayoutServiceData {
8
8
  }
9
9
  /**
10
10
  * Layout Service page state enum
11
+ * library mode would render a single component
11
12
  */
12
13
  export declare enum LayoutServicePageState {
13
14
  Preview = "preview",
@@ -36,6 +37,7 @@ export interface LayoutServiceContext {
36
37
  site?: {
37
38
  name?: string;
38
39
  };
40
+ renderingType?: RenderingType;
39
41
  editMode?: EditMode;
40
42
  clientScripts?: string[];
41
43
  clientData?: Record<string, Record<string, unknown>>;
@@ -144,3 +146,17 @@ export interface PlaceholderData {
144
146
  path: string;
145
147
  elements: Array<HtmlElementRendering | ComponentRendering>;
146
148
  }
149
+ /**
150
+ * Editing rendering type
151
+ */
152
+ export declare enum RenderingType {
153
+ Component = "component"
154
+ }
155
+ /**
156
+ * Static placeholder name used for component rendering
157
+ */
158
+ export declare const EDITING_COMPONENT_PLACEHOLDER = "editing-componentmode-placeholder";
159
+ /**
160
+ * Id of wrapper for component rendering
161
+ */
162
+ export declare const EDITING_COMPONENT_ID = "editing-component";
@@ -81,12 +81,13 @@ export declare class RestLayoutService extends LayoutServiceBase {
81
81
  * @returns {FetchOptions} fetch options
82
82
  */
83
83
  protected getFetchParams: (language?: string) => FetchParams;
84
+ protected getFetcher: (req?: IncomingMessage, res?: ServerResponse) => HttpDataFetcher<LayoutServiceData> | NativeDataFetcherFunction<LayoutServiceData>;
84
85
  /**
85
86
  * Resolves layout service url
86
87
  * @param {string} apiType which layout service API to call ('render' or 'placeholder')
87
88
  * @returns the layout service url
88
89
  */
89
- protected resolveLayoutServiceUrl(apiType: 'render' | 'placeholder'): string;
90
+ protected resolveLayoutServiceUrl(apiType: 'render' | 'placeholder' | 'component'): string;
90
91
  /**
91
92
  * Returns a fetcher function pre-configured with headers from the incoming request.
92
93
  * Provides default @see NativeDataFetcher data fetcher