@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.
Files changed (74) hide show
  1. package/README.md +166 -19
  2. package/index.cjs.d.ts +1 -0
  3. package/index.cjs.default.js +1 -0
  4. package/index.cjs.js +914 -0
  5. package/index.cjs.mjs +2 -0
  6. package/index.esm.d.ts +1 -0
  7. package/index.esm.js +903 -0
  8. package/next.cjs.d.ts +1 -0
  9. package/next.cjs.default.js +1 -0
  10. package/next.cjs.js +553 -0
  11. package/next.cjs.mjs +2 -0
  12. package/next.esm.d.ts +1 -0
  13. package/next.esm.js +551 -0
  14. package/package.json +59 -23
  15. package/src/index.d.ts +8 -0
  16. package/src/lib/client/client.d.ts +84 -0
  17. package/src/lib/client/content/builders/collection/collection.d.ts +226 -0
  18. package/src/lib/client/content/builders/query/lucene-syntax/Equals.d.ts +114 -0
  19. package/src/lib/client/content/builders/query/lucene-syntax/Field.d.ts +32 -0
  20. package/src/lib/client/content/builders/query/lucene-syntax/NotOperand.d.ts +26 -0
  21. package/src/lib/client/content/builders/query/lucene-syntax/Operand.d.ts +44 -0
  22. package/src/lib/client/content/builders/query/lucene-syntax/index.d.ts +4 -0
  23. package/src/lib/client/content/builders/query/query.d.ts +76 -0
  24. package/src/lib/client/content/builders/query/utils/index.d.ts +142 -0
  25. package/src/lib/client/content/content-api.d.ts +129 -0
  26. package/src/lib/client/content/shared/const.d.ts +13 -0
  27. package/src/lib/client/content/shared/types.d.ts +138 -0
  28. package/src/lib/client/content/shared/utils.d.ts +20 -0
  29. package/src/lib/client/models/index.d.ts +12 -0
  30. package/src/lib/client/models/types.d.ts +516 -0
  31. package/src/lib/client/navigation/navigation-api.d.ts +31 -0
  32. package/src/lib/client/page/page-api.d.ts +165 -0
  33. package/src/lib/client/page/utils.d.ts +41 -0
  34. package/src/lib/deprecated/editor/listeners/listeners.d.ts +45 -0
  35. package/src/lib/deprecated/editor/models/client.model.d.ts +111 -0
  36. package/src/lib/deprecated/editor/models/editor.model.d.ts +62 -0
  37. package/src/lib/deprecated/editor/models/inline-event.model.d.ts +9 -0
  38. package/src/lib/{editor/models/listeners.model.ts → deprecated/editor/models/listeners.model.d.ts} +17 -8
  39. package/src/lib/deprecated/editor/sdk-editor-vtl.d.ts +1 -0
  40. package/src/lib/deprecated/editor/sdk-editor.d.ts +92 -0
  41. package/src/lib/deprecated/editor/utils/editor.utils.d.ts +159 -0
  42. package/src/lib/deprecated/editor/utils/traditional-vtl.utils.d.ts +4 -0
  43. package/src/lib/deprecated/sdk-js-client.d.ts +276 -0
  44. package/src/lib/utils/graphql/transforms.d.ts +24 -0
  45. package/src/lib/utils/index.d.ts +2 -0
  46. package/src/lib/utils/page/common-utils.d.ts +33 -0
  47. package/src/next.d.ts +1 -0
  48. package/src/types.d.ts +2 -0
  49. package/transforms.cjs.js +1145 -0
  50. package/transforms.esm.js +1139 -0
  51. package/types.cjs.d.ts +1 -0
  52. package/types.cjs.default.js +1 -0
  53. package/types.cjs.js +2 -0
  54. package/types.cjs.mjs +2 -0
  55. package/types.esm.d.ts +1 -0
  56. package/types.esm.js +1 -0
  57. package/.eslintrc.json +0 -18
  58. package/jest.config.ts +0 -15
  59. package/project.json +0 -63
  60. package/src/index.ts +0 -4
  61. package/src/lib/client/sdk-js-client.spec.ts +0 -258
  62. package/src/lib/client/sdk-js-client.ts +0 -297
  63. package/src/lib/editor/listeners/listeners.spec.ts +0 -55
  64. package/src/lib/editor/listeners/listeners.ts +0 -200
  65. package/src/lib/editor/models/client.model.ts +0 -55
  66. package/src/lib/editor/models/editor.model.ts +0 -17
  67. package/src/lib/editor/sdk-editor-vtl.ts +0 -24
  68. package/src/lib/editor/sdk-editor.spec.ts +0 -95
  69. package/src/lib/editor/sdk-editor.ts +0 -70
  70. package/src/lib/editor/utils/editor.utils.spec.ts +0 -164
  71. package/src/lib/editor/utils/editor.utils.ts +0 -151
  72. package/tsconfig.json +0 -22
  73. package/tsconfig.lib.json +0 -10
  74. 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 };