@dotcms/client 0.0.1-beta.4 → 0.0.1-beta.40

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/next.esm.js CHANGED
@@ -1,4 +1,5 @@
1
- import { E as ErrorMessages, _ as __classPrivateFieldGet, g as graphqlToPageEntity, C as Content } from './transforms.esm.js';
1
+ import { consola } from 'consola';
2
+ import { E as ErrorMessages, g as graphqlToPageEntity, C as Content } from './transforms.esm.js';
2
3
 
3
4
  class NavigationClient {
4
5
  constructor(config, requestOptions) {
@@ -8,7 +9,7 @@ class NavigationClient {
8
9
  /**
9
10
  * Retrieves information about the dotCMS file and folder tree.
10
11
  * @param {NavigationApiOptions} options - The options for the Navigation API call. Defaults to `{ depth: 0, path: '/', languageId: 1 }`.
11
- * @returns {Promise<unknown>} - A Promise that resolves to the response from the DotCMS API.
12
+ * @returns {Promise<DotCMSNavigationItem[]>} - A Promise that resolves to the response from the DotCMS API.
12
13
  * @throws {Error} - Throws an error if the options are not valid.
13
14
  */
14
15
  async get(path, params) {
@@ -77,7 +78,7 @@ const DEFAULT_PAGE_CONTENTLETS_CONTENT = `
77
78
  */
78
79
  const buildPageQuery = ({ page, fragments, additionalQueries }) => {
79
80
  if (!page) {
80
- 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.');
81
+ consola.warn("[DotCMS Client]: No page query was found, so we're loading all content using _map. This might slow things down. For better performance, we recommend adding a specific query in the page attribute.");
81
82
  }
82
83
  return `
83
84
  fragment DotCMSPage on DotPage {
@@ -97,6 +98,7 @@ const buildPageQuery = ({ page, fragments, additionalQueries }) => {
97
98
  friendlyName
98
99
  workingInode
99
100
  url
101
+ pageURI
100
102
  hasLiveVersion
101
103
  deleted
102
104
  pageUrl
@@ -123,6 +125,22 @@ const buildPageQuery = ({ page, fragments, additionalQueries }) => {
123
125
  canEdit
124
126
  canLock
125
127
  canRead
128
+ runningExperimentId
129
+ urlContentMap {
130
+ _map
131
+ }
132
+ host {
133
+ identifier
134
+ hostName
135
+ googleMap
136
+ archived
137
+ contentType
138
+ }
139
+ vanityUrl {
140
+ action
141
+ forwardTo
142
+ uri
143
+ }
126
144
  conLanguage {
127
145
  id
128
146
  language
@@ -130,6 +148,9 @@ const buildPageQuery = ({ page, fragments, additionalQueries }) => {
130
148
  }
131
149
  template {
132
150
  drawed
151
+ anonymous
152
+ theme
153
+ identifier
133
154
  }
134
155
  containers {
135
156
  path
@@ -171,7 +192,24 @@ const buildPageQuery = ({ page, fragments, additionalQueries }) => {
171
192
  viewAs {
172
193
  visitor {
173
194
  persona {
195
+ modDate
196
+ inode
174
197
  name
198
+ identifier
199
+ keyTag
200
+ photo {
201
+ versionPath
202
+ }
203
+ }
204
+ }
205
+ persona {
206
+ modDate
207
+ inode
208
+ name
209
+ identifier
210
+ keyTag
211
+ photo {
212
+ versionPath
175
213
  }
176
214
  }
177
215
  language {
@@ -188,8 +226,8 @@ const buildPageQuery = ({ page, fragments, additionalQueries }) => {
188
226
 
189
227
  ${fragments ? fragments.join('\n\n') : ''}
190
228
 
191
- query PageContent($url: String!, $languageId: String, $mode: String) {
192
- page: page(url: $url, languageId: $languageId, pageMode: $mode) {
229
+ query PageContent($url: String!, $languageId: String, $mode: String, $personaId: String, $fireRules: Boolean, $publishDate: String, $siteId: String) {
230
+ page: page(url: $url, languageId: $languageId, pageMode: $mode, persona: $personaId, fireRules: $fireRules, publishDate: $publishDate, site: $siteId) {
193
231
  ...DotCMSPage
194
232
  ${page ? '...ClientPage' : ''}
195
233
  }
@@ -253,7 +291,6 @@ async function fetchGraphQL({ baseURL, body, headers }) {
253
291
  return await response.json();
254
292
  }
255
293
 
256
- var _PageClient_instances, _PageClient_isGraphQLRequest, _PageClient_getPageFromAPI, _PageClient_getPageFromGraphQL, _PageClient_mapToBackendParams;
257
294
  /**
258
295
  * Client for interacting with the DotCMS Page API.
259
296
  * Provides methods to retrieve and manipulate pages.
@@ -281,181 +318,120 @@ class PageClient {
281
318
  * ```
282
319
  */
283
320
  constructor(config, requestOptions) {
284
- _PageClient_instances.add(this);
285
321
  this.requestOptions = requestOptions;
286
322
  this.siteId = config.siteId || '';
287
323
  this.dotcmsUrl = config.dotcmsUrl;
288
324
  }
289
- get(url, options) {
290
- if (!options) {
291
- return __classPrivateFieldGet(this, _PageClient_instances, "m", _PageClient_getPageFromAPI).call(this, url);
292
- }
293
- if (__classPrivateFieldGet(this, _PageClient_instances, "m", _PageClient_isGraphQLRequest).call(this, options)) {
294
- return __classPrivateFieldGet(this, _PageClient_instances, "m", _PageClient_getPageFromGraphQL).call(this, url, options);
295
- }
296
- return __classPrivateFieldGet(this, _PageClient_instances, "m", _PageClient_getPageFromAPI).call(this, url, options);
297
- }
298
- }
299
- _PageClient_instances = new WeakSet(), _PageClient_isGraphQLRequest = function _PageClient_isGraphQLRequest(options) {
300
- return 'graphql' in options;
301
- }, _PageClient_getPageFromAPI =
302
- /**
303
- * Retrieves all the elements of a Page in your dotCMS system in JSON format.
304
- *
305
- * @param {string} path - The path of the page to retrieve
306
- * @param {PageRequestParams} params - The options for the Page API call
307
- * @returns {Promise<unknown>} A Promise that resolves to the page data
308
- * @throws {Error} Throws an error if the path parameter is missing or if the fetch request fails
309
- * @example
310
- * ```typescript
311
- * // Get a page with default parameters
312
- * const homePage = await pageClient.get('/');
313
- *
314
- * // Get a page with specific language and mode
315
- * const aboutPage = await pageClient.get('/about-us', {
316
- * languageId: 2,
317
- * mode: 'PREVIEW_MODE'
318
- * });
319
- *
320
- * // Get a page with persona targeting
321
- * const productPage = await pageClient.get('/products', {
322
- * personaId: 'persona-123',
323
- * depth: 2
324
- * });
325
- * ```
326
- */
327
- async function _PageClient_getPageFromAPI(path, params) {
328
- if (!path) {
329
- throw new Error("The 'path' parameter is required for the Page API");
330
- }
331
- // Remove leading and trailing slashes from the path.
332
- // Add a leading slash if it's missing.
333
- const pagePath = `/${path.replace(/^\/+/, '').replace(/\/+/g, '/')}${path.endsWith('/') ? '/' : ''}`;
334
- const pageParams = __classPrivateFieldGet(this, _PageClient_instances, "m", _PageClient_mapToBackendParams).call(this, params || {});
335
- const urlParams = new URLSearchParams(pageParams).toString();
336
- const url = `${this.dotcmsUrl}/api/v1/page/json${pagePath}${urlParams ? `?${urlParams}` : ''}`;
337
- const response = await fetch(url, this.requestOptions);
338
- if (!response.ok) {
339
- const error = {
340
- status: response.status,
341
- message: ErrorMessages[response.status] || response.statusText
342
- };
343
- throw error;
344
- }
345
- return response.json().then((data) => data.entity);
346
- }, _PageClient_getPageFromGraphQL =
347
- /**
348
- * Retrieves a personalized page with associated content and navigation.
349
- *
350
- * @param {Object} options - Options for the personalized page request
351
- * @param {string} options.url - The URL of the page to retrieve
352
- * @param {string} options.languageId - The language ID for the page content
353
- * @param {string} options.mode - The rendering mode for the page
354
- * @param {string} options.pageFragment - GraphQL fragment for page data
355
- * @param {Record<string, string>} options.content - Content queries to include
356
- * @param {Record<string, string>} options.nav - Navigation queries to include
357
- * @returns {Promise<Object>} A Promise that resolves to the personalized page data with content and navigation
358
- * @example
359
- * ```typescript
360
- * // Get a personalized page with content and navigation
361
- * const personalizedPage = await pageClient.getPageFromGraphQL({
362
- * url: '/about-us',
363
- * languageId: '1',
364
- * mode: 'LIVE',
365
- * pageFragment: `
366
- * fragment PageFields on Page {
367
- * title
368
- * description
369
- * modDate
370
- * }
371
- * `,
372
- * content: {
373
- * blogs: `
374
- * search(query: "+contentType: blog", limit: 3) {
375
- * title
376
- * ...on Blog {
377
- * author {
378
- * title
379
- * }
380
- * }
381
- }
382
- * nav: {
383
- * mainNav: `
384
- * query MainNav {
385
- * Nav(identifier: "main-nav") {
386
- * title
387
- * items {
388
- * label
389
- * url
390
- * }
391
- * }
392
- * }
393
- * `
394
- * }
395
- * });
396
- * ```
397
- */
398
- async function _PageClient_getPageFromGraphQL(url, options) {
399
- const { languageId = '1', mode = 'LIVE', graphql = {} } = options || {};
400
- const { page, content = {}, variables, fragments } = graphql;
401
- const contentQuery = buildQuery(content);
402
- const completeQuery = buildPageQuery({
403
- page,
404
- fragments,
405
- additionalQueries: contentQuery
406
- });
407
- const requestVariables = {
408
- url,
409
- mode,
410
- languageId,
411
- ...variables
412
- };
413
- const requestHeaders = this.requestOptions.headers;
414
- const requestBody = JSON.stringify({ query: completeQuery, variables: requestVariables });
415
- try {
416
- const { data, errors } = await fetchGraphQL({
417
- baseURL: this.dotcmsUrl,
418
- body: requestBody,
419
- headers: requestHeaders
325
+ /**
326
+ * Retrieves a page from DotCMS using GraphQL.
327
+ *
328
+ * @param {string} url - The URL of the page to retrieve
329
+ * @param {DotCMSPageRequestParams} [options] - Options for the request
330
+ * @template T - The type of the page and content, defaults to DotCMSBasicPage and Record<string, unknown> | unknown
331
+ * @returns {Promise<DotCMSComposedPageResponse<T>>} A Promise that resolves to the page data
332
+ *
333
+ * @example Using GraphQL
334
+ * ```typescript
335
+ * const page = await pageClient.get<{ page: MyPageWithBanners; content: { blogPosts: { blogTitle: string } } }>(
336
+ * '/index',
337
+ * {
338
+ * languageId: '1',
339
+ * mode: 'LIVE',
340
+ * graphql: {
341
+ * page: `
342
+ * containers {
343
+ * containerContentlets {
344
+ * contentlets {
345
+ * ... on Banner {
346
+ * ...bannerFragment
347
+ * }
348
+ * }
349
+ * }
350
+ * `,
351
+ * content: {
352
+ * blogPosts: `
353
+ * BlogCollection(limit: 3) {
354
+ * ...blogFragment
355
+ * }
356
+ * `,
357
+ * },
358
+ * fragments: [
359
+ * `
360
+ * fragment bannerFragment on Banner {
361
+ * caption
362
+ * }
363
+ * `,
364
+ * `
365
+ * fragment blogFragment on Blog {
366
+ * title
367
+ * urlTitle
368
+ * }
369
+ * `
370
+ * ]
371
+ * }
372
+ * });
373
+ * ```
374
+ */
375
+ async get(url, options) {
376
+ const { languageId = '1', mode = 'LIVE', siteId = this.siteId, fireRules = false, personaId, publishDate, graphql = {} } = options || {};
377
+ const { page, content = {}, variables, fragments } = graphql;
378
+ const contentQuery = buildQuery(content);
379
+ const completeQuery = buildPageQuery({
380
+ page,
381
+ fragments,
382
+ additionalQueries: contentQuery
420
383
  });
421
- if (errors) {
422
- errors.forEach((error) => {
423
- throw new Error(error.message);
384
+ const requestVariables = {
385
+ // The url is expected to have a leading slash to comply on VanityURL Matching, some frameworks like Angular will not add the leading slash
386
+ url: url.startsWith('/') ? url : `/${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
424
402
  });
403
+ if (errors) {
404
+ errors.forEach((error) => {
405
+ throw new Error(error.message);
406
+ });
407
+ }
408
+ const pageResponse = 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
+ };
425
421
  }
426
- const pageResponse = graphqlToPageEntity(data);
427
- if (!pageResponse) {
428
- throw new Error('No page data found');
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;
429
432
  }
430
- const contentResponse = mapResponseData(data, Object.keys(content));
431
- return {
432
- page: pageResponse,
433
- content: contentResponse,
434
- errors
435
- };
436
- }
437
- catch (error) {
438
- const errorMessage = {
439
- error,
440
- message: 'Failed to retrieve page data',
441
- query: completeQuery,
442
- variables: requestVariables
443
- };
444
- throw errorMessage;
445
433
  }
446
- }, _PageClient_mapToBackendParams = function _PageClient_mapToBackendParams(params) {
447
- const backendParams = {
448
- hostId: params.siteId || this.siteId,
449
- mode: params.mode,
450
- language_id: params.languageId ? String(params.languageId) : undefined,
451
- 'com.dotmarketing.persona.id': params.personaId,
452
- fireRules: params.fireRules ? String(params.fireRules) : undefined,
453
- depth: params.depth ? String(params.depth) : undefined,
454
- publishDate: params.publishDate
455
- };
456
- // Remove undefined values
457
- return Object.fromEntries(Object.entries(backendParams).filter(([_, value]) => value !== undefined));
458
- };
434
+ }
459
435
 
460
436
  /**
461
437
  * Parses a string into a URL object.
@@ -468,7 +444,7 @@ function parseURL(url) {
468
444
  return new URL(url);
469
445
  }
470
446
  catch {
471
- console.error('Invalid URL:', url);
447
+ consola.error('[DotCMS Client]: Invalid URL:', url);
472
448
  return undefined;
473
449
  }
474
450
  }
package/package.json CHANGED
@@ -1,11 +1,17 @@
1
1
  {
2
2
  "name": "@dotcms/client",
3
- "version": "0.0.1-beta.4",
3
+ "version": "0.0.1-beta.40",
4
4
  "description": "Official JavaScript library for interacting with DotCMS REST APIs.",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/dotCMS/core.git#main"
8
8
  },
9
+ "dependencies": {
10
+ "consola": "^3.4.2"
11
+ },
12
+ "devDependencies": {
13
+ "@dotcms/types": "next"
14
+ },
9
15
  "scripts": {
10
16
  "build": "nx run sdk-client:build:js; cd ../../../../dotCMS/src/main/webapp/html/js/editor-js; rm -rf src package.json *.esm.d.ts"
11
17
  },
@@ -29,12 +35,6 @@
29
35
  "types": "./next.esm.d.ts",
30
36
  "import": "./next.cjs.mjs",
31
37
  "default": "./next.cjs.js"
32
- },
33
- "./types": {
34
- "module": "./types.esm.js",
35
- "types": "./types.esm.d.ts",
36
- "import": "./types.cjs.mjs",
37
- "default": "./types.cjs.js"
38
38
  }
39
39
  },
40
40
  "typesVersions": {
@@ -44,9 +44,6 @@
44
44
  ],
45
45
  "next": [
46
46
  "./src/next.d.ts"
47
- ],
48
- "types": [
49
- "./src/types.d.ts"
50
47
  ]
51
48
  }
52
49
  },
@@ -1,35 +1,7 @@
1
+ import { DotCMSClientConfig } from '@dotcms/types';
1
2
  import { Content } from './content/content-api';
2
3
  import { NavigationClient } from './navigation/navigation-api';
3
4
  import { PageClient } from './page/page-api';
4
- /**
5
- * Options for configuring fetch requests, excluding body and method properties.
6
- */
7
- export type RequestOptions = Omit<RequestInit, 'body' | 'method'>;
8
- /**
9
- * Configuration options for the DotCMS client.
10
- */
11
- export interface DotCMSClientConfig {
12
- /**
13
- * The URL of the dotCMS instance.
14
- * Ensure to include the protocol (http or https).
15
- * @example `https://demo.dotcms.com`
16
- */
17
- dotcmsUrl: string;
18
- /**
19
- * The authentication token for requests.
20
- * Obtainable from the dotCMS UI.
21
- */
22
- authToken: string;
23
- /**
24
- * The id of the site you want to interact with. Defaults to the default site if not provided.
25
- */
26
- siteId?: string;
27
- /**
28
- * Additional options for the fetch request.
29
- * @example `{ headers: { 'Content-Type': 'application/json' } }`
30
- */
31
- requestOptions?: RequestOptions;
32
- }
33
5
  /**
34
6
  * Client for interacting with the DotCMS REST API.
35
7
  * Provides access to content, page, and navigation functionality.
@@ -1,5 +1,5 @@
1
+ import { RequestOptions } from '@dotcms/types';
1
2
  import { CollectionBuilder } from './builders/collection/collection';
2
- import { ClientOptions } from '../../deprecated/sdk-js-client';
3
3
  /**
4
4
  * Creates a builder to filter and fetch a collection of content items.
5
5
  * @param contentType - The content type to retrieve.
@@ -15,7 +15,6 @@ import { ClientOptions } from '../../deprecated/sdk-js-client';
15
15
  * .sortBy([{ field: 'title', order: 'asc' }])
16
16
  * .query(q => q.field('author').equals('John Doe'))
17
17
  * .depth(1)
18
- * .fetch();
19
18
  *
20
19
  * console.log(response.contentlets);
21
20
  * ```
@@ -29,7 +28,6 @@ import { ClientOptions } from '../../deprecated/sdk-js-client';
29
28
  * .sortBy([{ field: 'title', order: 'asc' }])
30
29
  * .query(q => q.field('author').equals('John Doe'))
31
30
  * .depth(1)
32
- * .fetch()
33
31
  * .then(response => console.log(response.contentlets))
34
32
  * .catch(error => console.error(error));
35
33
  * ```
@@ -45,7 +43,6 @@ import { ClientOptions } from '../../deprecated/sdk-js-client';
45
43
  * const posts = await client.content
46
44
  * .getCollection<BlogPost>('Blog')
47
45
  * .limit(10)
48
- * .fetch();
49
46
  *
50
47
  * posts.contentlets.forEach(post => {
51
48
  * console.log(post.title, post.author, post.summary);
@@ -56,10 +53,10 @@ export declare class Content {
56
53
  #private;
57
54
  /**
58
55
  * Creates an instance of Content.
59
- * @param {ClientOptions} requestOptions - The options for the client request.
56
+ * @param {RequestOptions} requestOptions - The options for the client request.
60
57
  * @param {string} serverUrl - The server URL.
61
58
  */
62
- constructor(requestOptions: ClientOptions, serverUrl: string);
59
+ constructor(requestOptions: RequestOptions, serverUrl: string);
63
60
  /**
64
61
  * Takes a content type and returns a builder to filter and fetch the collection.
65
62
  * @param {string} contentType - The content type to get the collection.
@@ -1,3 +1,4 @@
1
+ import { Contentlet } from '@dotcms/types';
1
2
  import { Equals } from '../builders/query/lucene-syntax';
2
3
  import { QueryBuilder } from '../builders/query/query';
3
4
  /**
@@ -21,48 +22,6 @@ export type SortBy = {
21
22
  * @returns {Equals} The built query.
22
23
  */
23
24
  export type BuildQuery = (qb: QueryBuilder) => Equals;
24
- /**
25
- * Main fields of a Contentlet (Inherited from the Content Type).
26
- */
27
- export interface ContentTypeMainFields {
28
- hostName: string;
29
- modDate: string;
30
- publishDate: string;
31
- title: string;
32
- baseType: string;
33
- inode: string;
34
- archived: boolean;
35
- ownerName: string;
36
- host: string;
37
- working: boolean;
38
- locked: boolean;
39
- stInode: string;
40
- contentType: string;
41
- live: boolean;
42
- owner: string;
43
- identifier: string;
44
- publishUserName: string;
45
- publishUser: string;
46
- languageId: number;
47
- creationDate: string;
48
- url: string;
49
- titleImage: string;
50
- modUserName: string;
51
- hasLiveVersion: boolean;
52
- folder: string;
53
- hasTitleImage: boolean;
54
- sortOrder: number;
55
- modUser: string;
56
- __icon__: string;
57
- contentTypeIcon: string;
58
- variant: string;
59
- }
60
- /**
61
- * The contentlet has the main fields and the custom fields of the content type.
62
- *
63
- * @template T - The custom fields of the content type.
64
- */
65
- export type Contentlet<T> = T & ContentTypeMainFields;
66
25
  /**
67
26
  * Callback for a fulfilled promise.
68
27
  *
@@ -1,20 +1,4 @@
1
- import { DotCMSClientConfig, RequestOptions } from '../client';
2
- interface NavRequestParams {
3
- /**
4
- * The depth of the folder tree to return.
5
- * @example
6
- * `1` returns only the element specified in the path.
7
- * `2` returns the element specified in the path, and if that element is a folder, returns all direct children of that folder.
8
- * `3` returns all children and grandchildren of the element specified in the path.
9
- */
10
- depth?: number;
11
- /**
12
- * The language ID of content to return.
13
- * @example
14
- * `1` (or unspecified) returns content in the default language of the site.
15
- */
16
- languageId?: number;
17
- }
1
+ import { DotCMSClientConfig, DotCMSNavigationRequestParams, RequestOptions, DotCMSNavigationItem } from '@dotcms/types';
18
2
  export declare class NavigationClient {
19
3
  private requestOptions;
20
4
  private BASE_URL;
@@ -22,10 +6,9 @@ export declare class NavigationClient {
22
6
  /**
23
7
  * Retrieves information about the dotCMS file and folder tree.
24
8
  * @param {NavigationApiOptions} options - The options for the Navigation API call. Defaults to `{ depth: 0, path: '/', languageId: 1 }`.
25
- * @returns {Promise<unknown>} - A Promise that resolves to the response from the DotCMS API.
9
+ * @returns {Promise<DotCMSNavigationItem[]>} - A Promise that resolves to the response from the DotCMS API.
26
10
  * @throws {Error} - Throws an error if the options are not valid.
27
11
  */
28
- get(path: string, params?: NavRequestParams): Promise<unknown>;
12
+ get(path: string, params?: DotCMSNavigationRequestParams): Promise<DotCMSNavigationItem[]>;
29
13
  private mapToBackendParams;
30
14
  }
31
- export {};