@dotcms/client 0.0.1-beta.3 → 0.0.1-beta.30

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 (41) hide show
  1. package/README.md +183 -36
  2. package/index.cjs.js +102 -1238
  3. package/index.esm.js +86 -1221
  4. package/next.cjs.d.ts +1 -0
  5. package/next.cjs.default.js +1 -0
  6. package/next.cjs.js +526 -0
  7. package/next.cjs.mjs +2 -0
  8. package/next.esm.d.ts +1 -0
  9. package/next.esm.js +524 -0
  10. package/package.json +26 -7
  11. package/src/index.d.ts +6 -6
  12. package/src/lib/client/client.d.ts +56 -0
  13. package/src/lib/client/content/builders/collection/collection.d.ts +1 -1
  14. package/src/lib/client/content/content-api.d.ts +3 -3
  15. package/src/lib/client/content/shared/types.d.ts +3 -44
  16. package/src/lib/client/navigation/navigation-api.d.ts +14 -0
  17. package/src/lib/client/page/page-api.d.ts +96 -0
  18. package/src/lib/client/page/utils.d.ts +41 -0
  19. package/src/lib/{editor → deprecated/editor}/models/client.model.d.ts +13 -0
  20. package/src/lib/{editor → deprecated/editor}/sdk-editor.d.ts +1 -1
  21. package/src/lib/{client → deprecated}/sdk-js-client.d.ts +1 -1
  22. package/src/lib/utils/graphql/transforms.d.ts +2 -13
  23. package/src/lib/utils/page/common-utils.d.ts +1 -1
  24. package/src/next.d.ts +1 -0
  25. package/transforms.cjs.js +1150 -0
  26. package/transforms.esm.js +1144 -0
  27. package/src/lib/client/models/types.d.ts +0 -13
  28. /package/src/lib/{query-builder → client/content/builders/query}/lucene-syntax/Equals.d.ts +0 -0
  29. /package/src/lib/{query-builder → client/content/builders/query}/lucene-syntax/Field.d.ts +0 -0
  30. /package/src/lib/{query-builder → client/content/builders/query}/lucene-syntax/NotOperand.d.ts +0 -0
  31. /package/src/lib/{query-builder → client/content/builders/query}/lucene-syntax/Operand.d.ts +0 -0
  32. /package/src/lib/{query-builder → client/content/builders/query}/lucene-syntax/index.d.ts +0 -0
  33. /package/src/lib/{query-builder/sdk-query-builder.d.ts → client/content/builders/query/query.d.ts} +0 -0
  34. /package/src/lib/{query-builder → client/content/builders/query}/utils/index.d.ts +0 -0
  35. /package/src/lib/{editor → deprecated/editor}/listeners/listeners.d.ts +0 -0
  36. /package/src/lib/{editor → deprecated/editor}/models/editor.model.d.ts +0 -0
  37. /package/src/lib/{editor → deprecated/editor}/models/inline-event.model.d.ts +0 -0
  38. /package/src/lib/{editor → deprecated/editor}/models/listeners.model.d.ts +0 -0
  39. /package/src/lib/{editor → deprecated/editor}/sdk-editor-vtl.d.ts +0 -0
  40. /package/src/lib/{editor → deprecated/editor}/utils/editor.utils.d.ts +0 -0
  41. /package/src/lib/{editor → deprecated/editor}/utils/traditional-vtl.utils.d.ts +0 -0
