@dotcms/client 0.0.1-alpha.9 → 0.0.1-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/README.md +166 -19
- package/index.cjs.d.ts +1 -0
- package/index.cjs.default.js +1 -0
- package/index.cjs.js +914 -0
- package/index.cjs.mjs +2 -0
- package/index.esm.d.ts +1 -0
- package/index.esm.js +903 -0
- package/next.cjs.d.ts +1 -0
- package/next.cjs.default.js +1 -0
- package/next.cjs.js +553 -0
- package/next.cjs.mjs +2 -0
- package/next.esm.d.ts +1 -0
- package/next.esm.js +551 -0
- package/package.json +59 -23
- package/src/index.d.ts +8 -0
- package/src/lib/client/client.d.ts +84 -0
- package/src/lib/client/content/builders/collection/collection.d.ts +226 -0
- package/src/lib/client/content/builders/query/lucene-syntax/Equals.d.ts +114 -0
- package/src/lib/client/content/builders/query/lucene-syntax/Field.d.ts +32 -0
- package/src/lib/client/content/builders/query/lucene-syntax/NotOperand.d.ts +26 -0
- package/src/lib/client/content/builders/query/lucene-syntax/Operand.d.ts +44 -0
- package/src/lib/client/content/builders/query/lucene-syntax/index.d.ts +4 -0
- package/src/lib/client/content/builders/query/query.d.ts +76 -0
- package/src/lib/client/content/builders/query/utils/index.d.ts +142 -0
- package/src/lib/client/content/content-api.d.ts +129 -0
- package/src/lib/client/content/shared/const.d.ts +13 -0
- package/src/lib/client/content/shared/types.d.ts +138 -0
- package/src/lib/client/content/shared/utils.d.ts +20 -0
- package/src/lib/client/models/index.d.ts +12 -0
- package/src/lib/client/models/types.d.ts +516 -0
- package/src/lib/client/navigation/navigation-api.d.ts +31 -0
- package/src/lib/client/page/page-api.d.ts +165 -0
- package/src/lib/client/page/utils.d.ts +41 -0
- package/src/lib/deprecated/editor/listeners/listeners.d.ts +45 -0
- package/src/lib/deprecated/editor/models/client.model.d.ts +111 -0
- package/src/lib/deprecated/editor/models/editor.model.d.ts +62 -0
- package/src/lib/deprecated/editor/models/inline-event.model.d.ts +9 -0
- package/src/lib/{editor/models/listeners.model.ts → deprecated/editor/models/listeners.model.d.ts} +17 -8
- package/src/lib/deprecated/editor/sdk-editor-vtl.d.ts +1 -0
- package/src/lib/deprecated/editor/sdk-editor.d.ts +92 -0
- package/src/lib/deprecated/editor/utils/editor.utils.d.ts +159 -0
- package/src/lib/deprecated/editor/utils/traditional-vtl.utils.d.ts +4 -0
- package/src/lib/deprecated/sdk-js-client.d.ts +276 -0
- package/src/lib/utils/graphql/transforms.d.ts +24 -0
- package/src/lib/utils/index.d.ts +2 -0
- package/src/lib/utils/page/common-utils.d.ts +33 -0
- package/src/next.d.ts +1 -0
- package/src/types.d.ts +2 -0
- package/transforms.cjs.js +1145 -0
- package/transforms.esm.js +1139 -0
- package/types.cjs.d.ts +1 -0
- package/types.cjs.default.js +1 -0
- package/types.cjs.js +2 -0
- package/types.cjs.mjs +2 -0
- package/types.esm.d.ts +1 -0
- package/types.esm.js +1 -0
- package/.eslintrc.json +0 -18
- package/jest.config.ts +0 -15
- package/project.json +0 -63
- package/src/index.ts +0 -4
- package/src/lib/client/sdk-js-client.spec.ts +0 -258
- package/src/lib/client/sdk-js-client.ts +0 -297
- package/src/lib/editor/listeners/listeners.spec.ts +0 -55
- package/src/lib/editor/listeners/listeners.ts +0 -200
- package/src/lib/editor/models/client.model.ts +0 -55
- package/src/lib/editor/models/editor.model.ts +0 -17
- package/src/lib/editor/sdk-editor-vtl.ts +0 -24
- package/src/lib/editor/sdk-editor.spec.ts +0 -95
- package/src/lib/editor/sdk-editor.ts +0 -70
- package/src/lib/editor/utils/editor.utils.spec.ts +0 -164
- package/src/lib/editor/utils/editor.utils.ts +0 -151
- package/tsconfig.json +0 -22
- package/tsconfig.lib.json +0 -10
- package/tsconfig.spec.json +0 -9
package/index.esm.js
ADDED
|
@@ -0,0 +1,903 @@
|
|
|
1
|
+
import { _ as __classPrivateFieldGet, E as ErrorMessages, a as __classPrivateFieldSet, C as Content } from './transforms.esm.js';
|
|
2
|
+
export { g as graphqlToPageEntity } from './transforms.esm.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Actions received from the dotcms editor
|
|
6
|
+
*
|
|
7
|
+
* @export
|
|
8
|
+
* @enum {number}
|
|
9
|
+
*/
|
|
10
|
+
var NOTIFY_CLIENT;
|
|
11
|
+
(function (NOTIFY_CLIENT) {
|
|
12
|
+
/**
|
|
13
|
+
* Request to page to reload
|
|
14
|
+
*/
|
|
15
|
+
NOTIFY_CLIENT["UVE_RELOAD_PAGE"] = "uve-reload-page";
|
|
16
|
+
/**
|
|
17
|
+
* Request the bounds for the elements
|
|
18
|
+
*/
|
|
19
|
+
NOTIFY_CLIENT["UVE_REQUEST_BOUNDS"] = "uve-request-bounds";
|
|
20
|
+
/**
|
|
21
|
+
* Received pong from the editor
|
|
22
|
+
*/
|
|
23
|
+
NOTIFY_CLIENT["UVE_EDITOR_PONG"] = "uve-editor-pong";
|
|
24
|
+
/**
|
|
25
|
+
* Received scroll event trigger from the editor
|
|
26
|
+
*/
|
|
27
|
+
NOTIFY_CLIENT["UVE_SCROLL_INSIDE_IFRAME"] = "uve-scroll-inside-iframe";
|
|
28
|
+
/**
|
|
29
|
+
* Set the page data
|
|
30
|
+
*/
|
|
31
|
+
NOTIFY_CLIENT["UVE_SET_PAGE_DATA"] = "uve-set-page-data";
|
|
32
|
+
/**
|
|
33
|
+
* Copy contentlet inline editing success
|
|
34
|
+
*/
|
|
35
|
+
NOTIFY_CLIENT["UVE_COPY_CONTENTLET_INLINE_EDITING_SUCCESS"] = "uve-copy-contentlet-inline-editing-success";
|
|
36
|
+
})(NOTIFY_CLIENT || (NOTIFY_CLIENT = {}));
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Calculates the bounding information for each page element within the given containers.
|
|
40
|
+
*
|
|
41
|
+
* @export
|
|
42
|
+
* @param {HTMLDivElement[]} containers - An array of HTMLDivElement representing the containers.
|
|
43
|
+
* @return {ContainerBound[]} An array of objects containing the bounding information for each page element.
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* const containers = document.querySelectorAll('.container');
|
|
47
|
+
* const bounds = getPageElementBound(containers);
|
|
48
|
+
* console.log(bounds);
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
function getPageElementBound(containers) {
|
|
52
|
+
return containers.map((container) => {
|
|
53
|
+
const containerRect = container.getBoundingClientRect();
|
|
54
|
+
const contentlets = Array.from(container.querySelectorAll('[data-dot-object="contentlet"]'));
|
|
55
|
+
return {
|
|
56
|
+
x: containerRect.x,
|
|
57
|
+
y: containerRect.y,
|
|
58
|
+
width: containerRect.width,
|
|
59
|
+
height: containerRect.height,
|
|
60
|
+
payload: JSON.stringify({
|
|
61
|
+
container: getContainerData(container)
|
|
62
|
+
}),
|
|
63
|
+
contentlets: getContentletsBound(containerRect, contentlets)
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Calculates the bounding information for each contentlet inside a container.
|
|
69
|
+
*
|
|
70
|
+
* @export
|
|
71
|
+
* @param {DOMRect} containerRect - The bounding rectangle of the container.
|
|
72
|
+
* @param {HTMLDivElement[]} contentlets - An array of HTMLDivElement representing the contentlets.
|
|
73
|
+
* @return {ContentletBound[]} An array of objects containing the bounding information for each contentlet.
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* const containerRect = container.getBoundingClientRect();
|
|
77
|
+
* const contentlets = container.querySelectorAll('.contentlet');
|
|
78
|
+
* const bounds = getContentletsBound(containerRect, contentlets);
|
|
79
|
+
* console.log(bounds); // Element bounds within the container
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
function getContentletsBound(containerRect, contentlets) {
|
|
83
|
+
return contentlets.map((contentlet) => {
|
|
84
|
+
const contentletRect = contentlet.getBoundingClientRect();
|
|
85
|
+
return {
|
|
86
|
+
x: 0,
|
|
87
|
+
y: contentletRect.y - containerRect.y,
|
|
88
|
+
width: contentletRect.width,
|
|
89
|
+
height: contentletRect.height,
|
|
90
|
+
payload: JSON.stringify({
|
|
91
|
+
container: contentlet.dataset?.['dotContainer']
|
|
92
|
+
? JSON.parse(contentlet.dataset?.['dotContainer'])
|
|
93
|
+
: getClosestContainerData(contentlet),
|
|
94
|
+
contentlet: {
|
|
95
|
+
identifier: contentlet.dataset?.['dotIdentifier'],
|
|
96
|
+
title: contentlet.dataset?.['dotTitle'],
|
|
97
|
+
inode: contentlet.dataset?.['dotInode'],
|
|
98
|
+
contentType: contentlet.dataset?.['dotType']
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get container data from VTLS.
|
|
106
|
+
*
|
|
107
|
+
* @export
|
|
108
|
+
* @param {HTMLElement} container - The container element.
|
|
109
|
+
* @return {object} An object containing the container data.
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* const container = document.querySelector('.container');
|
|
113
|
+
* const data = getContainerData(container);
|
|
114
|
+
* console.log(data);
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
function getContainerData(container) {
|
|
118
|
+
return {
|
|
119
|
+
acceptTypes: container.dataset?.['dotAcceptTypes'] || '',
|
|
120
|
+
identifier: container.dataset?.['dotIdentifier'] || '',
|
|
121
|
+
maxContentlets: container.dataset?.['maxContentlets'] || '',
|
|
122
|
+
uuid: container.dataset?.['dotUuid'] || ''
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get the closest container data from the contentlet.
|
|
127
|
+
*
|
|
128
|
+
* @export
|
|
129
|
+
* @param {Element} element - The contentlet element.
|
|
130
|
+
* @return {object | null} An object containing the closest container data or null if no container is found.
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* const contentlet = document.querySelector('.contentlet');
|
|
134
|
+
* const data = getClosestContainerData(contentlet);
|
|
135
|
+
* console.log(data);
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
function getClosestContainerData(element) {
|
|
139
|
+
// Find the closest ancestor element with data-dot-object="container" attribute
|
|
140
|
+
const container = element.closest('[data-dot-object="container"]');
|
|
141
|
+
// If a container element is found
|
|
142
|
+
if (container) {
|
|
143
|
+
// Return the dataset of the container element
|
|
144
|
+
return getContainerData(container);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// If no container element is found, return null
|
|
148
|
+
console.warn('No container found for the contentlet');
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Find the closest contentlet element based on HTMLElement.
|
|
154
|
+
*
|
|
155
|
+
* @export
|
|
156
|
+
* @param {HTMLElement | null} element - The starting element.
|
|
157
|
+
* @return {HTMLElement | null} The closest contentlet element or null if not found.
|
|
158
|
+
* @example
|
|
159
|
+
* const element = document.querySelector('.some-element');
|
|
160
|
+
* const contentlet = findDotElement(element);
|
|
161
|
+
* console.log(contentlet);
|
|
162
|
+
*/
|
|
163
|
+
function findDotElement(element) {
|
|
164
|
+
if (!element)
|
|
165
|
+
return null;
|
|
166
|
+
if (element?.dataset?.['dotObject'] === 'contentlet' ||
|
|
167
|
+
(element?.dataset?.['dotObject'] === 'container' && element.children.length === 0)) {
|
|
168
|
+
return element;
|
|
169
|
+
}
|
|
170
|
+
return findDotElement(element?.['parentElement']);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Find VTL data within a target element.
|
|
174
|
+
*
|
|
175
|
+
* @export
|
|
176
|
+
* @param {HTMLElement} target - The target element to search within.
|
|
177
|
+
* @return {Array<{ inode: string, name: string }> | null} An array of objects containing VTL data or null if none found.
|
|
178
|
+
* @example
|
|
179
|
+
* ```ts
|
|
180
|
+
* const target = document.querySelector('.target-element');
|
|
181
|
+
* const vtlData = findVTLData(target);
|
|
182
|
+
* console.log(vtlData);
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
function findVTLData(target) {
|
|
186
|
+
const vltElements = target.querySelectorAll('[data-dot-object="vtl-file"]');
|
|
187
|
+
if (!vltElements.length) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
return Array.from(vltElements).map((vltElement) => {
|
|
191
|
+
return {
|
|
192
|
+
inode: vltElement.dataset?.['dotInode'],
|
|
193
|
+
name: vltElement.dataset?.['dotUrl']
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Check if the scroll position is at the bottom of the page.
|
|
199
|
+
*
|
|
200
|
+
* @export
|
|
201
|
+
* @return {boolean} True if the scroll position is at the bottom, otherwise false.
|
|
202
|
+
* @example
|
|
203
|
+
* ```ts
|
|
204
|
+
* if (scrollIsInBottom()) {
|
|
205
|
+
* console.log('Scrolled to the bottom');
|
|
206
|
+
* }
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
function scrollIsInBottom() {
|
|
210
|
+
const documentHeight = document.documentElement.scrollHeight;
|
|
211
|
+
const viewportHeight = window.innerHeight;
|
|
212
|
+
const scrollY = window.scrollY;
|
|
213
|
+
return scrollY + viewportHeight >= documentHeight;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Represents an array of DotCMSPageEditorSubscription objects.
|
|
218
|
+
* Used to store the subscriptions for the editor and unsubscribe later.
|
|
219
|
+
*/
|
|
220
|
+
const subscriptions = [];
|
|
221
|
+
/**
|
|
222
|
+
* Sets the bounds of the containers in the editor.
|
|
223
|
+
* Retrieves the containers from the DOM and sends their position data to the editor.
|
|
224
|
+
* @private
|
|
225
|
+
* @memberof DotCMSPageEditor
|
|
226
|
+
*/
|
|
227
|
+
function setBounds() {
|
|
228
|
+
const containers = Array.from(document.querySelectorAll('[data-dot-object="container"]'));
|
|
229
|
+
const positionData = getPageElementBound(containers);
|
|
230
|
+
postMessageToEditor({
|
|
231
|
+
action: CLIENT_ACTIONS.SET_BOUNDS,
|
|
232
|
+
payload: positionData
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Listens for editor messages and performs corresponding actions based on the received message.
|
|
237
|
+
*
|
|
238
|
+
* @private
|
|
239
|
+
* @memberof DotCMSPageEditor
|
|
240
|
+
*/
|
|
241
|
+
function listenEditorMessages() {
|
|
242
|
+
const messageCallback = (event) => {
|
|
243
|
+
const ACTIONS_NOTIFICATION = {
|
|
244
|
+
[NOTIFY_CLIENT.UVE_RELOAD_PAGE]: () => {
|
|
245
|
+
window.location.reload();
|
|
246
|
+
},
|
|
247
|
+
[NOTIFY_CLIENT.UVE_REQUEST_BOUNDS]: () => {
|
|
248
|
+
setBounds();
|
|
249
|
+
},
|
|
250
|
+
[NOTIFY_CLIENT.UVE_SCROLL_INSIDE_IFRAME]: () => {
|
|
251
|
+
const direction = event.data.direction;
|
|
252
|
+
if ((window.scrollY === 0 && direction === 'up') ||
|
|
253
|
+
(scrollIsInBottom() && direction === 'down')) {
|
|
254
|
+
// If the iframe scroll is at the top or bottom, do not send anything.
|
|
255
|
+
// This avoids losing the scrollend event.
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const scrollY = direction === 'up' ? -120 : 120;
|
|
259
|
+
window.scrollBy({ left: 0, top: scrollY, behavior: 'smooth' });
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
ACTIONS_NOTIFICATION[event.data.name]?.();
|
|
263
|
+
};
|
|
264
|
+
window.addEventListener('message', messageCallback);
|
|
265
|
+
subscriptions.push({
|
|
266
|
+
type: 'listener',
|
|
267
|
+
event: 'message',
|
|
268
|
+
callback: messageCallback
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Listens for pointer move events and extracts information about the hovered contentlet.
|
|
273
|
+
*
|
|
274
|
+
* @private
|
|
275
|
+
* @memberof DotCMSPageEditor
|
|
276
|
+
*/
|
|
277
|
+
function listenHoveredContentlet() {
|
|
278
|
+
const pointerMoveCallback = (event) => {
|
|
279
|
+
const foundElement = findDotElement(event.target);
|
|
280
|
+
if (!foundElement)
|
|
281
|
+
return;
|
|
282
|
+
const { x, y, width, height } = foundElement.getBoundingClientRect();
|
|
283
|
+
const isContainer = foundElement.dataset?.['dotObject'] === 'container';
|
|
284
|
+
const contentletForEmptyContainer = {
|
|
285
|
+
identifier: 'TEMP_EMPTY_CONTENTLET',
|
|
286
|
+
title: 'TEMP_EMPTY_CONTENTLET',
|
|
287
|
+
contentType: 'TEMP_EMPTY_CONTENTLET_TYPE',
|
|
288
|
+
inode: 'TEMPY_EMPTY_CONTENTLET_INODE',
|
|
289
|
+
widgetTitle: 'TEMP_EMPTY_CONTENTLET',
|
|
290
|
+
baseType: 'TEMP_EMPTY_CONTENTLET',
|
|
291
|
+
onNumberOfPages: 1
|
|
292
|
+
};
|
|
293
|
+
const contentlet = {
|
|
294
|
+
identifier: foundElement.dataset?.['dotIdentifier'],
|
|
295
|
+
title: foundElement.dataset?.['dotTitle'],
|
|
296
|
+
inode: foundElement.dataset?.['dotInode'],
|
|
297
|
+
contentType: foundElement.dataset?.['dotType'],
|
|
298
|
+
baseType: foundElement.dataset?.['dotBasetype'],
|
|
299
|
+
widgetTitle: foundElement.dataset?.['dotWidgetTitle'],
|
|
300
|
+
onNumberOfPages: foundElement.dataset?.['dotOnNumberOfPages']
|
|
301
|
+
};
|
|
302
|
+
const vtlFiles = findVTLData(foundElement);
|
|
303
|
+
const contentletPayload = {
|
|
304
|
+
container:
|
|
305
|
+
// Here extract dot-container from contentlet if it is Headless
|
|
306
|
+
// or search in parent container if it is VTL
|
|
307
|
+
foundElement.dataset?.['dotContainer']
|
|
308
|
+
? JSON.parse(foundElement.dataset?.['dotContainer'])
|
|
309
|
+
: getClosestContainerData(foundElement),
|
|
310
|
+
contentlet: isContainer ? contentletForEmptyContainer : contentlet,
|
|
311
|
+
vtlFiles
|
|
312
|
+
};
|
|
313
|
+
postMessageToEditor({
|
|
314
|
+
action: CLIENT_ACTIONS.SET_CONTENTLET,
|
|
315
|
+
payload: {
|
|
316
|
+
x,
|
|
317
|
+
y,
|
|
318
|
+
width,
|
|
319
|
+
height,
|
|
320
|
+
payload: contentletPayload
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
};
|
|
324
|
+
document.addEventListener('pointermove', pointerMoveCallback);
|
|
325
|
+
subscriptions.push({
|
|
326
|
+
type: 'listener',
|
|
327
|
+
event: 'pointermove',
|
|
328
|
+
callback: pointerMoveCallback
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Attaches a scroll event listener to the window
|
|
333
|
+
* and sends a message to the editor when the window is scrolled.
|
|
334
|
+
*
|
|
335
|
+
* @private
|
|
336
|
+
* @memberof DotCMSPageEditor
|
|
337
|
+
*/
|
|
338
|
+
function scrollHandler() {
|
|
339
|
+
const scrollCallback = () => {
|
|
340
|
+
postMessageToEditor({
|
|
341
|
+
action: CLIENT_ACTIONS.IFRAME_SCROLL
|
|
342
|
+
});
|
|
343
|
+
// In case it doesn't have a dotUVE object, we create it with the initial values.
|
|
344
|
+
window.dotUVE = {
|
|
345
|
+
...(window.dotUVE ?? INITIAL_DOT_UVE),
|
|
346
|
+
lastScrollYPosition: window.scrollY
|
|
347
|
+
};
|
|
348
|
+
};
|
|
349
|
+
const scrollEndCallback = () => {
|
|
350
|
+
postMessageToEditor({
|
|
351
|
+
action: CLIENT_ACTIONS.IFRAME_SCROLL_END
|
|
352
|
+
});
|
|
353
|
+
};
|
|
354
|
+
window.addEventListener('scroll', scrollCallback);
|
|
355
|
+
window.addEventListener('scrollend', scrollEndCallback);
|
|
356
|
+
subscriptions.push({
|
|
357
|
+
type: 'listener',
|
|
358
|
+
event: 'scroll',
|
|
359
|
+
callback: scrollEndCallback
|
|
360
|
+
});
|
|
361
|
+
subscriptions.push({
|
|
362
|
+
type: 'listener',
|
|
363
|
+
event: 'scroll',
|
|
364
|
+
callback: scrollCallback
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Sends a message to the editor to get the page data.
|
|
369
|
+
* @param {string} pathname - The pathname of the page.
|
|
370
|
+
* @private
|
|
371
|
+
* @memberof DotCMSPageEditor
|
|
372
|
+
*/
|
|
373
|
+
function fetchPageDataFromInsideUVE(pathname) {
|
|
374
|
+
postMessageToEditor({
|
|
375
|
+
action: CLIENT_ACTIONS.GET_PAGE_DATA,
|
|
376
|
+
payload: {
|
|
377
|
+
pathname
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Updates the navigation in the editor.
|
|
384
|
+
*
|
|
385
|
+
* @param {string} pathname - The pathname to update the navigation with.
|
|
386
|
+
* @memberof DotCMSPageEditor
|
|
387
|
+
* @example
|
|
388
|
+
* updateNavigation('/home'); // Sends a message to the editor to update the navigation to '/home'
|
|
389
|
+
*/
|
|
390
|
+
function updateNavigation(pathname) {
|
|
391
|
+
postMessageToEditor({
|
|
392
|
+
action: CLIENT_ACTIONS.NAVIGATION_UPDATE,
|
|
393
|
+
payload: {
|
|
394
|
+
url: pathname || '/'
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* You can use this function to edit a contentlet in the editor.
|
|
400
|
+
*
|
|
401
|
+
* Calling this function inside the editor, will prompt the UVE to open a dialog to edit the contentlet.
|
|
402
|
+
*
|
|
403
|
+
* @export
|
|
404
|
+
* @template T
|
|
405
|
+
* @param {Contentlet<T>} contentlet - The contentlet to edit.
|
|
406
|
+
*/
|
|
407
|
+
function editContentlet(contentlet) {
|
|
408
|
+
postMessageToEditor({
|
|
409
|
+
action: CLIENT_ACTIONS.EDIT_CONTENTLET,
|
|
410
|
+
payload: contentlet
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Initializes the inline editing in the editor.
|
|
415
|
+
*
|
|
416
|
+
* @export
|
|
417
|
+
* @param {INLINE_EDITING_EVENT_KEY} type
|
|
418
|
+
* @param {InlineEditEventData} eventData
|
|
419
|
+
* @return {*}
|
|
420
|
+
*
|
|
421
|
+
* * @example
|
|
422
|
+
* ```html
|
|
423
|
+
* <div onclick="initInlineEditing('BLOCK_EDITOR', { inode, languageId, contentType, fieldName, content })">
|
|
424
|
+
* ${My Content}
|
|
425
|
+
* </div>
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
428
|
+
function initInlineEditing(type, data) {
|
|
429
|
+
postMessageToEditor({
|
|
430
|
+
action: CLIENT_ACTIONS.INIT_INLINE_EDITING,
|
|
431
|
+
payload: {
|
|
432
|
+
type,
|
|
433
|
+
data
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
/*
|
|
438
|
+
* Reorders the menu based on the provided configuration.
|
|
439
|
+
*
|
|
440
|
+
* @param {ReorderMenuConfig} [config] - Optional configuration for reordering the menu.
|
|
441
|
+
* @param {number} [config.startLevel=1] - The starting level of the menu to reorder.
|
|
442
|
+
* @param {number} [config.depth=2] - The depth of the menu to reorder.
|
|
443
|
+
*
|
|
444
|
+
* This function constructs a URL for the reorder menu page with the specified
|
|
445
|
+
* start level and depth, and sends a message to the editor to perform the reorder action.
|
|
446
|
+
*/
|
|
447
|
+
function reorderMenu(config) {
|
|
448
|
+
const { startLevel = 1, depth = 2 } = config || {};
|
|
449
|
+
postMessageToEditor({
|
|
450
|
+
action: CLIENT_ACTIONS.REORDER_MENU,
|
|
451
|
+
payload: { startLevel, depth }
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* @deprecated Use `getUVEState` function on {@link https://npmjs.com/package/@dotcms/uve|@dotcms/uve} instead, this function will be removed on future versions.
|
|
456
|
+
*
|
|
457
|
+
* Checks if the code is running inside the DotCMS Universal Visual Editor (UVE).
|
|
458
|
+
*
|
|
459
|
+
* The function checks three conditions:
|
|
460
|
+
* 1. If window is defined (for SSR environments)
|
|
461
|
+
* 2. If the page is not in preview mode
|
|
462
|
+
* 3. If the current window is embedded in a parent frame
|
|
463
|
+
*
|
|
464
|
+
* @returns {boolean} Returns true if running inside the UVE editor, false if running standalone or in preview mode
|
|
465
|
+
* @example
|
|
466
|
+
* ```ts
|
|
467
|
+
* // Check if code is running in editor before initializing editor-specific features
|
|
468
|
+
* if (isInsideEditor()) {
|
|
469
|
+
* initEditor(config);
|
|
470
|
+
* } else {
|
|
471
|
+
* initStandaloneMode();
|
|
472
|
+
* }
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
function isInsideEditor() {
|
|
476
|
+
if (typeof window === 'undefined') {
|
|
477
|
+
return false;
|
|
478
|
+
}
|
|
479
|
+
return window.parent !== window;
|
|
480
|
+
}
|
|
481
|
+
function initDotUVE() {
|
|
482
|
+
window.dotUVE = INITIAL_DOT_UVE;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Initializes the DotCMS page editor.
|
|
486
|
+
*
|
|
487
|
+
* @param {DotCMSPageEditorConfig} config - Optional configuration for the editor.
|
|
488
|
+
* @example
|
|
489
|
+
* ```ts
|
|
490
|
+
* const config = { pathname: '/home' };
|
|
491
|
+
* initEditor(config); // Initializes the editor with the provided configuration
|
|
492
|
+
* ```
|
|
493
|
+
*/
|
|
494
|
+
function initEditor(config) {
|
|
495
|
+
initDotUVE();
|
|
496
|
+
fetchPageDataFromInsideUVE(config.pathname);
|
|
497
|
+
listenEditorMessages();
|
|
498
|
+
listenHoveredContentlet();
|
|
499
|
+
scrollHandler();
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Destroys the editor by removing event listeners and disconnecting observers.
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* ```ts
|
|
506
|
+
* destroyEditor(); // Cleans up the editor by removing all event listeners and disconnecting observers
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
509
|
+
function destroyEditor() {
|
|
510
|
+
subscriptions.forEach((subscription) => {
|
|
511
|
+
if (subscription.type === 'listener') {
|
|
512
|
+
window.removeEventListener(subscription.event, subscription.callback);
|
|
513
|
+
}
|
|
514
|
+
if (subscription.type === 'observer') {
|
|
515
|
+
subscription.observer.disconnect();
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const INITIAL_DOT_UVE = {
|
|
521
|
+
editContentlet,
|
|
522
|
+
initInlineEditing,
|
|
523
|
+
reorderMenu,
|
|
524
|
+
lastScrollYPosition: 0
|
|
525
|
+
};
|
|
526
|
+
/**
|
|
527
|
+
* Actions send to the dotcms editor
|
|
528
|
+
*
|
|
529
|
+
* @export
|
|
530
|
+
* @enum {number}
|
|
531
|
+
*/
|
|
532
|
+
var CLIENT_ACTIONS;
|
|
533
|
+
(function (CLIENT_ACTIONS) {
|
|
534
|
+
/**
|
|
535
|
+
* Tell the dotcms editor that page change
|
|
536
|
+
*/
|
|
537
|
+
CLIENT_ACTIONS["NAVIGATION_UPDATE"] = "set-url";
|
|
538
|
+
/**
|
|
539
|
+
* Send the element position of the rows, columnsm containers and contentlets
|
|
540
|
+
*/
|
|
541
|
+
CLIENT_ACTIONS["SET_BOUNDS"] = "set-bounds";
|
|
542
|
+
/**
|
|
543
|
+
* Send the information of the hovered contentlet
|
|
544
|
+
*/
|
|
545
|
+
CLIENT_ACTIONS["SET_CONTENTLET"] = "set-contentlet";
|
|
546
|
+
/**
|
|
547
|
+
* Tell the editor that the page is being scrolled
|
|
548
|
+
*/
|
|
549
|
+
CLIENT_ACTIONS["IFRAME_SCROLL"] = "scroll";
|
|
550
|
+
/**
|
|
551
|
+
* Tell the editor that the page has stopped scrolling
|
|
552
|
+
*/
|
|
553
|
+
CLIENT_ACTIONS["IFRAME_SCROLL_END"] = "scroll-end";
|
|
554
|
+
/**
|
|
555
|
+
* Ping the editor to see if the page is inside the editor
|
|
556
|
+
*/
|
|
557
|
+
CLIENT_ACTIONS["PING_EDITOR"] = "ping-editor";
|
|
558
|
+
/**
|
|
559
|
+
* Tell the editor to init the inline editing editor.
|
|
560
|
+
*/
|
|
561
|
+
CLIENT_ACTIONS["INIT_INLINE_EDITING"] = "init-inline-editing";
|
|
562
|
+
/**
|
|
563
|
+
* Tell the editor to open the Copy-contentlet dialog
|
|
564
|
+
* To copy a content and then edit it inline.
|
|
565
|
+
*/
|
|
566
|
+
CLIENT_ACTIONS["COPY_CONTENTLET_INLINE_EDITING"] = "copy-contentlet-inline-editing";
|
|
567
|
+
/**
|
|
568
|
+
* Tell the editor to save inline edited contentlet
|
|
569
|
+
*/
|
|
570
|
+
CLIENT_ACTIONS["UPDATE_CONTENTLET_INLINE_EDITING"] = "update-contentlet-inline-editing";
|
|
571
|
+
/**
|
|
572
|
+
* Tell the editor to trigger a menu reorder
|
|
573
|
+
*/
|
|
574
|
+
CLIENT_ACTIONS["REORDER_MENU"] = "reorder-menu";
|
|
575
|
+
/**
|
|
576
|
+
* Tell the editor to send the page info to iframe
|
|
577
|
+
*/
|
|
578
|
+
CLIENT_ACTIONS["GET_PAGE_DATA"] = "get-page-data";
|
|
579
|
+
/**
|
|
580
|
+
* Tell the editor an user send a graphql query
|
|
581
|
+
*/
|
|
582
|
+
CLIENT_ACTIONS["CLIENT_READY"] = "client-ready";
|
|
583
|
+
/**
|
|
584
|
+
* Tell the editor to edit a contentlet
|
|
585
|
+
*/
|
|
586
|
+
CLIENT_ACTIONS["EDIT_CONTENTLET"] = "edit-contentlet";
|
|
587
|
+
/**
|
|
588
|
+
* Tell the editor to do nothing
|
|
589
|
+
*/
|
|
590
|
+
CLIENT_ACTIONS["NOOP"] = "noop";
|
|
591
|
+
})(CLIENT_ACTIONS || (CLIENT_ACTIONS = {}));
|
|
592
|
+
/**
|
|
593
|
+
* Post message to dotcms page editor
|
|
594
|
+
*
|
|
595
|
+
* @export
|
|
596
|
+
* @template T
|
|
597
|
+
* @param {PostMessageProps<T>} message
|
|
598
|
+
*/
|
|
599
|
+
function postMessageToEditor(message) {
|
|
600
|
+
window.parent.postMessage(message, '*');
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
var _DotCmsClient_config, _DotCmsClient_requestOptions, _DotCmsClient_listeners;
|
|
604
|
+
function getHostURL(url) {
|
|
605
|
+
try {
|
|
606
|
+
return new URL(url);
|
|
607
|
+
}
|
|
608
|
+
catch (error) {
|
|
609
|
+
return undefined;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* `DotCmsClient` is a TypeScript class that provides methods to interact with the DotCMS REST API.
|
|
614
|
+
* DotCMS is a hybrid-headless CMS and digital experience platform.
|
|
615
|
+
*
|
|
616
|
+
* @class DotCmsClient
|
|
617
|
+
* @property {ClientConfig} config - The configuration object for the DotCMS client.
|
|
618
|
+
* @property {Content} content - Provides methods to interact with content in DotCMS.
|
|
619
|
+
*
|
|
620
|
+
* @method constructor(config: ClientConfig) - Constructs a new instance of the DotCmsClient class.
|
|
621
|
+
*
|
|
622
|
+
* @method page.get(options: PageApiOptions): Promise<PageApiResponse> - Retrieves all the elements of any Page in your dotCMS system in JSON format.
|
|
623
|
+
* The Page API enables you to retrieve page information, layout, template, content blocks, and more.
|
|
624
|
+
* @see {@link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas}
|
|
625
|
+
*
|
|
626
|
+
* @method nav.get(options: NavApiOptions = { depth: 0, path: '/', languageId: 1 }): Promise<NavApiResponse> - Retrieves information about the dotCMS file and folder tree.
|
|
627
|
+
* The Navigation API allows you to fetch the site structure and menu items.
|
|
628
|
+
* @see {@link https://www.dotcms.com/docs/latest/navigation-rest-api}
|
|
629
|
+
*
|
|
630
|
+
* @method content.get(options: ContentApiOptions): Promise<ContentApiResponse> - Retrieves content items based on specified criteria.
|
|
631
|
+
* The Content API allows you to query and retrieve content by ID, inode, or using Lucene queries.
|
|
632
|
+
* @see {@link https://www.dotcms.com/docs/latest/content-api-retrieval-and-querying}
|
|
633
|
+
*
|
|
634
|
+
* @method editor.on(action: string, callbackFn: (payload: unknown) => void) - Allows you to react to actions issued by the Universal Visual Editor (UVE).
|
|
635
|
+
* @method editor.off(action: string) - Stops listening to an action issued by UVE.
|
|
636
|
+
*
|
|
637
|
+
* @static
|
|
638
|
+
* @method init(config: ClientConfig): DotCmsClient - Initializes and returns a DotCmsClient instance.
|
|
639
|
+
* @method dotcmsUrl: string - Retrieves the DotCMS URL from the instance configuration.
|
|
640
|
+
*
|
|
641
|
+
* @example <caption>Basic usage</caption>
|
|
642
|
+
* ```javascript
|
|
643
|
+
* const client = DotCmsClient.init({ dotcmsUrl: 'https://demo.dotcms.com', authToken: 'your-auth-token' });
|
|
644
|
+
*
|
|
645
|
+
* // Get a page
|
|
646
|
+
* client.page.get({ path: '/about-us' }).then(response => console.log(response));
|
|
647
|
+
*
|
|
648
|
+
* // Get navigation
|
|
649
|
+
* client.nav.get({ path: '/about-us', depth: 2 }).then(response => console.log(response));
|
|
650
|
+
*
|
|
651
|
+
* // Get content
|
|
652
|
+
* client.content.get({ query: '+contentType:Blog +languageId:1', limit: 10 }).then(response => console.log(response));
|
|
653
|
+
*
|
|
654
|
+
* // Listen to editor changes
|
|
655
|
+
* client.editor.on('changes', (payload) => console.log('Changes detected:', payload));
|
|
656
|
+
* ```
|
|
657
|
+
*/
|
|
658
|
+
class DotCmsClient {
|
|
659
|
+
constructor(config = { dotcmsUrl: '', authToken: '', requestOptions: {}, siteId: '' }) {
|
|
660
|
+
_DotCmsClient_config.set(this, void 0);
|
|
661
|
+
_DotCmsClient_requestOptions.set(this, void 0);
|
|
662
|
+
_DotCmsClient_listeners.set(this, []);
|
|
663
|
+
this.page = {
|
|
664
|
+
/**
|
|
665
|
+
* `page.get` is an asynchronous method of the `DotCmsClient` class that retrieves all the elements of any Page in your dotCMS system in JSON format.
|
|
666
|
+
* It takes a `PageApiOptions` object as a parameter and returns a Promise that resolves to the response from the DotCMS API.
|
|
667
|
+
*
|
|
668
|
+
* The Page API enables you to retrieve all the elements of any Page in your dotCMS system.
|
|
669
|
+
* The elements may be retrieved in JSON format.
|
|
670
|
+
*
|
|
671
|
+
* @link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas
|
|
672
|
+
* @async
|
|
673
|
+
* @param {PageApiOptions} options - The options for the Page API call.
|
|
674
|
+
* @returns {Promise<unknown>} - A Promise that resolves to the response from the DotCMS API.
|
|
675
|
+
* @throws {Error} - Throws an error if the options are not valid.
|
|
676
|
+
* @example
|
|
677
|
+
* ```ts
|
|
678
|
+
* const client = new DotCmsClient({ dotcmsUrl: 'https://your.dotcms.com', authToken: 'your-auth-token', siteId: 'your-site-id' });
|
|
679
|
+
* client.page.get({ path: '/about-us' }).then(response => console.log(response));
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
682
|
+
get: async (options) => {
|
|
683
|
+
this.validatePageOptions(options);
|
|
684
|
+
const queryParamsObj = {};
|
|
685
|
+
for (const [key, value] of Object.entries(options)) {
|
|
686
|
+
if (value === undefined || key === 'path' || key === 'siteId')
|
|
687
|
+
continue;
|
|
688
|
+
if (key === 'personaId') {
|
|
689
|
+
queryParamsObj['com.dotmarketing.persona.id'] = String(value);
|
|
690
|
+
}
|
|
691
|
+
else if (key === 'mode' && value) {
|
|
692
|
+
queryParamsObj['mode'] = String(value);
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
queryParamsObj[key] = String(value);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
const queryHostId = options.siteId ?? __classPrivateFieldGet(this, _DotCmsClient_config, "f").siteId ?? '';
|
|
699
|
+
if (queryHostId) {
|
|
700
|
+
queryParamsObj['host_id'] = queryHostId;
|
|
701
|
+
}
|
|
702
|
+
const queryParams = new URLSearchParams(queryParamsObj).toString();
|
|
703
|
+
const formattedPath = options.path.startsWith('/') ? options.path : `/${options.path}`;
|
|
704
|
+
const url = `${__classPrivateFieldGet(this, _DotCmsClient_config, "f").dotcmsUrl}/api/v1/page/json${formattedPath}${queryParams ? `?${queryParams}` : ''}`;
|
|
705
|
+
const response = await fetch(url, __classPrivateFieldGet(this, _DotCmsClient_requestOptions, "f"));
|
|
706
|
+
if (!response.ok) {
|
|
707
|
+
const error = {
|
|
708
|
+
status: response.status,
|
|
709
|
+
message: ErrorMessages[response.status] || response.statusText
|
|
710
|
+
};
|
|
711
|
+
console.error(error);
|
|
712
|
+
throw error;
|
|
713
|
+
}
|
|
714
|
+
return response.json().then((data) => data.entity);
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
this.editor = {
|
|
718
|
+
/**
|
|
719
|
+
* `editor.on` is an asynchronous method of the `DotCmsClient` class that allows you to react to actions issued by the UVE.
|
|
720
|
+
*
|
|
721
|
+
* NOTE: This is being used by the development team - This logic is probably varied or moved to another function/object.
|
|
722
|
+
* @param {string} action - The name of the action emitted by UVE.
|
|
723
|
+
* @param {function} callbackFn - The function to execute when the UVE emits the action.
|
|
724
|
+
* @example
|
|
725
|
+
* ```ts
|
|
726
|
+
* client.editor.on('changes', (payload) => {
|
|
727
|
+
* console.log('Changes detected:', payload);
|
|
728
|
+
* });
|
|
729
|
+
* ```
|
|
730
|
+
*/
|
|
731
|
+
on: (action, callbackFn) => {
|
|
732
|
+
if (!isInsideEditor()) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
if (action === 'changes') {
|
|
736
|
+
const messageCallback = (event) => {
|
|
737
|
+
if (event.data.name === NOTIFY_CLIENT.UVE_SET_PAGE_DATA) {
|
|
738
|
+
callbackFn(event.data.payload);
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
window.addEventListener('message', messageCallback);
|
|
742
|
+
__classPrivateFieldGet(this, _DotCmsClient_listeners, "f").push({ event: 'message', callback: messageCallback, action });
|
|
743
|
+
}
|
|
744
|
+
},
|
|
745
|
+
/**
|
|
746
|
+
* `editor.off` is a synchronous method of the `DotCmsClient` class that allows you to stop listening and reacting to an action issued by UVE.
|
|
747
|
+
*
|
|
748
|
+
* NOTE: This is being used by the development team - This logic is probably varied or moved to another function/object.
|
|
749
|
+
* @param {string} action - The name of the action to stop listening to.
|
|
750
|
+
* @example
|
|
751
|
+
* ```ts
|
|
752
|
+
* client.editor.off('changes');
|
|
753
|
+
* ```
|
|
754
|
+
*/
|
|
755
|
+
off: (action) => {
|
|
756
|
+
const listenerIndex = __classPrivateFieldGet(this, _DotCmsClient_listeners, "f").findIndex((listener) => listener.action === action);
|
|
757
|
+
if (listenerIndex !== -1) {
|
|
758
|
+
const listener = __classPrivateFieldGet(this, _DotCmsClient_listeners, "f")[listenerIndex];
|
|
759
|
+
window.removeEventListener(listener.event, listener.callback);
|
|
760
|
+
__classPrivateFieldGet(this, _DotCmsClient_listeners, "f").splice(listenerIndex, 1);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
this.nav = {
|
|
765
|
+
/**
|
|
766
|
+
* `nav.get` is an asynchronous method of the `DotCmsClient` class that retrieves information about the dotCMS file and folder tree.
|
|
767
|
+
* It takes a `NavApiOptions` object as a parameter (with default values) and returns a Promise that resolves to the response from the DotCMS API.
|
|
768
|
+
*
|
|
769
|
+
* The navigation REST API enables you to retrieve information about the dotCMS file and folder tree through REST API calls.
|
|
770
|
+
* @link https://www.dotcms.com/docs/latest/navigation-rest-api
|
|
771
|
+
* @async
|
|
772
|
+
* @param {NavApiOptions} options - The options for the Nav API call. Defaults to `{ depth: 0, path: '/', languageId: 1 }`.
|
|
773
|
+
* @returns {Promise<unknown>} - A Promise that resolves to the response from the DotCMS API.
|
|
774
|
+
* @throws {Error} - Throws an error if the options are not valid.
|
|
775
|
+
* @example
|
|
776
|
+
* ```ts
|
|
777
|
+
* const client = new DotCmsClient({ dotcmsUrl: 'https://your.dotcms.com', authToken: 'your-auth-token', siteId: 'your-site-id' }});
|
|
778
|
+
* client.nav.get({ path: '/about-us', depth: 2 }).then(response => console.log(response));
|
|
779
|
+
* ```
|
|
780
|
+
*/
|
|
781
|
+
get: async (options = { depth: 0, path: '/', languageId: 1 }) => {
|
|
782
|
+
this.validateNavOptions(options);
|
|
783
|
+
// Extract the 'path' from the options and prepare the rest as query parameters
|
|
784
|
+
const { path, ...queryParamsOptions } = options;
|
|
785
|
+
const queryParamsObj = {};
|
|
786
|
+
Object.entries(queryParamsOptions).forEach(([key, value]) => {
|
|
787
|
+
if (value !== undefined) {
|
|
788
|
+
queryParamsObj[key] = String(value);
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
const queryParams = new URLSearchParams(queryParamsObj).toString();
|
|
792
|
+
// Format the URL correctly depending on the 'path' value
|
|
793
|
+
const formattedPath = path === '/' ? '/' : `/${path}`;
|
|
794
|
+
const url = `${__classPrivateFieldGet(this, _DotCmsClient_config, "f").dotcmsUrl}/api/v1/nav${formattedPath}${queryParams ? `?${queryParams}` : ''}`;
|
|
795
|
+
const response = await fetch(url, __classPrivateFieldGet(this, _DotCmsClient_requestOptions, "f"));
|
|
796
|
+
return response.json();
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
if (!config.dotcmsUrl) {
|
|
800
|
+
throw new Error("Invalid configuration - 'dotcmsUrl' is required");
|
|
801
|
+
}
|
|
802
|
+
this.dotcmsUrl = getHostURL(config.dotcmsUrl)?.origin;
|
|
803
|
+
if (!this.dotcmsUrl) {
|
|
804
|
+
throw new Error("Invalid configuration - 'dotcmsUrl' must be a valid URL");
|
|
805
|
+
}
|
|
806
|
+
if (!config.authToken) {
|
|
807
|
+
throw new Error("Invalid configuration - 'authToken' is required");
|
|
808
|
+
}
|
|
809
|
+
__classPrivateFieldSet(this, _DotCmsClient_config, {
|
|
810
|
+
...config,
|
|
811
|
+
dotcmsUrl: this.dotcmsUrl
|
|
812
|
+
}, "f");
|
|
813
|
+
__classPrivateFieldSet(this, _DotCmsClient_requestOptions, {
|
|
814
|
+
...__classPrivateFieldGet(this, _DotCmsClient_config, "f").requestOptions,
|
|
815
|
+
headers: {
|
|
816
|
+
Authorization: `Bearer ${__classPrivateFieldGet(this, _DotCmsClient_config, "f").authToken}`,
|
|
817
|
+
...__classPrivateFieldGet(this, _DotCmsClient_config, "f").requestOptions?.headers
|
|
818
|
+
}
|
|
819
|
+
}, "f");
|
|
820
|
+
this.content = new Content(__classPrivateFieldGet(this, _DotCmsClient_requestOptions, "f"), __classPrivateFieldGet(this, _DotCmsClient_config, "f").dotcmsUrl);
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Initializes the DotCmsClient instance with the provided configuration.
|
|
824
|
+
* If an instance already exists, it returns the existing instance.
|
|
825
|
+
*
|
|
826
|
+
* @param {ClientConfig} config - The configuration object for the DotCMS client.
|
|
827
|
+
* @returns {DotCmsClient} - The initialized DotCmsClient instance.
|
|
828
|
+
* @example
|
|
829
|
+
* ```ts
|
|
830
|
+
* const client = DotCmsClient.init({ dotcmsUrl: 'https://demo.dotcms.com', authToken: 'your-auth-token' });
|
|
831
|
+
* ```
|
|
832
|
+
*/
|
|
833
|
+
static init(config) {
|
|
834
|
+
if (this.instance) {
|
|
835
|
+
console.warn('DotCmsClient has already been initialized. Please use the instance to interact with the DotCMS API.');
|
|
836
|
+
}
|
|
837
|
+
return this.instance ?? (this.instance = new DotCmsClient(config));
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Retrieves the DotCMS URL from the instance configuration.
|
|
841
|
+
*
|
|
842
|
+
* @returns {string} - The DotCMS URL.
|
|
843
|
+
*/
|
|
844
|
+
static get dotcmsUrl() {
|
|
845
|
+
return (this.instance && __classPrivateFieldGet(this.instance, _DotCmsClient_config, "f").dotcmsUrl) || '';
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Throws an error if the path is not valid.
|
|
849
|
+
*
|
|
850
|
+
* @returns {string} - The authentication token.
|
|
851
|
+
*/
|
|
852
|
+
validatePageOptions(options) {
|
|
853
|
+
if (!options.path) {
|
|
854
|
+
throw new Error("The 'path' parameter is required for the Page API");
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* Throws an error if the path is not valid.
|
|
859
|
+
*
|
|
860
|
+
* @returns {string} - The authentication token.
|
|
861
|
+
*/
|
|
862
|
+
validateNavOptions(options) {
|
|
863
|
+
if (!options.path) {
|
|
864
|
+
throw new Error("The 'path' parameter is required for the Nav API");
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
_DotCmsClient_config = new WeakMap(), _DotCmsClient_requestOptions = new WeakMap(), _DotCmsClient_listeners = new WeakMap();
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* Generates the page request parameters to be used in the API call.
|
|
872
|
+
*
|
|
873
|
+
* @param {PageRequestParamsProps} PageRequestParamsProps - The properties for the page request.
|
|
874
|
+
* @returns {PageApiOptions} The options for the page API.
|
|
875
|
+
* @example
|
|
876
|
+
* ```ts
|
|
877
|
+
* const pageApiOptions = getPageRequestParams({ path: '/api/v1/page', params: queryParams });
|
|
878
|
+
* ```
|
|
879
|
+
*/
|
|
880
|
+
const getPageRequestParams = ({ path = '', params = {} }) => {
|
|
881
|
+
const copiedParams = params instanceof URLSearchParams ? Object.fromEntries(params.entries()) : { ...params };
|
|
882
|
+
const finalParams = {};
|
|
883
|
+
const dotMarketingPersonaId = copiedParams['com.dotmarketing.persona.id'] || '';
|
|
884
|
+
finalParams['mode'] = copiedParams['mode'] || 'LIVE';
|
|
885
|
+
if (copiedParams['language_id']) {
|
|
886
|
+
finalParams['language_id'] = copiedParams['language_id'];
|
|
887
|
+
}
|
|
888
|
+
if (copiedParams['variantName']) {
|
|
889
|
+
finalParams['variantName'] = copiedParams['variantName'];
|
|
890
|
+
}
|
|
891
|
+
if (copiedParams['personaId'] || dotMarketingPersonaId) {
|
|
892
|
+
finalParams['personaId'] = copiedParams['personaId'] || dotMarketingPersonaId;
|
|
893
|
+
}
|
|
894
|
+
if (copiedParams['publishDate']) {
|
|
895
|
+
finalParams['publishDate'] = copiedParams['publishDate'];
|
|
896
|
+
}
|
|
897
|
+
return {
|
|
898
|
+
path,
|
|
899
|
+
...finalParams
|
|
900
|
+
};
|
|
901
|
+
};
|
|
902
|
+
|
|
903
|
+
export { CLIENT_ACTIONS, DotCmsClient, NOTIFY_CLIENT, destroyEditor, editContentlet, getPageRequestParams, initEditor, initInlineEditing, isInsideEditor, postMessageToEditor, reorderMenu, updateNavigation };
|