@dotcms/client 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +538 -13
- package/index.cjs.js +418 -58
- package/index.esm.js +419 -59
- package/package.json +1 -1
- package/src/lib/client/ai/ai-api.d.ts +77 -0
- package/src/lib/client/ai/search/search.d.ts +65 -0
- package/src/lib/client/ai/shared/const.d.ts +16 -0
- package/src/lib/client/ai/shared/types.d.ts +18 -0
- package/src/lib/client/base/base-api.d.ts +42 -0
- package/src/lib/client/client.d.ts +6 -0
- package/src/lib/client/content/builders/collection/collection.d.ts +3 -10
- package/src/lib/client/content/content-api.d.ts +3 -3
- package/src/lib/client/navigation/navigation-api.d.ts +8 -3
- package/src/lib/client/page/page-api.d.ts +2 -21
- package/src/lib/client/page/utils.d.ts +1 -1
- package/src/lib/utils/params/utils.d.ts +25 -0
package/index.cjs.js
CHANGED
|
@@ -147,6 +147,366 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
147
147
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
148
148
|
};
|
|
149
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Utility functions for AI search parameter mapping and processing
|
|
152
|
+
*/
|
|
153
|
+
/**
|
|
154
|
+
* Appends mapped parameters to URLSearchParams based on a mapping configuration.
|
|
155
|
+
* Only includes parameters that have defined values.
|
|
156
|
+
*
|
|
157
|
+
* @param searchParams - The URLSearchParams object to append to
|
|
158
|
+
* @param sourceObject - The source object containing values
|
|
159
|
+
* @param mapping - Array of [targetKey, sourceKey] pairs for parameter mapping, or [key] to use same key
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* const params = new URLSearchParams();
|
|
163
|
+
* const query = { limit: 10, offset: 0, siteId: 'default', indexName: 'content' };
|
|
164
|
+
* const mapping = [
|
|
165
|
+
* ['searchLimit', 'limit'], // Maps limit -> searchLimit
|
|
166
|
+
* ['searchOffset', 'offset'], // Maps offset -> searchOffset
|
|
167
|
+
* ['site', 'siteId'], // Maps siteId -> site
|
|
168
|
+
* ['indexName'] // Uses indexName -> indexName (same key)
|
|
169
|
+
* ];
|
|
170
|
+
* appendMappedParams(params, query, mapping);
|
|
171
|
+
* // Results in: searchLimit=10&searchOffset=0&site=default&indexName=content
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
function appendMappedParams(searchParams, sourceObject, mapping) {
|
|
175
|
+
mapping.forEach((item) => {
|
|
176
|
+
const targetKey = item[0];
|
|
177
|
+
const sourceKey = item[1] ?? item[0];
|
|
178
|
+
const value = sourceObject[sourceKey];
|
|
179
|
+
if (value !== undefined) {
|
|
180
|
+
searchParams.append(targetKey, String(value));
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
var _BaseApiClient_requestOptions, _BaseApiClient_config, _BaseApiClient_httpClient;
|
|
186
|
+
/**
|
|
187
|
+
* Base class for all DotCMS API clients.
|
|
188
|
+
* Provides common constructor parameters and properties that all API clients need.
|
|
189
|
+
* Uses JavaScript private fields (#) for true runtime privacy.
|
|
190
|
+
*/
|
|
191
|
+
class BaseApiClient {
|
|
192
|
+
/**
|
|
193
|
+
* Creates a new API client instance.
|
|
194
|
+
*
|
|
195
|
+
* @param {DotCMSClientConfig} config - Configuration options for the DotCMS client
|
|
196
|
+
* @param {DotRequestOptions} requestOptions - Options for fetch requests including authorization headers
|
|
197
|
+
* @param {DotHttpClient} httpClient - HTTP client for making requests
|
|
198
|
+
*/
|
|
199
|
+
constructor(config, requestOptions = {}, httpClient) {
|
|
200
|
+
/**
|
|
201
|
+
* Request options including authorization headers.
|
|
202
|
+
* @private
|
|
203
|
+
*/
|
|
204
|
+
_BaseApiClient_requestOptions.set(this, void 0);
|
|
205
|
+
/**
|
|
206
|
+
* DotCMS client configuration.
|
|
207
|
+
* @private
|
|
208
|
+
*/
|
|
209
|
+
_BaseApiClient_config.set(this, void 0);
|
|
210
|
+
/**
|
|
211
|
+
* HTTP client for making requests.
|
|
212
|
+
* @private
|
|
213
|
+
*/
|
|
214
|
+
_BaseApiClient_httpClient.set(this, void 0);
|
|
215
|
+
__classPrivateFieldSet(this, _BaseApiClient_config, {
|
|
216
|
+
siteId: '',
|
|
217
|
+
...config
|
|
218
|
+
}, "f");
|
|
219
|
+
__classPrivateFieldSet(this, _BaseApiClient_requestOptions, {
|
|
220
|
+
...requestOptions
|
|
221
|
+
}, "f");
|
|
222
|
+
__classPrivateFieldSet(this, _BaseApiClient_httpClient, httpClient, "f");
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Gets the request options including authorization headers.
|
|
226
|
+
* @protected
|
|
227
|
+
*/
|
|
228
|
+
get requestOptions() {
|
|
229
|
+
return __classPrivateFieldGet(this, _BaseApiClient_requestOptions, "f");
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Gets the DotCMS client configuration.
|
|
233
|
+
* @protected
|
|
234
|
+
*/
|
|
235
|
+
get config() {
|
|
236
|
+
return __classPrivateFieldGet(this, _BaseApiClient_config, "f");
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Gets the HTTP client for making requests.
|
|
240
|
+
* @protected
|
|
241
|
+
*/
|
|
242
|
+
get httpClient() {
|
|
243
|
+
return __classPrivateFieldGet(this, _BaseApiClient_httpClient, "f");
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Gets the DotCMS URL from config.
|
|
247
|
+
* @protected
|
|
248
|
+
*/
|
|
249
|
+
get dotcmsUrl() {
|
|
250
|
+
return __classPrivateFieldGet(this, _BaseApiClient_config, "f").dotcmsUrl;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Gets the site ID from config.
|
|
254
|
+
* @protected
|
|
255
|
+
*/
|
|
256
|
+
get siteId() {
|
|
257
|
+
return __classPrivateFieldGet(this, _BaseApiClient_config, "f").siteId || '';
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
_BaseApiClient_requestOptions = new WeakMap(), _BaseApiClient_config = new WeakMap(), _BaseApiClient_httpClient = new WeakMap();
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Default values for AI configuration
|
|
264
|
+
*/
|
|
265
|
+
const DEFAULT_AI_CONFIG = {
|
|
266
|
+
threshold: 0.5,
|
|
267
|
+
distanceFunction: types.DISTANCE_FUNCTIONS.cosine,
|
|
268
|
+
responseLength: 1024
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* Default values for search query
|
|
272
|
+
*/
|
|
273
|
+
const DEFAULT_QUERY = {
|
|
274
|
+
limit: 1000,
|
|
275
|
+
offset: 0,
|
|
276
|
+
indexName: 'default'
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
var _AISearch_params, _AISearch_prompt, _AISearch_indexName;
|
|
280
|
+
/**
|
|
281
|
+
* Class for executing AI searches.
|
|
282
|
+
*
|
|
283
|
+
* @template T - The type of the contentlet.
|
|
284
|
+
* @param config - The configuration for the client.
|
|
285
|
+
* @param requestOptions - The request options for the client.
|
|
286
|
+
* @param httpClient - The HTTP client for the client.
|
|
287
|
+
* @param params - The parameters for the search.
|
|
288
|
+
* @param prompt - The prompt for the search.
|
|
289
|
+
*/
|
|
290
|
+
class AISearch extends BaseApiClient {
|
|
291
|
+
constructor(config, requestOptions, httpClient, prompt, indexName, params = {}) {
|
|
292
|
+
super(config, requestOptions, httpClient);
|
|
293
|
+
_AISearch_params.set(this, void 0);
|
|
294
|
+
_AISearch_prompt.set(this, void 0);
|
|
295
|
+
_AISearch_indexName.set(this, void 0);
|
|
296
|
+
__classPrivateFieldSet(this, _AISearch_params, params, "f");
|
|
297
|
+
__classPrivateFieldSet(this, _AISearch_prompt, prompt, "f");
|
|
298
|
+
__classPrivateFieldSet(this, _AISearch_indexName, indexName, "f");
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Executes the AI search and returns a promise with the search results.
|
|
302
|
+
*
|
|
303
|
+
* @param onfulfilled - Callback function to handle the search results.
|
|
304
|
+
* @param onrejected - Callback function to handle the search error.
|
|
305
|
+
* @returns Promise with the search results or the error.
|
|
306
|
+
* @example
|
|
307
|
+
* ```typescript
|
|
308
|
+
* const results = await client.ai.search('machine learning articles', 'content_index', {
|
|
309
|
+
* query: {
|
|
310
|
+
* limit: 20,
|
|
311
|
+
* contentType: 'BlogPost',
|
|
312
|
+
* languageId: '1' // or 1
|
|
313
|
+
* },
|
|
314
|
+
* config: {
|
|
315
|
+
* threshold: 0.7
|
|
316
|
+
* }
|
|
317
|
+
* });
|
|
318
|
+
* ```
|
|
319
|
+
* @example
|
|
320
|
+
* ```typescript
|
|
321
|
+
* client.ai.search('machine learning articles', 'content_index', {
|
|
322
|
+
* query: {
|
|
323
|
+
* limit: 20,
|
|
324
|
+
* contentType: 'BlogPost',
|
|
325
|
+
* languageId: '1' // or 1
|
|
326
|
+
* },
|
|
327
|
+
* config: {
|
|
328
|
+
* threshold: 0.7
|
|
329
|
+
* }
|
|
330
|
+
* }).then((results) => {
|
|
331
|
+
* console.log(results);
|
|
332
|
+
* }).catch((error) => {
|
|
333
|
+
* console.error(error);
|
|
334
|
+
* });
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
337
|
+
then(onfulfilled, onrejected) {
|
|
338
|
+
return this.fetch().then((data) => {
|
|
339
|
+
const response = {
|
|
340
|
+
...data,
|
|
341
|
+
results: data.dotCMSResults
|
|
342
|
+
};
|
|
343
|
+
if (typeof onfulfilled === 'function') {
|
|
344
|
+
const result = onfulfilled(response);
|
|
345
|
+
// Ensure we always return a value, fallback to data if callback returns undefined
|
|
346
|
+
return result ?? response;
|
|
347
|
+
}
|
|
348
|
+
return response;
|
|
349
|
+
}, (error) => {
|
|
350
|
+
// Wrap error in DotCMSContentError
|
|
351
|
+
let contentError;
|
|
352
|
+
if (error instanceof types.DotHttpError) {
|
|
353
|
+
contentError = new types.DotErrorAISearch({
|
|
354
|
+
message: `AI Search failed (fetch): ${error.message}`,
|
|
355
|
+
httpError: error,
|
|
356
|
+
params: __classPrivateFieldGet(this, _AISearch_params, "f"),
|
|
357
|
+
prompt: __classPrivateFieldGet(this, _AISearch_prompt, "f"),
|
|
358
|
+
indexName: __classPrivateFieldGet(this, _AISearch_indexName, "f")
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
363
|
+
contentError = new types.DotErrorAISearch({
|
|
364
|
+
message: `AI Search failed (fetch): ${errorMessage}`,
|
|
365
|
+
httpError: undefined,
|
|
366
|
+
params: __classPrivateFieldGet(this, _AISearch_params, "f"),
|
|
367
|
+
prompt: __classPrivateFieldGet(this, _AISearch_prompt, "f"),
|
|
368
|
+
indexName: __classPrivateFieldGet(this, _AISearch_indexName, "f")
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
if (typeof onrejected === 'function') {
|
|
372
|
+
const result = onrejected(contentError);
|
|
373
|
+
// Ensure we always return a value, fallback to original error if callback returns undefined
|
|
374
|
+
return result ?? contentError;
|
|
375
|
+
}
|
|
376
|
+
// Throw the wrapped error to trigger .catch()
|
|
377
|
+
throw contentError;
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
fetch() {
|
|
381
|
+
const searchParams = this.buildSearchParams(__classPrivateFieldGet(this, _AISearch_prompt, "f"), __classPrivateFieldGet(this, _AISearch_params, "f"));
|
|
382
|
+
const url = new URL('/api/v1/ai/search', this.dotcmsUrl);
|
|
383
|
+
url.search = searchParams.toString();
|
|
384
|
+
return this.httpClient.request(url.toString(), {
|
|
385
|
+
...this.requestOptions,
|
|
386
|
+
headers: {
|
|
387
|
+
...this.requestOptions.headers
|
|
388
|
+
},
|
|
389
|
+
method: 'GET'
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Builds URLSearchParams from the SDK interface, mapping to backend parameter names.
|
|
394
|
+
* Only includes parameters that have values.
|
|
395
|
+
*
|
|
396
|
+
* @param params - Search parameters with SDK naming
|
|
397
|
+
* @returns URLSearchParams with backend parameter names
|
|
398
|
+
* @private
|
|
399
|
+
*/
|
|
400
|
+
buildSearchParams(prompt, params = {}) {
|
|
401
|
+
const searchParams = new URLSearchParams();
|
|
402
|
+
const { query = {}, config = {} } = params;
|
|
403
|
+
const combinedQuery = {
|
|
404
|
+
...DEFAULT_QUERY,
|
|
405
|
+
siteId: this.siteId,
|
|
406
|
+
...query
|
|
407
|
+
};
|
|
408
|
+
const combinedConfig = {
|
|
409
|
+
...DEFAULT_AI_CONFIG,
|
|
410
|
+
...config
|
|
411
|
+
};
|
|
412
|
+
const entriesQueryParameters = [
|
|
413
|
+
['searchLimit', 'limit'],
|
|
414
|
+
['searchOffset', 'offset'],
|
|
415
|
+
['site', 'siteId'],
|
|
416
|
+
['language', 'languageId'],
|
|
417
|
+
['contentType']
|
|
418
|
+
];
|
|
419
|
+
// Map SDK query parameters to backend parameter names
|
|
420
|
+
appendMappedParams(searchParams, combinedQuery, entriesQueryParameters);
|
|
421
|
+
// Map config parameters using the same key names
|
|
422
|
+
appendMappedParams(searchParams, combinedConfig, Object.keys(combinedConfig).map((key) => [key]));
|
|
423
|
+
// Add search-specific parameters
|
|
424
|
+
searchParams.append('indexName', __classPrivateFieldGet(this, _AISearch_indexName, "f"));
|
|
425
|
+
searchParams.append('query', prompt);
|
|
426
|
+
return searchParams;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
_AISearch_params = new WeakMap(), _AISearch_prompt = new WeakMap(), _AISearch_indexName = new WeakMap();
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Client for interacting with the DotCMS AI API.
|
|
433
|
+
* Provides methods to interact with AI features.
|
|
434
|
+
* @experimental This client is experimental and may be subject to change.
|
|
435
|
+
*/
|
|
436
|
+
class AIClient extends BaseApiClient {
|
|
437
|
+
/**
|
|
438
|
+
* Creates a new AIClient instance.
|
|
439
|
+
*
|
|
440
|
+
* @param {DotCMSClientConfig} config - Configuration options for the DotCMS client
|
|
441
|
+
* @param {DotRequestOptions} requestOptions - Options for fetch requests including authorization headers
|
|
442
|
+
* @param {DotHttpClient} httpClient - HTTP client for making requests
|
|
443
|
+
* @example
|
|
444
|
+
* ```typescript
|
|
445
|
+
* const aiClient = new AIClient(
|
|
446
|
+
* {
|
|
447
|
+
* dotcmsUrl: 'https://demo.dotcms.com',
|
|
448
|
+
* authToken: 'your-auth-token',
|
|
449
|
+
* siteId: 'demo.dotcms.com'
|
|
450
|
+
* },
|
|
451
|
+
* {
|
|
452
|
+
* headers: {
|
|
453
|
+
* Authorization: 'Bearer your-auth-token'
|
|
454
|
+
* }
|
|
455
|
+
* },
|
|
456
|
+
* httpClient
|
|
457
|
+
* );
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
460
|
+
constructor(config, requestOptions, httpClient) {
|
|
461
|
+
super(config, requestOptions, httpClient);
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Performs an AI-powered search.
|
|
465
|
+
*
|
|
466
|
+
* @param params - Search parameters with query and AI configuration
|
|
467
|
+
* @returns Promise with search results
|
|
468
|
+
* @experimental This method is experimental and may be subject to change.
|
|
469
|
+
* @template T - The type of the contentlet.
|
|
470
|
+
* @param prompt - The prompt for the search.
|
|
471
|
+
* @param indexName - The name of the index you want to search in.
|
|
472
|
+
* @param params - Search parameters with query and AI configuration.
|
|
473
|
+
* @example
|
|
474
|
+
* @example
|
|
475
|
+
* ```typescript
|
|
476
|
+
* const response = await client.ai.search('machine learning articles', 'content_index', {
|
|
477
|
+
* query: {
|
|
478
|
+
* limit: 20,
|
|
479
|
+
* contentType: 'BlogPost',
|
|
480
|
+
* languageId: "1" // or 1
|
|
481
|
+
* },
|
|
482
|
+
* config: {
|
|
483
|
+
* threshold: 0.7
|
|
484
|
+
* }
|
|
485
|
+
* });
|
|
486
|
+
* ```
|
|
487
|
+
* @example
|
|
488
|
+
* ```typescript
|
|
489
|
+
* client.ai.search('machine learning articles', 'content_index', {
|
|
490
|
+
* query: {
|
|
491
|
+
* limit: 20,
|
|
492
|
+
* contentType: 'BlogPost',
|
|
493
|
+
* languageId: "1" // or 1
|
|
494
|
+
* },
|
|
495
|
+
* config: {
|
|
496
|
+
* threshold: 0.7,
|
|
497
|
+
* distanceFunction: DISTANCE_FUNCTIONS.cosine
|
|
498
|
+
* }
|
|
499
|
+
* }).then((response) => {
|
|
500
|
+
* console.log(response.results);
|
|
501
|
+
* }).catch((error) => {
|
|
502
|
+
* console.error(error);
|
|
503
|
+
* });
|
|
504
|
+
*/
|
|
505
|
+
search(prompt, indexName, params = {}) {
|
|
506
|
+
return new AISearch(this.config, this.requestOptions, this.httpClient, prompt, indexName, params);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
150
510
|
/**
|
|
151
511
|
* Default variant identifier used in the application.
|
|
152
512
|
*/
|
|
@@ -186,7 +546,9 @@ const CONTENT_API_URL = '/api/content/_search';
|
|
|
186
546
|
* @returns {string} The sanitized query string.
|
|
187
547
|
*/
|
|
188
548
|
function sanitizeQueryForContentType(query, contentType) {
|
|
189
|
-
|
|
549
|
+
// Match field names that start with letter/underscore, followed by alphanumeric/underscore/dot
|
|
550
|
+
// This excludes Lucene grouping operators like +(...)
|
|
551
|
+
return query.replace(/\+([a-zA-Z_][a-zA-Z0-9_.]*):/g, (original, field) => {
|
|
190
552
|
return !CONTENT_TYPE_MAIN_FIELDS.includes(field) // Fields that are not content type fields
|
|
191
553
|
? `+${contentType}.${field}:` // Should have this format: +contentTypeVar.field:
|
|
192
554
|
: original; // Return the field if it is a content type field
|
|
@@ -746,7 +1108,7 @@ class QueryBuilder {
|
|
|
746
1108
|
}
|
|
747
1109
|
_QueryBuilder_query = new WeakMap();
|
|
748
1110
|
|
|
749
|
-
var _CollectionBuilder_page, _CollectionBuilder_limit, _CollectionBuilder_depth, _CollectionBuilder_render, _CollectionBuilder_sortBy, _CollectionBuilder_contentType, _CollectionBuilder_defaultQuery, _CollectionBuilder_query, _CollectionBuilder_rawQuery, _CollectionBuilder_languageId, _CollectionBuilder_draft
|
|
1111
|
+
var _CollectionBuilder_page, _CollectionBuilder_limit, _CollectionBuilder_depth, _CollectionBuilder_render, _CollectionBuilder_sortBy, _CollectionBuilder_contentType, _CollectionBuilder_defaultQuery, _CollectionBuilder_query, _CollectionBuilder_rawQuery, _CollectionBuilder_languageId, _CollectionBuilder_draft;
|
|
750
1112
|
/**
|
|
751
1113
|
* Creates a Builder to filter and fetch content from the content API for a specific content type.
|
|
752
1114
|
*
|
|
@@ -754,7 +1116,7 @@ var _CollectionBuilder_page, _CollectionBuilder_limit, _CollectionBuilder_depth,
|
|
|
754
1116
|
* @class CollectionBuilder
|
|
755
1117
|
* @template T Represents the type of the content type to fetch. Defaults to unknown.
|
|
756
1118
|
*/
|
|
757
|
-
class CollectionBuilder {
|
|
1119
|
+
class CollectionBuilder extends BaseApiClient {
|
|
758
1120
|
/**
|
|
759
1121
|
* Creates an instance of CollectionBuilder.
|
|
760
1122
|
* @param {ClientOptions} requestOptions Options for the client request.
|
|
@@ -764,6 +1126,7 @@ class CollectionBuilder {
|
|
|
764
1126
|
* @memberof CollectionBuilder
|
|
765
1127
|
*/
|
|
766
1128
|
constructor(requestOptions, config, contentType, httpClient) {
|
|
1129
|
+
super(config, requestOptions, httpClient);
|
|
767
1130
|
_CollectionBuilder_page.set(this, 1);
|
|
768
1131
|
_CollectionBuilder_limit.set(this, 10);
|
|
769
1132
|
_CollectionBuilder_depth.set(this, 0);
|
|
@@ -775,14 +1138,7 @@ class CollectionBuilder {
|
|
|
775
1138
|
_CollectionBuilder_rawQuery.set(this, void 0);
|
|
776
1139
|
_CollectionBuilder_languageId.set(this, 1);
|
|
777
1140
|
_CollectionBuilder_draft.set(this, false);
|
|
778
|
-
_CollectionBuilder_requestOptions.set(this, void 0);
|
|
779
|
-
_CollectionBuilder_httpClient.set(this, void 0);
|
|
780
|
-
_CollectionBuilder_config.set(this, void 0);
|
|
781
|
-
__classPrivateFieldSet(this, _CollectionBuilder_requestOptions, requestOptions, "f");
|
|
782
|
-
__classPrivateFieldSet(this, _CollectionBuilder_config, config, "f");
|
|
783
1141
|
__classPrivateFieldSet(this, _CollectionBuilder_contentType, contentType, "f");
|
|
784
|
-
__classPrivateFieldSet(this, _CollectionBuilder_httpClient, httpClient, "f");
|
|
785
|
-
__classPrivateFieldSet(this, _CollectionBuilder_config, config, "f");
|
|
786
1142
|
// Build the default query with the contentType field
|
|
787
1143
|
__classPrivateFieldSet(this, _CollectionBuilder_defaultQuery, new QueryBuilder().field('contentType').equals(__classPrivateFieldGet(this, _CollectionBuilder_contentType, "f")), "f");
|
|
788
1144
|
}
|
|
@@ -814,17 +1170,7 @@ class CollectionBuilder {
|
|
|
814
1170
|
* @memberof CollectionBuilder
|
|
815
1171
|
*/
|
|
816
1172
|
get url() {
|
|
817
|
-
return `${
|
|
818
|
-
}
|
|
819
|
-
/**
|
|
820
|
-
* Returns the site ID from the configuration.
|
|
821
|
-
*
|
|
822
|
-
* @readonly
|
|
823
|
-
* @private
|
|
824
|
-
* @memberof CollectionBuilder
|
|
825
|
-
*/
|
|
826
|
-
get siteId() {
|
|
827
|
-
return __classPrivateFieldGet(this, _CollectionBuilder_config, "f").siteId;
|
|
1173
|
+
return `${this.config.dotcmsUrl}${CONTENT_API_URL}`;
|
|
828
1174
|
}
|
|
829
1175
|
/**
|
|
830
1176
|
* Returns the current query built.
|
|
@@ -1076,11 +1422,11 @@ class CollectionBuilder {
|
|
|
1076
1422
|
const finalQuery = this.getFinalQuery();
|
|
1077
1423
|
const sanitizedQuery = sanitizeQueryForContentType(finalQuery, __classPrivateFieldGet(this, _CollectionBuilder_contentType, "f"));
|
|
1078
1424
|
const query = __classPrivateFieldGet(this, _CollectionBuilder_rawQuery, "f") ? `${sanitizedQuery} ${__classPrivateFieldGet(this, _CollectionBuilder_rawQuery, "f")}` : sanitizedQuery;
|
|
1079
|
-
return
|
|
1080
|
-
...
|
|
1425
|
+
return this.httpClient.request(this.url, {
|
|
1426
|
+
...this.requestOptions,
|
|
1081
1427
|
method: 'POST',
|
|
1082
1428
|
headers: {
|
|
1083
|
-
...
|
|
1429
|
+
...this.requestOptions.headers,
|
|
1084
1430
|
'Content-Type': 'application/json'
|
|
1085
1431
|
},
|
|
1086
1432
|
body: JSON.stringify({
|
|
@@ -1118,7 +1464,7 @@ class CollectionBuilder {
|
|
|
1118
1464
|
*
|
|
1119
1465
|
* @example
|
|
1120
1466
|
* // For draft content without site constraint:
|
|
1121
|
-
* // Returns: "+contentType:Blog +languageId:1 +live:false"
|
|
1467
|
+
* // Returns: "+contentType:Blog +languageId:1 +(live:false AND working:true AND deleted:false)"
|
|
1122
1468
|
*
|
|
1123
1469
|
* @example
|
|
1124
1470
|
* // For content with explicit exclusion of current site (site ID 123):
|
|
@@ -1132,25 +1478,26 @@ class CollectionBuilder {
|
|
|
1132
1478
|
*/
|
|
1133
1479
|
getFinalQuery() {
|
|
1134
1480
|
// Build base query with language and live/draft constraints
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
.
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
.
|
|
1481
|
+
let baseQuery = this.currentQuery.field('languageId').equals(__classPrivateFieldGet(this, _CollectionBuilder_languageId, "f").toString());
|
|
1482
|
+
if (__classPrivateFieldGet(this, _CollectionBuilder_draft, "f")) {
|
|
1483
|
+
baseQuery = baseQuery.raw('+(live:false AND working:true AND deleted:false)');
|
|
1484
|
+
}
|
|
1485
|
+
else {
|
|
1486
|
+
baseQuery = baseQuery.field('live').equals('true');
|
|
1487
|
+
}
|
|
1488
|
+
const builtQuery = baseQuery.build();
|
|
1141
1489
|
// Check if site ID constraint should be added using utility function
|
|
1142
|
-
const shouldAddSiteId = shouldAddSiteIdConstraint(
|
|
1490
|
+
const shouldAddSiteId = shouldAddSiteIdConstraint(builtQuery, this.siteId);
|
|
1143
1491
|
// Add site ID constraint if needed
|
|
1144
1492
|
if (shouldAddSiteId) {
|
|
1145
|
-
const queryWithSiteId = `${
|
|
1493
|
+
const queryWithSiteId = `${builtQuery} +conhost:${this.siteId}`;
|
|
1146
1494
|
return sanitizeQuery(queryWithSiteId);
|
|
1147
1495
|
}
|
|
1148
|
-
return
|
|
1496
|
+
return builtQuery;
|
|
1149
1497
|
}
|
|
1150
1498
|
}
|
|
1151
|
-
_CollectionBuilder_page = new WeakMap(), _CollectionBuilder_limit = new WeakMap(), _CollectionBuilder_depth = new WeakMap(), _CollectionBuilder_render = new WeakMap(), _CollectionBuilder_sortBy = new WeakMap(), _CollectionBuilder_contentType = new WeakMap(), _CollectionBuilder_defaultQuery = new WeakMap(), _CollectionBuilder_query = new WeakMap(), _CollectionBuilder_rawQuery = new WeakMap(), _CollectionBuilder_languageId = new WeakMap(), _CollectionBuilder_draft = new WeakMap()
|
|
1499
|
+
_CollectionBuilder_page = new WeakMap(), _CollectionBuilder_limit = new WeakMap(), _CollectionBuilder_depth = new WeakMap(), _CollectionBuilder_render = new WeakMap(), _CollectionBuilder_sortBy = new WeakMap(), _CollectionBuilder_contentType = new WeakMap(), _CollectionBuilder_defaultQuery = new WeakMap(), _CollectionBuilder_query = new WeakMap(), _CollectionBuilder_rawQuery = new WeakMap(), _CollectionBuilder_languageId = new WeakMap(), _CollectionBuilder_draft = new WeakMap();
|
|
1152
1500
|
|
|
1153
|
-
var _Content_requestOptions, _Content_httpClient, _Content_config;
|
|
1154
1501
|
/**
|
|
1155
1502
|
* Creates a builder to filter and fetch a collection of content items.
|
|
1156
1503
|
* @param contentType - The content type to retrieve.
|
|
@@ -1200,20 +1547,15 @@ var _Content_requestOptions, _Content_httpClient, _Content_config;
|
|
|
1200
1547
|
* });
|
|
1201
1548
|
* ```
|
|
1202
1549
|
*/
|
|
1203
|
-
class Content {
|
|
1550
|
+
class Content extends BaseApiClient {
|
|
1204
1551
|
/**
|
|
1205
1552
|
* Creates an instance of Content.
|
|
1553
|
+
* @param {DotCMSClientConfig} config - Configuration options for the DotCMS client
|
|
1206
1554
|
* @param {DotRequestOptions} requestOptions - The options for the client request.
|
|
1207
|
-
* @param {string} serverUrl - The server URL.
|
|
1208
1555
|
* @param {DotHttpClient} httpClient - HTTP client for making requests.
|
|
1209
1556
|
*/
|
|
1210
1557
|
constructor(config, requestOptions, httpClient) {
|
|
1211
|
-
|
|
1212
|
-
_Content_httpClient.set(this, void 0);
|
|
1213
|
-
_Content_config.set(this, void 0);
|
|
1214
|
-
__classPrivateFieldSet(this, _Content_requestOptions, requestOptions, "f");
|
|
1215
|
-
__classPrivateFieldSet(this, _Content_config, config, "f");
|
|
1216
|
-
__classPrivateFieldSet(this, _Content_httpClient, httpClient, "f");
|
|
1558
|
+
super(config, requestOptions, httpClient);
|
|
1217
1559
|
}
|
|
1218
1560
|
/**
|
|
1219
1561
|
* Takes a content type and returns a builder to filter and fetch the collection.
|
|
@@ -1281,16 +1623,20 @@ class Content {
|
|
|
1281
1623
|
*
|
|
1282
1624
|
*/
|
|
1283
1625
|
getCollection(contentType) {
|
|
1284
|
-
return new CollectionBuilder(
|
|
1626
|
+
return new CollectionBuilder(this.requestOptions, this.config, contentType, this.httpClient);
|
|
1285
1627
|
}
|
|
1286
1628
|
}
|
|
1287
|
-
_Content_requestOptions = new WeakMap(), _Content_httpClient = new WeakMap(), _Content_config = new WeakMap();
|
|
1288
1629
|
|
|
1289
|
-
class NavigationClient {
|
|
1630
|
+
class NavigationClient extends BaseApiClient {
|
|
1631
|
+
/**
|
|
1632
|
+
* Creates a new NavigationClient instance.
|
|
1633
|
+
* @param {DotCMSClientConfig} config - Configuration options for the DotCMS client
|
|
1634
|
+
* @param {DotRequestOptions} requestOptions - Options for fetch requests including authorization headers
|
|
1635
|
+
* @param {DotHttpClient} httpClient - HTTP client for making requests
|
|
1636
|
+
*/
|
|
1290
1637
|
constructor(config, requestOptions, httpClient) {
|
|
1291
|
-
|
|
1638
|
+
super(config, requestOptions, httpClient);
|
|
1292
1639
|
this.BASE_URL = `${config?.dotcmsUrl}/api/v1/nav`;
|
|
1293
|
-
this.httpClient = httpClient;
|
|
1294
1640
|
}
|
|
1295
1641
|
/**
|
|
1296
1642
|
* Retrieves information about the dotCMS file and folder tree.
|
|
@@ -1420,6 +1766,8 @@ const buildPageQuery = ({ page, fragments, additionalQueries }) => {
|
|
|
1420
1766
|
canLock
|
|
1421
1767
|
canRead
|
|
1422
1768
|
runningExperimentId
|
|
1769
|
+
lockedBy
|
|
1770
|
+
lockedByName
|
|
1423
1771
|
urlContentMap {
|
|
1424
1772
|
_map
|
|
1425
1773
|
}
|
|
@@ -1485,6 +1833,7 @@ const buildPageQuery = ({ page, fragments, additionalQueries }) => {
|
|
|
1485
1833
|
}
|
|
1486
1834
|
}
|
|
1487
1835
|
viewAs {
|
|
1836
|
+
variantId
|
|
1488
1837
|
visitor {
|
|
1489
1838
|
persona {
|
|
1490
1839
|
modDate
|
|
@@ -1587,7 +1936,7 @@ async function fetchGraphQL({ baseURL, body, headers, httpClient }) {
|
|
|
1587
1936
|
* Client for interacting with the DotCMS Page API.
|
|
1588
1937
|
* Provides methods to retrieve and manipulate pages.
|
|
1589
1938
|
*/
|
|
1590
|
-
class PageClient {
|
|
1939
|
+
class PageClient extends BaseApiClient {
|
|
1591
1940
|
/**
|
|
1592
1941
|
* Creates a new PageClient instance.
|
|
1593
1942
|
*
|
|
@@ -1612,10 +1961,7 @@ class PageClient {
|
|
|
1612
1961
|
* ```
|
|
1613
1962
|
*/
|
|
1614
1963
|
constructor(config, requestOptions, httpClient) {
|
|
1615
|
-
|
|
1616
|
-
this.siteId = config.siteId || '';
|
|
1617
|
-
this.dotcmsUrl = config.dotcmsUrl;
|
|
1618
|
-
this.httpClient = httpClient;
|
|
1964
|
+
super(config, requestOptions, httpClient);
|
|
1619
1965
|
}
|
|
1620
1966
|
/**
|
|
1621
1967
|
* Retrieves a page from DotCMS using GraphQL.
|
|
@@ -1703,12 +2049,25 @@ class PageClient {
|
|
|
1703
2049
|
response.errors.forEach((error) => {
|
|
1704
2050
|
consola.consola.error('[DotCMS GraphQL Error]: ', error.message);
|
|
1705
2051
|
});
|
|
2052
|
+
const pageError = response.errors.find((error) => error.message.includes('DotPage'));
|
|
2053
|
+
if (pageError) {
|
|
2054
|
+
// Throw HTTP error - will be caught and wrapped in DotErrorPage below
|
|
2055
|
+
throw new types.DotHttpError({
|
|
2056
|
+
status: 400,
|
|
2057
|
+
statusText: 'Bad Request',
|
|
2058
|
+
message: `GraphQL query failed for URL '${url}': ${pageError.message}`,
|
|
2059
|
+
data: response.errors
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
1706
2062
|
}
|
|
1707
2063
|
const pageResponse = internal.graphqlToPageEntity(response.data.page);
|
|
1708
2064
|
if (!pageResponse) {
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
2065
|
+
// Throw HTTP error - will be caught and wrapped in DotErrorPage below
|
|
2066
|
+
throw new types.DotHttpError({
|
|
2067
|
+
status: 404,
|
|
2068
|
+
statusText: 'Not Found',
|
|
2069
|
+
message: `Page ${url} not found. Check the page URL and permissions.`,
|
|
2070
|
+
data: response.errors
|
|
1712
2071
|
});
|
|
1713
2072
|
}
|
|
1714
2073
|
const contentResponse = mapContentResponse(response.data, Object.keys(content));
|
|
@@ -1722,7 +2081,7 @@ class PageClient {
|
|
|
1722
2081
|
};
|
|
1723
2082
|
}
|
|
1724
2083
|
catch (error) {
|
|
1725
|
-
// Handle DotHttpError instances
|
|
2084
|
+
// Handle DotHttpError instances
|
|
1726
2085
|
if (error instanceof types.DotHttpError) {
|
|
1727
2086
|
throw new types.DotErrorPage(`Page request failed for URL '${url}': ${error.message}`, error, {
|
|
1728
2087
|
query: completeQuery,
|
|
@@ -1780,6 +2139,7 @@ class DotCMSClient {
|
|
|
1780
2139
|
this.page = new PageClient(this.config, this.requestOptions, this.httpClient);
|
|
1781
2140
|
this.nav = new NavigationClient(this.config, this.requestOptions, this.httpClient);
|
|
1782
2141
|
this.content = new Content(this.config, this.requestOptions, this.httpClient);
|
|
2142
|
+
this.ai = new AIClient(this.config, this.requestOptions, this.httpClient);
|
|
1783
2143
|
}
|
|
1784
2144
|
/**
|
|
1785
2145
|
* Creates request options with authentication headers.
|