package/next.cjs.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/next";
@@ -0,0 +1 @@
1
+ exports._default = require('./next.cjs.js').default;
package/next.cjs.js ADDED
@@ -0,0 +1,526 @@
1
+ 'use strict';
2
+
3
+ var transforms = require('./transforms.cjs.js');
4
+
5
+ class NavigationClient {
6
+ constructor(config, requestOptions) {
7
+ this.requestOptions = requestOptions;
8
+ this.BASE_URL = `${config?.dotcmsUrl}/api/v1/nav`;
9
+ }
10
+ /**
11
+ * Retrieves information about the dotCMS file and folder tree.
12
+ * @param {NavigationApiOptions} options - The options for the Navigation API call. Defaults to `{ depth: 0, path: '/', languageId: 1 }`.
13
+ * @returns {Promise<unknown>} - A Promise that resolves to the response from the DotCMS API.
14
+ * @throws {Error} - Throws an error if the options are not valid.
15
+ */
16
+ async get(path, params) {
17
+ if (!path) {
18
+ throw new Error("The 'path' parameter is required for the Navigation API");
19
+ }
20
+ const navParams = params ? this.mapToBackendParams(params) : {};
21
+ const urlParams = new URLSearchParams(navParams).toString();
22
+ const parsedPath = path.replace(/^\/+/, '/').replace(/\/+$/, '/');
23
+ const url = `${this.BASE_URL}${parsedPath}${urlParams ? `?${urlParams}` : ''}`;
24
+ const response = await fetch(url, this.requestOptions);
25
+ if (!response.ok) {
26
+ throw new Error(`Failed to fetch navigation data: ${response.statusText} - ${response.status}`);
27
+ }
28
+ return response.json().then((data) => data.entity);
29
+ }
30
+ mapToBackendParams(params) {
31
+ const backendParams = {};
32
+ if (params.depth) {
33
+ backendParams['depth'] = String(params.depth);
34
+ }
35
+ if (params.languageId) {
36
+ backendParams['language_id'] = String(params.languageId);
37
+ }
38
+ return backendParams;
39
+ }
40
+ }
41
+
42
+ const DEFAULT_PAGE_CONTENTLETS_CONTENT = `
43
+ publishDate
44
+ inode
45
+ identifier
46
+ archived
47
+ urlMap
48
+ urlMap
49
+ locked
50
+ contentType
51
+ creationDate
52
+ modDate
53
+ title
54
+ baseType
55
+ working
56
+ live
57
+ publishUser {
58
+ firstName
59
+ lastName
60
+ }
61
+ owner {
62
+ lastName
63
+ }
64
+ conLanguage {
65
+ language
66
+ languageCode
67
+ }
68
+ modUser {
69
+ firstName
70
+ lastName
71
+ }
72
+ `;
73
+ /**
74
+ * Builds a GraphQL query for retrieving page content from DotCMS.
75
+ *
76
+ * @param {string} pageQuery - Custom fragment fields to include in the ClientPage fragment
77
+ * @param {string} additionalQueries - Additional GraphQL queries to include in the main query
78
+ * @returns {string} Complete GraphQL query string for page content
79
+ */
80
+ const buildPageQuery = ({ page, fragments, additionalQueries }) => {
81
+ if (!page) {
82
+ console.warn('No page query provided. The query will be used by fetching all content with _map. This may mean poor performance in the query. We suggest you provide a detailed query on page attribute.');
83
+ }
84
+ return `
85
+ fragment DotCMSPage on DotPage {
86
+ publishDate
87
+ type
88
+ httpsRequired
89
+ inode
90
+ path
91
+ identifier
92
+ hasTitleImage
93
+ sortOrder
94
+ extension
95
+ canRead
96
+ pageURI
97
+ canEdit
98
+ archived
99
+ friendlyName
100
+ workingInode
101
+ url
102
+ pageURI
103
+ hasLiveVersion
104
+ deleted
105
+ pageUrl
106
+ shortyWorking
107
+ mimeType
108
+ locked
109
+ stInode
110
+ contentType
111
+ creationDate
112
+ liveInode
113
+ name
114
+ shortyLive
115
+ modDate
116
+ title
117
+ baseType
118
+ working
119
+ canLock
120
+ live
121
+ isContentlet
122
+ statusIcons
123
+ canEdit
124
+ canLock
125
+ canRead
126
+ canEdit
127
+ canLock
128
+ canRead
129
+ urlContentMap {
130
+ _map
131
+ }
132
+ conLanguage {
133
+ id
134
+ language
135
+ languageCode
136
+ }
137
+ template {
138
+ drawed
139
+ }
140
+ containers {
141
+ path
142
+ identifier
143
+ maxContentlets
144
+ containerStructures {
145
+ id
146
+ code
147
+ structureId
148
+ containerId
149
+ contentTypeVar
150
+ containerInode
151
+ }
152
+ containerContentlets {
153
+ uuid
154
+ contentlets {
155
+ ${page ? DEFAULT_PAGE_CONTENTLETS_CONTENT : '_map'}
156
+ }
157
+ }
158
+ }
159
+ layout {
160
+ header
161
+ footer
162
+ body {
163
+ rows {
164
+ columns {
165
+ leftOffset
166
+ styleClass
167
+ width
168
+ left
169
+ containers {
170
+ identifier
171
+ uuid
172
+ }
173
+ }
174
+ }
175
+ }
176
+ }
177
+ viewAs {
178
+ visitor {
179
+ persona {
180
+ modDate
181
+ inode
182
+ name
183
+ identifier
184
+ keyTag
185
+ photo {
186
+ versionPath
187
+ }
188
+ }
189
+ }
190
+ persona {
191
+ modDate
192
+ inode
193
+ name
194
+ identifier
195
+ keyTag
196
+ photo {
197
+ versionPath
198
+ }
199
+ }
200
+ language {
201
+ id
202
+ languageCode
203
+ countryCode
204
+ language
205
+ country
206
+ }
207
+ }
208
+ }
209
+
210
+ ${page ? ` fragment ClientPage on DotPage { ${page} } ` : ''}
211
+
212
+ ${fragments ? fragments.join('\n\n') : ''}
213
+
214
+ query PageContent($url: String!, $languageId: String, $mode: String, $personaId: String, $fireRules: Boolean, $publishDate: String, $siteId: String) {
215
+ page: page(url: $url, languageId: $languageId, pageMode: $mode, persona: $personaId, fireRules: $fireRules, publishDate: $publishDate, site: $siteId) {
216
+ ...DotCMSPage
217
+ ${page ? '...ClientPage' : ''}
218
+ }
219
+
220
+ ${additionalQueries}
221
+ }
222
+ `;
223
+ };
224
+ /**
225
+ * Converts a record of query strings into a single GraphQL query string.
226
+ *
227
+ * @param {Record<string, string>} queryData - Object containing named query strings
228
+ * @returns {string} Combined query string or empty string if no queryData provided
229
+ */
230
+ function buildQuery(queryData) {
231
+ if (!queryData)
232
+ return '';
233
+ return Object.entries(queryData)
234
+ .map(([key, query]) => `${key}: ${query}`)
235
+ .join(' ');
236
+ }
237
+ /**
238
+ * Filters response data to include only specified keys.
239
+ *
240
+ * @param {Record<string, string>} responseData - Original response data object
241
+ * @param {string[]} keys - Array of keys to extract from the response data
242
+ * @returns {Record<string, string>} New object containing only the specified keys
243
+ */
244
+ function mapResponseData(responseData, keys) {
245
+ return keys.reduce((accumulator, key) => {
246
+ if (responseData[key] !== undefined) {
247
+ accumulator[key] = responseData[key];
248
+ }
249
+ return accumulator;
250
+ }, {});
251
+ }
252
+ /**
253
+ * Executes a GraphQL query against the DotCMS API.
254
+ *
255
+ * @param {Object} options - Options for the fetch request
256
+ * @param {string} options.body - GraphQL query string
257
+ * @param {Record<string, string>} options.headers - HTTP headers for the request
258
+ * @returns {Promise<any>} Parsed JSON response from the GraphQL API
259
+ * @throws {Error} If the HTTP response is not successful
260
+ */
261
+ async function fetchGraphQL({ baseURL, body, headers }) {
262
+ const url = new URL(baseURL);
263
+ url.pathname = '/api/v1/graphql';
264
+ const response = await fetch(url.toString(), {
265
+ method: 'POST',
266
+ body,
267
+ headers
268
+ });
269
+ if (!response.ok) {
270
+ const error = {
271
+ status: response.status,
272
+ message: transforms.ErrorMessages[response.status] || response.statusText
273
+ };
274
+ throw error;
275
+ }
276
+ return await response.json();
277
+ }
278
+
279
+ var _PageClient_instances, _PageClient_getPageFromGraphQL;
280
+ /**
281
+ * Client for interacting with the DotCMS Page API.
282
+ * Provides methods to retrieve and manipulate pages.
283
+ */
284
+ class PageClient {
285
+ /**
286
+ * Creates a new PageClient instance.
287
+ *
288
+ * @param {DotCMSClientConfig} config - Configuration options for the DotCMS client
289
+ * @param {RequestOptions} requestOptions - Options for fetch requests including authorization headers
290
+ * @example
291
+ * ```typescript
292
+ * const pageClient = new PageClient(
293
+ * {
294
+ * dotcmsUrl: 'https://demo.dotcms.com',
295
+ * authToken: 'your-auth-token',
296
+ * siteId: 'demo.dotcms.com'
297
+ * },
298
+ * {
299
+ * headers: {
300
+ * Authorization: 'Bearer your-auth-token'
301
+ * }
302
+ * }
303
+ * );
304
+ * ```
305
+ */
306
+ constructor(config, requestOptions) {
307
+ _PageClient_instances.add(this);
308
+ this.requestOptions = requestOptions;
309
+ this.siteId = config.siteId || '';
310
+ this.dotcmsUrl = config.dotcmsUrl;
311
+ }
312
+ /**
313
+ * Retrieves a page from DotCMS using GraphQL.
314
+ *
315
+ * @param {string} url - The URL of the page to retrieve
316
+ * @param {DotCMSPageRequestParams} [options] - Options for the request
317
+ * @template T - The type of the page and content, defaults to DotCMSBasicPage and Record<string, unknown> | unknown
318
+ * @returns {Promise<DotCMSComposedPageResponse<T>>} A Promise that resolves to the page data
319
+ *
320
+ * @example Using GraphQL
321
+ * ```typescript
322
+ * const page = await pageClient.get<{ page: MyPageWithBanners; content: { blogPosts: { blogTitle: string } } }>(
323
+ * '/index',
324
+ * {
325
+ * languageId: '1',
326
+ * mode: 'LIVE',
327
+ * graphql: {
328
+ * page: `
329
+ * containers {
330
+ * containerContentlets {
331
+ * contentlets {
332
+ * ... on Banner {
333
+ * ...bannerFragment
334
+ * }
335
+ * }
336
+ * }
337
+ * `,
338
+ * content: {
339
+ * blogPosts: `
340
+ * BlogCollection(limit: 3) {
341
+ * ...blogFragment
342
+ * }
343
+ * `,
344
+ * },
345
+ * fragments: [
346
+ * `
347
+ * fragment bannerFragment on Banner {
348
+ * caption
349
+ * }
350
+ * `,
351
+ * `
352
+ * fragment blogFragment on Blog {
353
+ * title
354
+ * urlTitle
355
+ * }
356
+ * `
357
+ * ]
358
+ * }
359
+ * });
360
+ * ```
361
+ */
362
+ get(url, options) {
363
+ return transforms.__classPrivateFieldGet(this, _PageClient_instances, "m", _PageClient_getPageFromGraphQL).call(this, url, options);
364
+ }
365
+ }
366
+ _PageClient_instances = new WeakSet(), _PageClient_getPageFromGraphQL =
367
+ /**
368
+ * Private implementation method that fetches page data using GraphQL.
369
+ * This method is used internally by the public get() method.
370
+ *
371
+ * @private
372
+ * @param {string} url - The URL of the page to retrieve
373
+ * @param {DotCMSPageRequestParams} [options] - Options including languageId, mode, and GraphQL parameters
374
+ * @returns {Promise<DotCMSComposedPageResponse<T>>} A Promise that resolves to the page data
375
+ */
376
+ async function _PageClient_getPageFromGraphQL(url, options) {
377
+ const { languageId = '1', mode = 'LIVE', siteId = this.siteId, fireRules = false, personaId, publishDate, graphql = {} } = options || {};
378
+ const { page, content = {}, variables, fragments } = graphql;
379
+ const contentQuery = buildQuery(content);
380
+ const completeQuery = buildPageQuery({
381
+ page,
382
+ fragments,
383
+ additionalQueries: contentQuery
384
+ });
385
+ const requestVariables = {
386
+ url,
387
+ mode,
388
+ languageId,
389
+ personaId,
390
+ fireRules,
391
+ publishDate,
392
+ siteId,
393
+ ...variables
394
+ };
395
+ const requestHeaders = this.requestOptions.headers;
396
+ const requestBody = JSON.stringify({ query: completeQuery, variables: requestVariables });
397
+ try {
398
+ const { data, errors } = await fetchGraphQL({
399
+ baseURL: this.dotcmsUrl,
400
+ body: requestBody,
401
+ headers: requestHeaders
402
+ });
403
+ if (errors) {
404
+ errors.forEach((error) => {
405
+ throw new Error(error.message);
406
+ });
407
+ }
408
+ const pageResponse = transforms.graphqlToPageEntity(data);
409
+ if (!pageResponse) {
410
+ throw new Error('No page data found');
411
+ }
412
+ const contentResponse = mapResponseData(data, Object.keys(content));
413
+ return {
414
+ pageAsset: pageResponse,
415
+ content: contentResponse,
416
+ graphql: {
417
+ query: completeQuery,
418
+ variables: requestVariables
419
+ }
420
+ };
421
+ }
422
+ catch (error) {
423
+ const errorMessage = {
424
+ error,
425
+ message: 'Failed to retrieve page data',
426
+ graphql: {
427
+ query: completeQuery,
428
+ variables: requestVariables
429
+ }
430
+ };
431
+ throw errorMessage;
432
+ }
433
+ };
434
+
435
+ /**
436
+ * Parses a string into a URL object.
437
+ *
438
+ * @param url - The URL string to parse
439
+ * @returns A URL object if parsing is successful, undefined otherwise
440
+ */
441
+ function parseURL(url) {
442
+ try {
443
+ return new URL(url);
444
+ }
445
+ catch {
446
+ console.error('Invalid URL:', url);
447
+ return undefined;
448
+ }
449
+ }
450
+ /**
451
+ * Default configuration for the DotCMS client.
452
+ */
453
+ const defaultConfig = {
454
+ dotcmsUrl: '',
455
+ authToken: '',
456
+ requestOptions: {}
457
+ };
458
+ /**
459
+ * Client for interacting with the DotCMS REST API.
460
+ * Provides access to content, page, and navigation functionality.
461
+ */
462
+ class DotCMSClient {
463
+ /**
464
+ * Creates a new DotCMS client instance.
465
+ *
466
+ * @param config - Configuration options for the client
467
+ * @throws Warning if dotcmsUrl is invalid or authToken is missing
468
+ */
469
+ constructor(config = defaultConfig) {
470
+ this.config = config;
471
+ this.requestOptions = this.createAuthenticatedRequestOptions(this.config);
472
+ // Initialize clients
473
+ this.page = new PageClient(this.config, this.requestOptions);
474
+ this.nav = new NavigationClient(this.config, this.requestOptions);
475
+ this.content = new transforms.Content(this.requestOptions, this.config.dotcmsUrl);
476
+ }
477
+ /**
478
+ * Creates request options with authentication headers.
479
+ *
480
+ * @param config - The client configuration
481
+ * @returns Request options with authorization headers
482
+ */
483
+ createAuthenticatedRequestOptions(config) {
484
+ return {
485
+ ...config.requestOptions,
486
+ headers: {
487
+ ...config.requestOptions?.headers,
488
+ Authorization: `Bearer ${config.authToken}`
489
+ }
490
+ };
491
+ }
492
+ }
493
+ /**
494
+ * Creates and returns a new DotCMS client instance.
495
+ *
496
+ * @param config - Configuration options for the client
497
+ * @returns A configured DotCMS client instance
498
+ * @example
499
+ * ```typescript
500
+ * const client = dotCMSCreateClient({
501
+ * dotcmsUrl: 'https://demo.dotcms.com',
502
+ * authToken: 'your-auth-token'
503
+ * });
504
+ *
505
+ * // Use the client to fetch content
506
+ * const pages = await client.page.get('/about-us');
507
+ * ```
508
+ */
509
+ const createDotCMSClient = (clientConfig) => {
510
+ const { dotcmsUrl, authToken } = clientConfig || {};
511
+ const instanceUrl = parseURL(dotcmsUrl)?.origin;
512
+ if (!instanceUrl) {
513
+ throw new TypeError("Invalid configuration - 'dotcmsUrl' must be a valid URL");
514
+ }
515
+ if (!authToken) {
516
+ throw new TypeError("Invalid configuration - 'authToken' is required");
517
+ }
518
+ const config = {
519
+ ...clientConfig,
520
+ authToken,
521
+ dotcmsUrl: instanceUrl
522
+ };
523
+ return new DotCMSClient(config);
524
+ };
525
+
526
+ exports.createDotCMSClient = createDotCMSClient;
package/next.cjs.mjs ADDED
@@ -0,0 +1,2 @@
1
+ export * from './next.cjs.js';
2
+ export { _default as default } from './next.cjs.default.js';
package/next.esm.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/next";