@datocms/cma-client 5.1.13 → 5.1.14
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 +94 -40
- package/dist/cjs/generated/Client.js +1 -1
- package/dist/cjs/utilities/schemaRepository.js +107 -0
- package/dist/cjs/utilities/schemaRepository.js.map +1 -1
- package/dist/esm/generated/Client.js +1 -1
- package/dist/esm/utilities/schemaRepository.d.ts +40 -0
- package/dist/esm/utilities/schemaRepository.js +107 -0
- package/dist/esm/utilities/schemaRepository.js.map +1 -1
- package/dist/types/utilities/schemaRepository.d.ts +40 -0
- package/package.json +2 -2
- package/src/generated/Client.ts +1 -1
- package/src/utilities/schemaRepository.ts +141 -0
package/README.md
CHANGED
|
@@ -18,26 +18,30 @@ Every field type follows a consistent pattern providing:
|
|
|
18
18
|
|
|
19
19
|
**Example: `lat_lon` Field Type**
|
|
20
20
|
|
|
21
|
+
<details>
|
|
22
|
+
<summary>View example</summary>
|
|
23
|
+
|
|
21
24
|
```typescript
|
|
22
|
-
import {
|
|
23
|
-
import type { LatLonFieldValidators, LatLonFieldAppearance } from '@datocms/cma-client';
|
|
25
|
+
import { isLatLonFieldValue, isLocalizedLatLonFieldValue } from '@datocms/cma-client';
|
|
26
|
+
import type { LatLonFieldValue, LatLonFieldValidators, LatLonFieldAppearance } from '@datocms/cma-client';
|
|
24
27
|
|
|
25
|
-
// Field value type -
|
|
26
|
-
const value: LatLonFieldValue =
|
|
28
|
+
// Field value type - object with latitude/longitude or null
|
|
29
|
+
const value: LatLonFieldValue = { latitude: 45.4642, longitude: 9.1900 };
|
|
27
30
|
|
|
28
31
|
// Type guard functions for validation
|
|
29
32
|
if (isLatLonFieldValue(someValue)) {
|
|
30
|
-
// someValue is guaranteed to be
|
|
33
|
+
// someValue is guaranteed to be { latitude: number; longitude: number } | null
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
if (isLocalizedLatLonFieldValue(localizedValue)) {
|
|
34
|
-
// localizedValue is a localized
|
|
37
|
+
// localizedValue is a localized lat/lon field
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
// Validator and appearance types available for type-safe configuration
|
|
38
41
|
type Validators = LatLonFieldValidators;
|
|
39
42
|
type Appearance = LatLonFieldAppearance;
|
|
40
43
|
```
|
|
44
|
+
</details>
|
|
41
45
|
|
|
42
46
|
### Context-Dependent field types
|
|
43
47
|
|
|
@@ -47,6 +51,9 @@ Some field types have different value formats depending on the API context (requ
|
|
|
47
51
|
|
|
48
52
|
**File and Gallery fields** have different type requirements for API requests versus responses:
|
|
49
53
|
|
|
54
|
+
<details>
|
|
55
|
+
<summary>View example</summary>
|
|
56
|
+
|
|
50
57
|
```typescript
|
|
51
58
|
import {
|
|
52
59
|
FileFieldValue,
|
|
@@ -84,11 +91,15 @@ if (isGalleryFieldValue(someGalleryValue)) {
|
|
|
84
91
|
// someGalleryValue is array of files with all metadata present
|
|
85
92
|
}
|
|
86
93
|
```
|
|
94
|
+
</details>
|
|
87
95
|
|
|
88
96
|
#### "Nested Mode" Response variations
|
|
89
97
|
|
|
90
98
|
**Block-containing fields** (`structured_text`, `single_block`, `rich_text`) support different block representations for regular responses, for ["Nested Mode" responses](https://www.datocms.com/docs/content-management-api/resources/item#api-response-modes-regular-vs-nested), and for requests:
|
|
91
99
|
|
|
100
|
+
<details>
|
|
101
|
+
<summary>View example</summary>
|
|
102
|
+
|
|
92
103
|
```typescript
|
|
93
104
|
import {
|
|
94
105
|
StructuredTextFieldValue,
|
|
@@ -165,11 +176,15 @@ if (isStructuredTextFieldValueInRequest(requestData)) {
|
|
|
165
176
|
// requestData allows flexible block representations
|
|
166
177
|
}
|
|
167
178
|
```
|
|
179
|
+
</details>
|
|
168
180
|
|
|
169
181
|
These variants ensure type safety across different API contexts while maintaining the same conceptual data structure. All localized variants also have corresponding type guards (e.g., `isLocalizedStructuredTextFieldValueInRequest`, `isLocalizedStructuredTextFieldValueInNestedResponse`, etc.).
|
|
170
182
|
|
|
171
183
|
**TypeScript Generics Support:** For maximum type safety, all field value types and type guards for block-containing fields accept [`ItemTypeDefinition` generics](https://www.datocms.com/docs/content-management-api/resources/item#type-safe-development-with-typescript) to provide precise typing for your specific schema:
|
|
172
184
|
|
|
185
|
+
<details>
|
|
186
|
+
<summary>View example</summary>
|
|
187
|
+
|
|
173
188
|
```typescript
|
|
174
189
|
import type { MyArticle, MyArticleSection } from './schema';
|
|
175
190
|
|
|
@@ -186,6 +201,7 @@ if (isStructuredTextFieldValueInNestedResponse<MyArticleSection>(value)) {
|
|
|
186
201
|
// value is now typed with your specific block schema
|
|
187
202
|
}
|
|
188
203
|
```
|
|
204
|
+
</details>
|
|
189
205
|
|
|
190
206
|
## Block Processing Utilities
|
|
191
207
|
|
|
@@ -193,11 +209,13 @@ if (isStructuredTextFieldValueInNestedResponse<MyArticleSection>(value)) {
|
|
|
193
209
|
|
|
194
210
|
The `inspectItem()` function provides a visual, tree-structured representation of DatoCMS records in the console, making it easier to debug and understand complex content structures.
|
|
195
211
|
|
|
196
|
-
|
|
197
|
-
<summary><strong>inspectItem()</strong> - Display records with visual appeal</summary>
|
|
212
|
+
#### inspectItem()
|
|
198
213
|
|
|
199
214
|
Formats a DatoCMS item (record or block) as a visual tree structure, showing all fields with proper formatting for each field type. Particularly useful for debugging nested structures like modular content and structured text.
|
|
200
215
|
|
|
216
|
+
<details>
|
|
217
|
+
<summary>View details</summary>
|
|
218
|
+
|
|
201
219
|
**TypeScript Signature:**
|
|
202
220
|
```typescript
|
|
203
221
|
function inspectItem(
|
|
@@ -236,11 +254,13 @@ console.log(inspectItem(record));
|
|
|
236
254
|
|
|
237
255
|
### Creating and Duplicating Blocks
|
|
238
256
|
|
|
239
|
-
|
|
240
|
-
<summary><strong>buildBlockRecord()</strong> - Create block records from data</summary>
|
|
257
|
+
#### buildBlockRecord()
|
|
241
258
|
|
|
242
259
|
Converts a block data object into the proper format for API requests.
|
|
243
260
|
|
|
261
|
+
<details>
|
|
262
|
+
<summary>View details</summary>
|
|
263
|
+
|
|
244
264
|
**TypeScript Signature:**
|
|
245
265
|
```typescript
|
|
246
266
|
function buildBlockRecord<D extends ItemTypeDefinition>(
|
|
@@ -254,11 +274,13 @@ function buildBlockRecord<D extends ItemTypeDefinition>(
|
|
|
254
274
|
**Returns:** Formatted block record ready for API requests
|
|
255
275
|
</details>
|
|
256
276
|
|
|
257
|
-
|
|
258
|
-
<summary><strong>duplicateBlockRecord()</strong> - Deep clone blocks with nested content</summary>
|
|
277
|
+
#### duplicateBlockRecord()
|
|
259
278
|
|
|
260
279
|
Creates a deep copy of a block record, including all nested blocks, removing IDs to create new instances.
|
|
261
280
|
|
|
281
|
+
<details>
|
|
282
|
+
<summary>View details</summary>
|
|
283
|
+
|
|
262
284
|
**TypeScript Signature:**
|
|
263
285
|
```typescript
|
|
264
286
|
async function duplicateBlockRecord<D extends ItemTypeDefinition>(
|
|
@@ -278,11 +300,13 @@ async function duplicateBlockRecord<D extends ItemTypeDefinition>(
|
|
|
278
300
|
|
|
279
301
|
DatoCMS supports three field types that can contain blocks: Modular Content (arrays of blocks), Single Block fields, and Structured Text (rich-text with embedded blocks). These functions abstract away the differences between field types and can traverse blocks recursively, processing nested blocks within blocks. They require a `SchemaRepository` instance to look up field definitions for nested blocks.
|
|
280
302
|
|
|
281
|
-
|
|
282
|
-
<summary><strong>visitBlocksInNonLocalizedFieldValue()</strong> - Recursively visit all blocks</summary>
|
|
303
|
+
#### visitBlocksInNonLocalizedFieldValue()
|
|
283
304
|
|
|
284
305
|
Visit every block in a non-localized field value recursively, including blocks nested within other blocks.
|
|
285
306
|
|
|
307
|
+
<details>
|
|
308
|
+
<summary>View details</summary>
|
|
309
|
+
|
|
286
310
|
**TypeScript Signature:**
|
|
287
311
|
```typescript
|
|
288
312
|
async function visitBlocksInNonLocalizedFieldValue(
|
|
@@ -300,11 +324,13 @@ async function visitBlocksInNonLocalizedFieldValue(
|
|
|
300
324
|
- `visitor`: Function called for each block (including nested)
|
|
301
325
|
</details>
|
|
302
326
|
|
|
303
|
-
|
|
304
|
-
<summary><strong>mapBlocksInNonLocalizedFieldValue()</strong> - Recursively transform all blocks</summary>
|
|
327
|
+
#### mapBlocksInNonLocalizedFieldValue()
|
|
305
328
|
|
|
306
329
|
Transform all blocks in a non-localized field value recursively, including nested blocks.
|
|
307
330
|
|
|
331
|
+
<details>
|
|
332
|
+
<summary>View details</summary>
|
|
333
|
+
|
|
308
334
|
**TypeScript Signature:**
|
|
309
335
|
```typescript
|
|
310
336
|
async function mapBlocksInNonLocalizedFieldValue(
|
|
@@ -324,11 +350,13 @@ async function mapBlocksInNonLocalizedFieldValue(
|
|
|
324
350
|
**Returns:** New field value
|
|
325
351
|
</details>
|
|
326
352
|
|
|
327
|
-
|
|
328
|
-
<summary><strong>filterBlocksInNonLocalizedFieldValue()</strong> - Recursively filter blocks</summary>
|
|
353
|
+
#### filterBlocksInNonLocalizedFieldValue()
|
|
329
354
|
|
|
330
355
|
Filter blocks recursively, removing blocks at any nesting level that don't match the predicate.
|
|
331
356
|
|
|
357
|
+
<details>
|
|
358
|
+
<summary>View details</summary>
|
|
359
|
+
|
|
332
360
|
**TypeScript Signature:**
|
|
333
361
|
```typescript
|
|
334
362
|
async function filterBlocksInNonLocalizedFieldValue(
|
|
@@ -359,11 +387,13 @@ const noVideos = await filterBlocksInNonLocalizedFieldValue(
|
|
|
359
387
|
```
|
|
360
388
|
</details>
|
|
361
389
|
|
|
362
|
-
|
|
363
|
-
<summary><strong>findAllBlocksInNonLocalizedFieldValue()</strong> - Recursively search for blocks</summary>
|
|
390
|
+
#### findAllBlocksInNonLocalizedFieldValue()
|
|
364
391
|
|
|
365
392
|
Find all blocks that match the predicate, searching recursively through nested blocks.
|
|
366
393
|
|
|
394
|
+
<details>
|
|
395
|
+
<summary>View details</summary>
|
|
396
|
+
|
|
367
397
|
**TypeScript Signature:**
|
|
368
398
|
```typescript
|
|
369
399
|
async function findAllBlocksInNonLocalizedFieldValue(
|
|
@@ -383,11 +413,13 @@ async function findAllBlocksInNonLocalizedFieldValue(
|
|
|
383
413
|
**Returns:** Array of all matching blocks with their paths
|
|
384
414
|
</details>
|
|
385
415
|
|
|
386
|
-
|
|
387
|
-
<summary><strong>reduceBlocksInNonLocalizedFieldValue()</strong> - Recursively reduce blocks</summary>
|
|
416
|
+
#### reduceBlocksInNonLocalizedFieldValue()
|
|
388
417
|
|
|
389
418
|
Reduce all blocks recursively to a single value.
|
|
390
419
|
|
|
420
|
+
<details>
|
|
421
|
+
<summary>View details</summary>
|
|
422
|
+
|
|
391
423
|
**TypeScript Signature:**
|
|
392
424
|
```typescript
|
|
393
425
|
async function reduceBlocksInNonLocalizedFieldValue<R>(
|
|
@@ -409,11 +441,13 @@ async function reduceBlocksInNonLocalizedFieldValue<R>(
|
|
|
409
441
|
**Returns:** The final accumulated value
|
|
410
442
|
</details>
|
|
411
443
|
|
|
412
|
-
|
|
413
|
-
<summary><strong>someBlocksInNonLocalizedFieldValue()</strong> - Recursively test for any match</summary>
|
|
444
|
+
#### someBlocksInNonLocalizedFieldValue()
|
|
414
445
|
|
|
415
446
|
Check if any block (including nested) matches the predicate.
|
|
416
447
|
|
|
448
|
+
<details>
|
|
449
|
+
<summary>View details</summary>
|
|
450
|
+
|
|
417
451
|
**TypeScript Signature:**
|
|
418
452
|
```typescript
|
|
419
453
|
async function someBlocksInNonLocalizedFieldValue(
|
|
@@ -433,11 +467,13 @@ async function someBlocksInNonLocalizedFieldValue(
|
|
|
433
467
|
**Returns:** True if any block matches
|
|
434
468
|
</details>
|
|
435
469
|
|
|
436
|
-
|
|
437
|
-
<summary><strong>everyBlockInNonLocalizedFieldValue()</strong> - Recursively test if all match</summary>
|
|
470
|
+
#### everyBlockInNonLocalizedFieldValue()
|
|
438
471
|
|
|
439
472
|
Check if every block (including nested) matches the predicate.
|
|
440
473
|
|
|
474
|
+
<details>
|
|
475
|
+
<summary>View details</summary>
|
|
476
|
+
|
|
441
477
|
**TypeScript Signature:**
|
|
442
478
|
```typescript
|
|
443
479
|
async function everyBlockInNonLocalizedFieldValue(
|
|
@@ -461,11 +497,13 @@ async function everyBlockInNonLocalizedFieldValue(
|
|
|
461
497
|
|
|
462
498
|
These utilities provide a unified interface for working with DatoCMS field values that may or may not be localized. They eliminate the need for conditional logic when processing fields that could be either localized or non-localized.
|
|
463
499
|
|
|
464
|
-
|
|
465
|
-
<summary><strong>mapNormalizedFieldValues() / mapNormalizedFieldValuesAsync()</strong> - Transform field values</summary>
|
|
500
|
+
#### mapNormalizedFieldValues() / mapNormalizedFieldValuesAsync()
|
|
466
501
|
|
|
467
502
|
Apply a transformation function to field values, handling both localized and non-localized fields uniformly.
|
|
468
503
|
|
|
504
|
+
<details>
|
|
505
|
+
<summary>View details</summary>
|
|
506
|
+
|
|
469
507
|
**TypeScript Signatures:**
|
|
470
508
|
```typescript
|
|
471
509
|
function mapNormalizedFieldValues<TInput, TOutput>(
|
|
@@ -489,11 +527,13 @@ async function mapNormalizedFieldValuesAsync<TInput, TOutput>(
|
|
|
489
527
|
**Returns:** Transformed value maintaining the same structure
|
|
490
528
|
</details>
|
|
491
529
|
|
|
492
|
-
|
|
493
|
-
<summary><strong>filterNormalizedFieldValues() / filterNormalizedFieldValuesAsync()</strong> - Filter field values</summary>
|
|
530
|
+
#### filterNormalizedFieldValues() / filterNormalizedFieldValuesAsync()
|
|
494
531
|
|
|
495
532
|
Filter field values based on a predicate, handling both localized and non-localized fields.
|
|
496
533
|
|
|
534
|
+
<details>
|
|
535
|
+
<summary>View details</summary>
|
|
536
|
+
|
|
497
537
|
**TypeScript Signatures:**
|
|
498
538
|
```typescript
|
|
499
539
|
function filterNormalizedFieldValues<T>(
|
|
@@ -517,11 +557,13 @@ async function filterNormalizedFieldValuesAsync<T>(
|
|
|
517
557
|
**Returns:** Filtered value or undefined if all filtered out
|
|
518
558
|
</details>
|
|
519
559
|
|
|
520
|
-
|
|
521
|
-
<summary><strong>visitNormalizedFieldValues() / visitNormalizedFieldValuesAsync()</strong> - Iterate over field values</summary>
|
|
560
|
+
#### visitNormalizedFieldValues() / visitNormalizedFieldValuesAsync()
|
|
522
561
|
|
|
523
562
|
Visit each value in a field, handling both localized and non-localized fields.
|
|
524
563
|
|
|
564
|
+
<details>
|
|
565
|
+
<summary>View details</summary>
|
|
566
|
+
|
|
525
567
|
**TypeScript Signatures:**
|
|
526
568
|
```typescript
|
|
527
569
|
function visitNormalizedFieldValues<T>(
|
|
@@ -543,11 +585,13 @@ async function visitNormalizedFieldValuesAsync<T>(
|
|
|
543
585
|
- `visitFn`: Function called for each value
|
|
544
586
|
</details>
|
|
545
587
|
|
|
546
|
-
|
|
547
|
-
<summary><strong>someNormalizedFieldValues() / someNormalizedFieldValuesAsync()</strong> - Test if any value matches</summary>
|
|
588
|
+
#### someNormalizedFieldValues() / someNormalizedFieldValuesAsync()
|
|
548
589
|
|
|
549
590
|
Check if at least one field value passes the test.
|
|
550
591
|
|
|
592
|
+
<details>
|
|
593
|
+
<summary>View details</summary>
|
|
594
|
+
|
|
551
595
|
**TypeScript Signatures:**
|
|
552
596
|
```typescript
|
|
553
597
|
function someNormalizedFieldValues<T>(
|
|
@@ -571,11 +615,13 @@ async function someNormalizedFieldValuesAsync<T>(
|
|
|
571
615
|
**Returns:** True if any value passes the test
|
|
572
616
|
</details>
|
|
573
617
|
|
|
574
|
-
|
|
575
|
-
<summary><strong>everyNormalizedFieldValue() / everyNormalizedFieldValueAsync()</strong> - Test if all values match</summary>
|
|
618
|
+
#### everyNormalizedFieldValue() / everyNormalizedFieldValueAsync()
|
|
576
619
|
|
|
577
620
|
Check if all field values pass the test.
|
|
578
621
|
|
|
622
|
+
<details>
|
|
623
|
+
<summary>View details</summary>
|
|
624
|
+
|
|
579
625
|
**TypeScript Signatures:**
|
|
580
626
|
```typescript
|
|
581
627
|
function everyNormalizedFieldValue<T>(
|
|
@@ -599,11 +645,13 @@ async function everyNormalizedFieldValueAsync<T>(
|
|
|
599
645
|
**Returns:** True if all values pass the test
|
|
600
646
|
</details>
|
|
601
647
|
|
|
602
|
-
|
|
603
|
-
<summary><strong>toNormalizedFieldValueEntries() / fromNormalizedFieldValueEntries()</strong> - Convert between formats</summary>
|
|
648
|
+
#### toNormalizedFieldValueEntries() / fromNormalizedFieldValueEntries()
|
|
604
649
|
|
|
605
650
|
Convert field values to/from a normalized entry format for uniform processing.
|
|
606
651
|
|
|
652
|
+
<details>
|
|
653
|
+
<summary>View details</summary>
|
|
654
|
+
|
|
607
655
|
**TypeScript Signatures:**
|
|
608
656
|
```typescript
|
|
609
657
|
function toNormalizedFieldValueEntries<T>(
|
|
@@ -641,9 +689,10 @@ const processed = entries.map(({ locale, value }) => ({
|
|
|
641
689
|
|
|
642
690
|
// Convert back to field value format
|
|
643
691
|
const result = fromNormalizedFieldValueEntries(field, processed);
|
|
692
|
+
```
|
|
644
693
|
</details>
|
|
645
694
|
|
|
646
|
-
|
|
695
|
+
## SchemaRepository
|
|
647
696
|
|
|
648
697
|
The `SchemaRepository` class provides a lightweight, in-memory cache for DatoCMS schema entities (item types, fields, fieldsets, and plugins). It helps avoid redundant API calls when working across multiple functions or utilities that require schema lookups.
|
|
649
698
|
|
|
@@ -655,6 +704,10 @@ The `SchemaRepository` class provides a lightweight, in-memory cache for DatoCMS
|
|
|
655
704
|
- **Fewer API calls**: Dramatically speeds up bulk operations and complex traversals.
|
|
656
705
|
|
|
657
706
|
**Usage Example:**
|
|
707
|
+
|
|
708
|
+
<details>
|
|
709
|
+
<summary>View example</summary>
|
|
710
|
+
|
|
658
711
|
```typescript
|
|
659
712
|
const schemaRepository = new SchemaRepository(client);
|
|
660
713
|
|
|
@@ -669,13 +722,14 @@ const sameFields = await schemaRepository.getItemTypeFields(blogPost);
|
|
|
669
722
|
// Works seamlessly with block-processing utilities
|
|
670
723
|
await mapBlocksInNonLocalizedFieldValue(
|
|
671
724
|
fieldValue,
|
|
672
|
-
|
|
725
|
+
fieldType,
|
|
673
726
|
schemaRepository, // share cached lookups
|
|
674
727
|
async (block) => {
|
|
675
728
|
// transform block here
|
|
676
729
|
}
|
|
677
730
|
);
|
|
678
731
|
```
|
|
732
|
+
</details>
|
|
679
733
|
|
|
680
734
|
**When to Use**
|
|
681
735
|
|
|
@@ -88,7 +88,7 @@ class Client {
|
|
|
88
88
|
return this.config.baseUrl || Client.defaultBaseUrl;
|
|
89
89
|
}
|
|
90
90
|
request(options) {
|
|
91
|
-
return (0, rest_client_utils_1.request)(Object.assign(Object.assign(Object.assign({}, this.config), options), { logFn: this.config.logFn || console.log, userAgent: '@datocms/cma-client v5.1.
|
|
91
|
+
return (0, rest_client_utils_1.request)(Object.assign(Object.assign(Object.assign({}, this.config), options), { logFn: this.config.logFn || console.log, userAgent: '@datocms/cma-client v5.1.14', baseUrl: this.baseUrl, preCallStack: new Error().stack, extraHeaders: Object.assign(Object.assign(Object.assign({}, (this.config.extraHeaders || {})), (this.config.environment
|
|
92
92
|
? { 'X-Environment': this.config.environment }
|
|
93
93
|
: {})), { 'X-API-Version': '3' }), fetchJobResult: (jobId) => {
|
|
94
94
|
return this.jobResultsFetcher
|
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.SchemaRepository = void 0;
|
|
13
13
|
const rest_client_utils_1 = require("@datocms/rest-client-utils");
|
|
14
|
+
const fieldsContainingReferences_1 = require("./fieldsContainingReferences");
|
|
14
15
|
/**
|
|
15
16
|
* Repository for DatoCMS schema entities including item types, fields, and plugins.
|
|
16
17
|
* Provides caching and efficient lookup functionality for schema-related operations.
|
|
@@ -413,6 +414,112 @@ class SchemaRepository {
|
|
|
413
414
|
return plugin;
|
|
414
415
|
});
|
|
415
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* Prefetches all models and their fields in a single optimized API call.
|
|
419
|
+
* This method populates the internal caches for both item types and fields,
|
|
420
|
+
* making subsequent lookups very fast without additional API calls.
|
|
421
|
+
*
|
|
422
|
+
* This is more efficient than lazy loading when you know you'll need access
|
|
423
|
+
* to multiple models and fields, as it reduces the number of API requests
|
|
424
|
+
* from potentially dozens down to just one.
|
|
425
|
+
*
|
|
426
|
+
* @returns Promise that resolves when all data has been fetched and cached
|
|
427
|
+
*/
|
|
428
|
+
prefetchAllModelsAndFields() {
|
|
429
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
430
|
+
const { included } = yield this.client.site.rawFind({
|
|
431
|
+
include: 'item_types,item_types.fields',
|
|
432
|
+
});
|
|
433
|
+
if (!included) {
|
|
434
|
+
throw new Error('This should not happen');
|
|
435
|
+
}
|
|
436
|
+
const allItemTypes = included.filter((item) => item.type === 'item_type');
|
|
437
|
+
const allFields = included.filter((item) => item.type === 'field');
|
|
438
|
+
// Populate item types caches
|
|
439
|
+
this.itemTypesPromise = Promise.resolve(allItemTypes);
|
|
440
|
+
for (const itemType of allItemTypes) {
|
|
441
|
+
this.itemTypesByApiKey.set(itemType.attributes.api_key, itemType);
|
|
442
|
+
this.itemTypesById.set(itemType.id, itemType);
|
|
443
|
+
}
|
|
444
|
+
// Group fields by item type and populate fields cache
|
|
445
|
+
const fieldsByItemTypeId = new Map();
|
|
446
|
+
for (const field of allFields) {
|
|
447
|
+
const itemTypeId = field.relationships.item_type.data.id;
|
|
448
|
+
if (!fieldsByItemTypeId.has(itemTypeId)) {
|
|
449
|
+
fieldsByItemTypeId.set(itemTypeId, []);
|
|
450
|
+
}
|
|
451
|
+
fieldsByItemTypeId.get(itemTypeId).push(field);
|
|
452
|
+
}
|
|
453
|
+
// Populate the fields cache
|
|
454
|
+
for (const [itemTypeId, fields] of fieldsByItemTypeId) {
|
|
455
|
+
this.fieldsByItemType.set(itemTypeId, fields);
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Gets all models that directly or indirectly embed the given block models.
|
|
461
|
+
* This method recursively traverses the schema to find all models that reference
|
|
462
|
+
* the provided blocks, either directly through block fields or indirectly through
|
|
463
|
+
* other block models that reference them.
|
|
464
|
+
*
|
|
465
|
+
* @param blocks - Array of block models to find references to
|
|
466
|
+
* @returns Promise that resolves to array of models that embed these blocks
|
|
467
|
+
*/
|
|
468
|
+
getRawModelsEmbeddingBlocks(blocks) {
|
|
469
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
470
|
+
yield this.prefetchAllModelsAndFields();
|
|
471
|
+
const allItemTypes = yield this.getAllRawItemTypes();
|
|
472
|
+
const blockIds = new Set(blocks.map((block) => block.id));
|
|
473
|
+
const embeddingModels = [];
|
|
474
|
+
// Helper function to check if a model points to any of the target blocks
|
|
475
|
+
const modelPointsToBlocks = (itemType, alreadyExplored = new Set()) => __awaiter(this, void 0, void 0, function* () {
|
|
476
|
+
if (alreadyExplored.has(itemType.id)) {
|
|
477
|
+
return false;
|
|
478
|
+
}
|
|
479
|
+
alreadyExplored.add(itemType.id);
|
|
480
|
+
const fields = yield this.getRawItemTypeFields(itemType);
|
|
481
|
+
for (const field of fields) {
|
|
482
|
+
const referencedBlockIds = (0, fieldsContainingReferences_1.blockModelIdsReferencedInField)(field);
|
|
483
|
+
// Check if this field directly references any of our target blocks
|
|
484
|
+
if (referencedBlockIds.some((id) => blockIds.has(id))) {
|
|
485
|
+
return true;
|
|
486
|
+
}
|
|
487
|
+
// Check if this field references other block models that might transitively reference our targets
|
|
488
|
+
const referencedBlocks = referencedBlockIds.map((id) => allItemTypes.find((it) => it.id === id));
|
|
489
|
+
for (const linkedBlock of referencedBlocks) {
|
|
490
|
+
if (yield modelPointsToBlocks(linkedBlock, new Set(alreadyExplored))) {
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return false;
|
|
496
|
+
});
|
|
497
|
+
// Check each model to see if it embeds any of the target blocks
|
|
498
|
+
for (const itemType of allItemTypes) {
|
|
499
|
+
if (yield modelPointsToBlocks(itemType)) {
|
|
500
|
+
embeddingModels.push(itemType);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
return embeddingModels;
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Gets all models that directly or indirectly embed the given block models.
|
|
508
|
+
* This method recursively traverses the schema to find all models that reference
|
|
509
|
+
* the provided blocks, either directly through block fields or indirectly through
|
|
510
|
+
* other block models that reference them.
|
|
511
|
+
*
|
|
512
|
+
* @param blocks - Array of block models to find references to
|
|
513
|
+
* @returns Promise that resolves to array of models that embed these blocks
|
|
514
|
+
*/
|
|
515
|
+
getModelsEmbeddingBlocks(blocks) {
|
|
516
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
517
|
+
const rawResult = yield this.getRawModelsEmbeddingBlocks(blocks);
|
|
518
|
+
return (0, rest_client_utils_1.deserializeResponseBody)({
|
|
519
|
+
data: rawResult,
|
|
520
|
+
});
|
|
521
|
+
});
|
|
522
|
+
}
|
|
416
523
|
}
|
|
417
524
|
exports.SchemaRepository = SchemaRepository;
|
|
418
525
|
//# sourceMappingURL=schemaRepository.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemaRepository.js","sourceRoot":"","sources":["../../../src/utilities/schemaRepository.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,kEAAqE;
|
|
1
|
+
{"version":3,"file":"schemaRepository.js","sourceRoot":"","sources":["../../../src/utilities/schemaRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -62,7 +62,7 @@ export class Client {
|
|
|
62
62
|
return this.config.baseUrl || Client.defaultBaseUrl;
|
|
63
63
|
}
|
|
64
64
|
request(options) {
|
|
65
|
-
return request(Object.assign(Object.assign(Object.assign({}, this.config), options), { logFn: this.config.logFn || console.log, userAgent: '@datocms/cma-client v5.1.
|
|
65
|
+
return request(Object.assign(Object.assign(Object.assign({}, this.config), options), { logFn: this.config.logFn || console.log, userAgent: '@datocms/cma-client v5.1.14', baseUrl: this.baseUrl, preCallStack: new Error().stack, extraHeaders: Object.assign(Object.assign(Object.assign({}, (this.config.extraHeaders || {})), (this.config.environment
|
|
66
66
|
? { 'X-Environment': this.config.environment }
|
|
67
67
|
: {})), { 'X-API-Version': '3' }), fetchJobResult: (jobId) => {
|
|
68
68
|
return this.jobResultsFetcher
|
|
@@ -24,6 +24,14 @@ interface GenericClient {
|
|
|
24
24
|
data: RawApiTypes.Plugin[];
|
|
25
25
|
}>;
|
|
26
26
|
};
|
|
27
|
+
site: {
|
|
28
|
+
rawFind(params: {
|
|
29
|
+
include: string;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
data: any;
|
|
32
|
+
included?: Array<RawApiTypes.ItemType | RawApiTypes.Field | any>;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
27
35
|
}
|
|
28
36
|
/**
|
|
29
37
|
* Repository for DatoCMS schema entities including item types, fields, and plugins.
|
|
@@ -244,5 +252,37 @@ export declare class SchemaRepository {
|
|
|
244
252
|
* @throws Error if the plugin is not found
|
|
245
253
|
*/
|
|
246
254
|
getRawPluginByPackageName(packageName: string): Promise<RawApiTypes.Plugin>;
|
|
255
|
+
/**
|
|
256
|
+
* Prefetches all models and their fields in a single optimized API call.
|
|
257
|
+
* This method populates the internal caches for both item types and fields,
|
|
258
|
+
* making subsequent lookups very fast without additional API calls.
|
|
259
|
+
*
|
|
260
|
+
* This is more efficient than lazy loading when you know you'll need access
|
|
261
|
+
* to multiple models and fields, as it reduces the number of API requests
|
|
262
|
+
* from potentially dozens down to just one.
|
|
263
|
+
*
|
|
264
|
+
* @returns Promise that resolves when all data has been fetched and cached
|
|
265
|
+
*/
|
|
266
|
+
prefetchAllModelsAndFields(): Promise<void>;
|
|
267
|
+
/**
|
|
268
|
+
* Gets all models that directly or indirectly embed the given block models.
|
|
269
|
+
* This method recursively traverses the schema to find all models that reference
|
|
270
|
+
* the provided blocks, either directly through block fields or indirectly through
|
|
271
|
+
* other block models that reference them.
|
|
272
|
+
*
|
|
273
|
+
* @param blocks - Array of block models to find references to
|
|
274
|
+
* @returns Promise that resolves to array of models that embed these blocks
|
|
275
|
+
*/
|
|
276
|
+
getRawModelsEmbeddingBlocks(blocks: Array<ApiTypes.ItemType | RawApiTypes.ItemType>): Promise<Array<RawApiTypes.ItemType>>;
|
|
277
|
+
/**
|
|
278
|
+
* Gets all models that directly or indirectly embed the given block models.
|
|
279
|
+
* This method recursively traverses the schema to find all models that reference
|
|
280
|
+
* the provided blocks, either directly through block fields or indirectly through
|
|
281
|
+
* other block models that reference them.
|
|
282
|
+
*
|
|
283
|
+
* @param blocks - Array of block models to find references to
|
|
284
|
+
* @returns Promise that resolves to array of models that embed these blocks
|
|
285
|
+
*/
|
|
286
|
+
getModelsEmbeddingBlocks(blocks: Array<ApiTypes.ItemType | RawApiTypes.ItemType>): Promise<Array<ApiTypes.ItemType>>;
|
|
247
287
|
}
|
|
248
288
|
export {};
|
|
@@ -8,6 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { deserializeResponseBody } from '@datocms/rest-client-utils';
|
|
11
|
+
import { blockModelIdsReferencedInField } from './fieldsContainingReferences';
|
|
11
12
|
/**
|
|
12
13
|
* Repository for DatoCMS schema entities including item types, fields, and plugins.
|
|
13
14
|
* Provides caching and efficient lookup functionality for schema-related operations.
|
|
@@ -410,5 +411,111 @@ export class SchemaRepository {
|
|
|
410
411
|
return plugin;
|
|
411
412
|
});
|
|
412
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Prefetches all models and their fields in a single optimized API call.
|
|
416
|
+
* This method populates the internal caches for both item types and fields,
|
|
417
|
+
* making subsequent lookups very fast without additional API calls.
|
|
418
|
+
*
|
|
419
|
+
* This is more efficient than lazy loading when you know you'll need access
|
|
420
|
+
* to multiple models and fields, as it reduces the number of API requests
|
|
421
|
+
* from potentially dozens down to just one.
|
|
422
|
+
*
|
|
423
|
+
* @returns Promise that resolves when all data has been fetched and cached
|
|
424
|
+
*/
|
|
425
|
+
prefetchAllModelsAndFields() {
|
|
426
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
427
|
+
const { included } = yield this.client.site.rawFind({
|
|
428
|
+
include: 'item_types,item_types.fields',
|
|
429
|
+
});
|
|
430
|
+
if (!included) {
|
|
431
|
+
throw new Error('This should not happen');
|
|
432
|
+
}
|
|
433
|
+
const allItemTypes = included.filter((item) => item.type === 'item_type');
|
|
434
|
+
const allFields = included.filter((item) => item.type === 'field');
|
|
435
|
+
// Populate item types caches
|
|
436
|
+
this.itemTypesPromise = Promise.resolve(allItemTypes);
|
|
437
|
+
for (const itemType of allItemTypes) {
|
|
438
|
+
this.itemTypesByApiKey.set(itemType.attributes.api_key, itemType);
|
|
439
|
+
this.itemTypesById.set(itemType.id, itemType);
|
|
440
|
+
}
|
|
441
|
+
// Group fields by item type and populate fields cache
|
|
442
|
+
const fieldsByItemTypeId = new Map();
|
|
443
|
+
for (const field of allFields) {
|
|
444
|
+
const itemTypeId = field.relationships.item_type.data.id;
|
|
445
|
+
if (!fieldsByItemTypeId.has(itemTypeId)) {
|
|
446
|
+
fieldsByItemTypeId.set(itemTypeId, []);
|
|
447
|
+
}
|
|
448
|
+
fieldsByItemTypeId.get(itemTypeId).push(field);
|
|
449
|
+
}
|
|
450
|
+
// Populate the fields cache
|
|
451
|
+
for (const [itemTypeId, fields] of fieldsByItemTypeId) {
|
|
452
|
+
this.fieldsByItemType.set(itemTypeId, fields);
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Gets all models that directly or indirectly embed the given block models.
|
|
458
|
+
* This method recursively traverses the schema to find all models that reference
|
|
459
|
+
* the provided blocks, either directly through block fields or indirectly through
|
|
460
|
+
* other block models that reference them.
|
|
461
|
+
*
|
|
462
|
+
* @param blocks - Array of block models to find references to
|
|
463
|
+
* @returns Promise that resolves to array of models that embed these blocks
|
|
464
|
+
*/
|
|
465
|
+
getRawModelsEmbeddingBlocks(blocks) {
|
|
466
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
467
|
+
yield this.prefetchAllModelsAndFields();
|
|
468
|
+
const allItemTypes = yield this.getAllRawItemTypes();
|
|
469
|
+
const blockIds = new Set(blocks.map((block) => block.id));
|
|
470
|
+
const embeddingModels = [];
|
|
471
|
+
// Helper function to check if a model points to any of the target blocks
|
|
472
|
+
const modelPointsToBlocks = (itemType, alreadyExplored = new Set()) => __awaiter(this, void 0, void 0, function* () {
|
|
473
|
+
if (alreadyExplored.has(itemType.id)) {
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
alreadyExplored.add(itemType.id);
|
|
477
|
+
const fields = yield this.getRawItemTypeFields(itemType);
|
|
478
|
+
for (const field of fields) {
|
|
479
|
+
const referencedBlockIds = blockModelIdsReferencedInField(field);
|
|
480
|
+
// Check if this field directly references any of our target blocks
|
|
481
|
+
if (referencedBlockIds.some((id) => blockIds.has(id))) {
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
484
|
+
// Check if this field references other block models that might transitively reference our targets
|
|
485
|
+
const referencedBlocks = referencedBlockIds.map((id) => allItemTypes.find((it) => it.id === id));
|
|
486
|
+
for (const linkedBlock of referencedBlocks) {
|
|
487
|
+
if (yield modelPointsToBlocks(linkedBlock, new Set(alreadyExplored))) {
|
|
488
|
+
return true;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return false;
|
|
493
|
+
});
|
|
494
|
+
// Check each model to see if it embeds any of the target blocks
|
|
495
|
+
for (const itemType of allItemTypes) {
|
|
496
|
+
if (yield modelPointsToBlocks(itemType)) {
|
|
497
|
+
embeddingModels.push(itemType);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return embeddingModels;
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Gets all models that directly or indirectly embed the given block models.
|
|
505
|
+
* This method recursively traverses the schema to find all models that reference
|
|
506
|
+
* the provided blocks, either directly through block fields or indirectly through
|
|
507
|
+
* other block models that reference them.
|
|
508
|
+
*
|
|
509
|
+
* @param blocks - Array of block models to find references to
|
|
510
|
+
* @returns Promise that resolves to array of models that embed these blocks
|
|
511
|
+
*/
|
|
512
|
+
getModelsEmbeddingBlocks(blocks) {
|
|
513
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
514
|
+
const rawResult = yield this.getRawModelsEmbeddingBlocks(blocks);
|
|
515
|
+
return deserializeResponseBody({
|
|
516
|
+
data: rawResult,
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
}
|
|
413
520
|
}
|
|
414
521
|
//# sourceMappingURL=schemaRepository.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemaRepository.js","sourceRoot":"","sources":["../../../src/utilities/schemaRepository.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"schemaRepository.js","sourceRoot":"","sources":["../../../src/utilities/schemaRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,14 @@ interface GenericClient {
|
|
|
24
24
|
data: RawApiTypes.Plugin[];
|
|
25
25
|
}>;
|
|
26
26
|
};
|
|
27
|
+
site: {
|
|
28
|
+
rawFind(params: {
|
|
29
|
+
include: string;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
data: any;
|
|
32
|
+
included?: Array<RawApiTypes.ItemType | RawApiTypes.Field | any>;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
27
35
|
}
|
|
28
36
|
/**
|
|
29
37
|
* Repository for DatoCMS schema entities including item types, fields, and plugins.
|
|
@@ -244,5 +252,37 @@ export declare class SchemaRepository {
|
|
|
244
252
|
* @throws Error if the plugin is not found
|
|
245
253
|
*/
|
|
246
254
|
getRawPluginByPackageName(packageName: string): Promise<RawApiTypes.Plugin>;
|
|
255
|
+
/**
|
|
256
|
+
* Prefetches all models and their fields in a single optimized API call.
|
|
257
|
+
* This method populates the internal caches for both item types and fields,
|
|
258
|
+
* making subsequent lookups very fast without additional API calls.
|
|
259
|
+
*
|
|
260
|
+
* This is more efficient than lazy loading when you know you'll need access
|
|
261
|
+
* to multiple models and fields, as it reduces the number of API requests
|
|
262
|
+
* from potentially dozens down to just one.
|
|
263
|
+
*
|
|
264
|
+
* @returns Promise that resolves when all data has been fetched and cached
|
|
265
|
+
*/
|
|
266
|
+
prefetchAllModelsAndFields(): Promise<void>;
|
|
267
|
+
/**
|
|
268
|
+
* Gets all models that directly or indirectly embed the given block models.
|
|
269
|
+
* This method recursively traverses the schema to find all models that reference
|
|
270
|
+
* the provided blocks, either directly through block fields or indirectly through
|
|
271
|
+
* other block models that reference them.
|
|
272
|
+
*
|
|
273
|
+
* @param blocks - Array of block models to find references to
|
|
274
|
+
* @returns Promise that resolves to array of models that embed these blocks
|
|
275
|
+
*/
|
|
276
|
+
getRawModelsEmbeddingBlocks(blocks: Array<ApiTypes.ItemType | RawApiTypes.ItemType>): Promise<Array<RawApiTypes.ItemType>>;
|
|
277
|
+
/**
|
|
278
|
+
* Gets all models that directly or indirectly embed the given block models.
|
|
279
|
+
* This method recursively traverses the schema to find all models that reference
|
|
280
|
+
* the provided blocks, either directly through block fields or indirectly through
|
|
281
|
+
* other block models that reference them.
|
|
282
|
+
*
|
|
283
|
+
* @param blocks - Array of block models to find references to
|
|
284
|
+
* @returns Promise that resolves to array of models that embed these blocks
|
|
285
|
+
*/
|
|
286
|
+
getModelsEmbeddingBlocks(blocks: Array<ApiTypes.ItemType | RawApiTypes.ItemType>): Promise<Array<ApiTypes.ItemType>>;
|
|
247
287
|
}
|
|
248
288
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datocms/cma-client",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.14",
|
|
4
4
|
"description": "JS client for DatoCMS REST Content Management API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"datocms",
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"@datocms/dashboard-client": "^5.1.13",
|
|
46
46
|
"@types/uuid": "^9.0.7"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "267e2d5a5dbab1bf3cec144445724bcec49ae7e3"
|
|
49
49
|
}
|
package/src/generated/Client.ts
CHANGED
|
@@ -147,7 +147,7 @@ export class Client {
|
|
|
147
147
|
...this.config,
|
|
148
148
|
...options,
|
|
149
149
|
logFn: this.config.logFn || console.log,
|
|
150
|
-
userAgent: '@datocms/cma-client v5.1.
|
|
150
|
+
userAgent: '@datocms/cma-client v5.1.14',
|
|
151
151
|
baseUrl: this.baseUrl,
|
|
152
152
|
preCallStack: new Error().stack,
|
|
153
153
|
extraHeaders: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { deserializeResponseBody } from '@datocms/rest-client-utils';
|
|
2
2
|
import type * as ApiTypes from '../generated/ApiTypes';
|
|
3
3
|
import type * as RawApiTypes from '../generated/RawApiTypes';
|
|
4
|
+
import { blockModelIdsReferencedInField } from './fieldsContainingReferences';
|
|
4
5
|
|
|
5
6
|
interface GenericClient {
|
|
6
7
|
itemTypes: {
|
|
@@ -16,6 +17,12 @@ interface GenericClient {
|
|
|
16
17
|
plugins: {
|
|
17
18
|
rawList(): Promise<{ data: RawApiTypes.Plugin[] }>;
|
|
18
19
|
};
|
|
20
|
+
site: {
|
|
21
|
+
rawFind(params: { include: string }): Promise<{
|
|
22
|
+
data: any;
|
|
23
|
+
included?: Array<RawApiTypes.ItemType | RawApiTypes.Field | any>;
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
/**
|
|
@@ -437,4 +444,138 @@ export class SchemaRepository {
|
|
|
437
444
|
|
|
438
445
|
return plugin;
|
|
439
446
|
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Prefetches all models and their fields in a single optimized API call.
|
|
450
|
+
* This method populates the internal caches for both item types and fields,
|
|
451
|
+
* making subsequent lookups very fast without additional API calls.
|
|
452
|
+
*
|
|
453
|
+
* This is more efficient than lazy loading when you know you'll need access
|
|
454
|
+
* to multiple models and fields, as it reduces the number of API requests
|
|
455
|
+
* from potentially dozens down to just one.
|
|
456
|
+
*
|
|
457
|
+
* @returns Promise that resolves when all data has been fetched and cached
|
|
458
|
+
*/
|
|
459
|
+
async prefetchAllModelsAndFields(): Promise<void> {
|
|
460
|
+
const { included } = await this.client.site.rawFind({
|
|
461
|
+
include: 'item_types,item_types.fields',
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
if (!included) {
|
|
465
|
+
throw new Error('This should not happen');
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const allItemTypes = included.filter(
|
|
469
|
+
(item): item is RawApiTypes.ItemType => item.type === 'item_type',
|
|
470
|
+
);
|
|
471
|
+
const allFields = included.filter(
|
|
472
|
+
(item): item is RawApiTypes.Field => item.type === 'field',
|
|
473
|
+
);
|
|
474
|
+
|
|
475
|
+
// Populate item types caches
|
|
476
|
+
this.itemTypesPromise = Promise.resolve(allItemTypes);
|
|
477
|
+
for (const itemType of allItemTypes) {
|
|
478
|
+
this.itemTypesByApiKey.set(itemType.attributes.api_key, itemType);
|
|
479
|
+
this.itemTypesById.set(itemType.id, itemType);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Group fields by item type and populate fields cache
|
|
483
|
+
const fieldsByItemTypeId = new Map<string, RawApiTypes.Field[]>();
|
|
484
|
+
for (const field of allFields) {
|
|
485
|
+
const itemTypeId = field.relationships.item_type.data.id;
|
|
486
|
+
if (!fieldsByItemTypeId.has(itemTypeId)) {
|
|
487
|
+
fieldsByItemTypeId.set(itemTypeId, []);
|
|
488
|
+
}
|
|
489
|
+
fieldsByItemTypeId.get(itemTypeId)!.push(field);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Populate the fields cache
|
|
493
|
+
for (const [itemTypeId, fields] of fieldsByItemTypeId) {
|
|
494
|
+
this.fieldsByItemType.set(itemTypeId, fields);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Gets all models that directly or indirectly embed the given block models.
|
|
500
|
+
* This method recursively traverses the schema to find all models that reference
|
|
501
|
+
* the provided blocks, either directly through block fields or indirectly through
|
|
502
|
+
* other block models that reference them.
|
|
503
|
+
*
|
|
504
|
+
* @param blocks - Array of block models to find references to
|
|
505
|
+
* @returns Promise that resolves to array of models that embed these blocks
|
|
506
|
+
*/
|
|
507
|
+
async getRawModelsEmbeddingBlocks(
|
|
508
|
+
blocks: Array<ApiTypes.ItemType | RawApiTypes.ItemType>,
|
|
509
|
+
): Promise<Array<RawApiTypes.ItemType>> {
|
|
510
|
+
await this.prefetchAllModelsAndFields();
|
|
511
|
+
|
|
512
|
+
const allItemTypes = await this.getAllRawItemTypes();
|
|
513
|
+
const blockIds = new Set(blocks.map((block) => block.id));
|
|
514
|
+
const embeddingModels: Array<RawApiTypes.ItemType> = [];
|
|
515
|
+
|
|
516
|
+
// Helper function to check if a model points to any of the target blocks
|
|
517
|
+
const modelPointsToBlocks = async (
|
|
518
|
+
itemType: RawApiTypes.ItemType,
|
|
519
|
+
alreadyExplored: Set<string> = new Set(),
|
|
520
|
+
): Promise<boolean> => {
|
|
521
|
+
if (alreadyExplored.has(itemType.id)) {
|
|
522
|
+
return false;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
alreadyExplored.add(itemType.id);
|
|
526
|
+
|
|
527
|
+
const fields = await this.getRawItemTypeFields(itemType);
|
|
528
|
+
|
|
529
|
+
for (const field of fields) {
|
|
530
|
+
const referencedBlockIds = blockModelIdsReferencedInField(field);
|
|
531
|
+
|
|
532
|
+
// Check if this field directly references any of our target blocks
|
|
533
|
+
if (referencedBlockIds.some((id) => blockIds.has(id))) {
|
|
534
|
+
return true;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// Check if this field references other block models that might transitively reference our targets
|
|
538
|
+
const referencedBlocks = referencedBlockIds.map(
|
|
539
|
+
(id) => allItemTypes.find((it) => it.id === id)!,
|
|
540
|
+
);
|
|
541
|
+
|
|
542
|
+
for (const linkedBlock of referencedBlocks) {
|
|
543
|
+
if (
|
|
544
|
+
await modelPointsToBlocks(linkedBlock, new Set(alreadyExplored))
|
|
545
|
+
) {
|
|
546
|
+
return true;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
return false;
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
// Check each model to see if it embeds any of the target blocks
|
|
555
|
+
for (const itemType of allItemTypes) {
|
|
556
|
+
if (await modelPointsToBlocks(itemType)) {
|
|
557
|
+
embeddingModels.push(itemType);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
return embeddingModels;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Gets all models that directly or indirectly embed the given block models.
|
|
566
|
+
* This method recursively traverses the schema to find all models that reference
|
|
567
|
+
* the provided blocks, either directly through block fields or indirectly through
|
|
568
|
+
* other block models that reference them.
|
|
569
|
+
*
|
|
570
|
+
* @param blocks - Array of block models to find references to
|
|
571
|
+
* @returns Promise that resolves to array of models that embed these blocks
|
|
572
|
+
*/
|
|
573
|
+
async getModelsEmbeddingBlocks(
|
|
574
|
+
blocks: Array<ApiTypes.ItemType | RawApiTypes.ItemType>,
|
|
575
|
+
): Promise<Array<ApiTypes.ItemType>> {
|
|
576
|
+
const rawResult = await this.getRawModelsEmbeddingBlocks(blocks);
|
|
577
|
+
return deserializeResponseBody<ApiTypes.ItemType[]>({
|
|
578
|
+
data: rawResult,
|
|
579
|
+
});
|
|
580
|
+
}
|
|
440
581
|
}
|