@datocms/cma-client 5.1.10 → 5.1.12
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 +569 -0
- package/dist/cjs/fieldTypes/boolean.js +2 -2
- package/dist/cjs/fieldTypes/boolean.js.map +1 -1
- package/dist/cjs/fieldTypes/color.js +2 -2
- package/dist/cjs/fieldTypes/color.js.map +1 -1
- package/dist/cjs/fieldTypes/date.js +2 -3
- package/dist/cjs/fieldTypes/date.js.map +1 -1
- package/dist/cjs/fieldTypes/date_time.js +2 -2
- package/dist/cjs/fieldTypes/date_time.js.map +1 -1
- package/dist/cjs/fieldTypes/file.js +33 -5
- package/dist/cjs/fieldTypes/file.js.map +1 -1
- package/dist/cjs/fieldTypes/float.js +2 -2
- package/dist/cjs/fieldTypes/float.js.map +1 -1
- package/dist/cjs/fieldTypes/gallery.js +20 -5
- package/dist/cjs/fieldTypes/gallery.js.map +1 -1
- package/dist/cjs/fieldTypes/index.js +2 -2
- package/dist/cjs/fieldTypes/index.js.map +1 -1
- package/dist/cjs/fieldTypes/integer.js +2 -2
- package/dist/cjs/fieldTypes/integer.js.map +1 -1
- package/dist/cjs/fieldTypes/json.js +2 -3
- package/dist/cjs/fieldTypes/json.js.map +1 -1
- package/dist/cjs/fieldTypes/lat_lon.js +2 -2
- package/dist/cjs/fieldTypes/lat_lon.js.map +1 -1
- package/dist/cjs/fieldTypes/link.js +4 -4
- package/dist/cjs/fieldTypes/link.js.map +1 -1
- package/dist/cjs/fieldTypes/links.js +5 -3
- package/dist/cjs/fieldTypes/links.js.map +1 -1
- package/dist/cjs/fieldTypes/rich_text.js +18 -18
- package/dist/cjs/fieldTypes/rich_text.js.map +1 -1
- package/dist/cjs/fieldTypes/schema.js +3 -0
- package/dist/cjs/fieldTypes/schema.js.map +1 -0
- package/dist/cjs/fieldTypes/seo.js +2 -3
- package/dist/cjs/fieldTypes/seo.js.map +1 -1
- package/dist/cjs/fieldTypes/single_block.js +20 -19
- package/dist/cjs/fieldTypes/single_block.js.map +1 -1
- package/dist/cjs/fieldTypes/slug.js +2 -3
- package/dist/cjs/fieldTypes/slug.js.map +1 -1
- package/dist/cjs/fieldTypes/string.js +2 -2
- package/dist/cjs/fieldTypes/string.js.map +1 -1
- package/dist/cjs/fieldTypes/structured_text.js +17 -18
- package/dist/cjs/fieldTypes/structured_text.js.map +1 -1
- package/dist/cjs/fieldTypes/text.js +2 -3
- package/dist/cjs/fieldTypes/text.js.map +1 -1
- package/dist/cjs/fieldTypes/video.js +2 -2
- package/dist/cjs/fieldTypes/video.js.map +1 -1
- package/dist/cjs/generated/Client.js +1 -1
- package/dist/cjs/generated/resources/Item.js.map +1 -1
- package/dist/cjs/generated/resources/ScheduledPublication.js.map +1 -1
- package/dist/cjs/generated/resources/ScheduledUnpublishing.js.map +1 -1
- package/dist/cjs/generated/resources/Upload.js.map +1 -1
- package/dist/cjs/index.js +5 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/utilities/buildBlockRecord.js +1 -45
- package/dist/cjs/utilities/buildBlockRecord.js.map +1 -1
- package/dist/cjs/utilities/duplicateBlockRecord.js +49 -0
- package/dist/cjs/utilities/duplicateBlockRecord.js.map +1 -0
- package/dist/cjs/utilities/inspectItem.js +427 -0
- package/dist/cjs/utilities/inspectItem.js.map +1 -0
- package/dist/cjs/utilities/{blocks.js → nonRecursiveBlocks.js} +60 -234
- package/dist/cjs/utilities/nonRecursiveBlocks.js.map +1 -0
- package/dist/cjs/utilities/{fieldValue.js → normalizedFieldValues.js} +53 -41
- package/dist/cjs/utilities/normalizedFieldValues.js.map +1 -0
- package/dist/cjs/utilities/recursiveBlocks.js +73 -92
- package/dist/cjs/utilities/recursiveBlocks.js.map +1 -1
- package/dist/cjs/utilities/schemaRepository.js +2 -2
- package/dist/esm/fieldTypes/boolean.d.ts +1 -1
- package/dist/esm/fieldTypes/boolean.js +2 -2
- package/dist/esm/fieldTypes/boolean.js.map +1 -1
- package/dist/esm/fieldTypes/color.d.ts +1 -1
- package/dist/esm/fieldTypes/color.js +2 -2
- package/dist/esm/fieldTypes/color.js.map +1 -1
- package/dist/esm/fieldTypes/date.d.ts +1 -1
- package/dist/esm/fieldTypes/date.js +2 -3
- package/dist/esm/fieldTypes/date.js.map +1 -1
- package/dist/esm/fieldTypes/date_time.d.ts +1 -1
- package/dist/esm/fieldTypes/date_time.js +2 -2
- package/dist/esm/fieldTypes/date_time.js.map +1 -1
- package/dist/esm/fieldTypes/file.d.ts +68 -1
- package/dist/esm/fieldTypes/file.js +29 -3
- package/dist/esm/fieldTypes/file.js.map +1 -1
- package/dist/esm/fieldTypes/float.d.ts +1 -1
- package/dist/esm/fieldTypes/float.js +2 -2
- package/dist/esm/fieldTypes/float.js.map +1 -1
- package/dist/esm/fieldTypes/gallery.d.ts +27 -11
- package/dist/esm/fieldTypes/gallery.js +17 -4
- package/dist/esm/fieldTypes/gallery.js.map +1 -1
- package/dist/esm/fieldTypes/index.d.ts +2 -2
- package/dist/esm/fieldTypes/index.js +2 -2
- package/dist/esm/fieldTypes/index.js.map +1 -1
- package/dist/esm/fieldTypes/integer.d.ts +1 -1
- package/dist/esm/fieldTypes/integer.js +2 -2
- package/dist/esm/fieldTypes/integer.js.map +1 -1
- package/dist/esm/fieldTypes/json.d.ts +1 -1
- package/dist/esm/fieldTypes/json.js +2 -3
- package/dist/esm/fieldTypes/json.js.map +1 -1
- package/dist/esm/fieldTypes/lat_lon.d.ts +1 -1
- package/dist/esm/fieldTypes/lat_lon.js +2 -2
- package/dist/esm/fieldTypes/lat_lon.js.map +1 -1
- package/dist/esm/fieldTypes/link.d.ts +1 -1
- package/dist/esm/fieldTypes/link.js +4 -4
- package/dist/esm/fieldTypes/link.js.map +1 -1
- package/dist/esm/fieldTypes/links.d.ts +1 -1
- package/dist/esm/fieldTypes/links.js +5 -3
- package/dist/esm/fieldTypes/links.js.map +1 -1
- package/dist/esm/fieldTypes/rich_text.d.ts +9 -10
- package/dist/esm/fieldTypes/rich_text.js +13 -13
- package/dist/esm/fieldTypes/rich_text.js.map +1 -1
- package/dist/esm/fieldTypes/schema.d.ts +59 -0
- package/dist/esm/fieldTypes/schema.js +2 -0
- package/dist/esm/fieldTypes/schema.js.map +1 -0
- package/dist/esm/fieldTypes/seo.d.ts +1 -1
- package/dist/esm/fieldTypes/seo.js +2 -3
- package/dist/esm/fieldTypes/seo.js.map +1 -1
- package/dist/esm/fieldTypes/single_block.d.ts +31 -16
- package/dist/esm/fieldTypes/single_block.js +15 -14
- package/dist/esm/fieldTypes/single_block.js.map +1 -1
- package/dist/esm/fieldTypes/slug.d.ts +1 -1
- package/dist/esm/fieldTypes/slug.js +2 -3
- package/dist/esm/fieldTypes/slug.js.map +1 -1
- package/dist/esm/fieldTypes/string.d.ts +1 -1
- package/dist/esm/fieldTypes/string.js +2 -2
- package/dist/esm/fieldTypes/string.js.map +1 -1
- package/dist/esm/fieldTypes/structured_text.d.ts +15 -16
- package/dist/esm/fieldTypes/structured_text.js +12 -13
- package/dist/esm/fieldTypes/structured_text.js.map +1 -1
- package/dist/esm/fieldTypes/text.d.ts +1 -1
- package/dist/esm/fieldTypes/text.js +2 -3
- package/dist/esm/fieldTypes/text.js.map +1 -1
- package/dist/esm/fieldTypes/video.d.ts +1 -1
- package/dist/esm/fieldTypes/video.js +2 -2
- package/dist/esm/fieldTypes/video.js.map +1 -1
- package/dist/esm/generated/ApiTypes.d.ts +90 -980
- package/dist/esm/generated/Client.js +1 -1
- package/dist/esm/generated/RawApiTypes.d.ts +156 -999
- package/dist/esm/generated/resources/Field.d.ts +200 -200
- package/dist/esm/generated/resources/Item.d.ts +34 -34
- package/dist/esm/generated/resources/Item.js.map +1 -1
- package/dist/esm/generated/resources/ItemVersion.d.ts +3 -1
- package/dist/esm/generated/resources/ScheduledPublication.d.ts +3 -3
- package/dist/esm/generated/resources/ScheduledPublication.js.map +1 -1
- package/dist/esm/generated/resources/ScheduledUnpublishing.d.ts +3 -3
- package/dist/esm/generated/resources/ScheduledUnpublishing.js.map +1 -1
- package/dist/esm/generated/resources/Upload.d.ts +6 -6
- package/dist/esm/generated/resources/Upload.js.map +1 -1
- package/dist/esm/index.d.ts +5 -4
- package/dist/esm/index.js +5 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utilities/buildBlockRecord.d.ts +3 -5
- package/dist/esm/utilities/buildBlockRecord.js +0 -43
- package/dist/esm/utilities/buildBlockRecord.js.map +1 -1
- package/dist/esm/utilities/duplicateBlockRecord.d.ts +6 -0
- package/dist/esm/utilities/duplicateBlockRecord.js +45 -0
- package/dist/esm/utilities/duplicateBlockRecord.js.map +1 -0
- package/dist/esm/utilities/inspectItem.d.ts +8 -0
- package/dist/esm/utilities/inspectItem.js +400 -0
- package/dist/esm/utilities/inspectItem.js.map +1 -0
- package/dist/esm/utilities/itemDefinition.d.ts +45 -23
- package/dist/esm/utilities/nonRecursiveBlocks.d.ts +114 -0
- package/dist/esm/utilities/{blocks.js → nonRecursiveBlocks.js} +52 -220
- package/dist/esm/utilities/nonRecursiveBlocks.js.map +1 -0
- package/dist/{types/utilities/fieldValue.d.ts → esm/utilities/normalizedFieldValues.d.ts} +15 -14
- package/dist/esm/utilities/{fieldValue.js → normalizedFieldValues.js} +39 -28
- package/dist/esm/utilities/normalizedFieldValues.js.map +1 -0
- package/dist/esm/utilities/recursiveBlocks.d.ts +124 -11
- package/dist/esm/utilities/recursiveBlocks.js +65 -84
- package/dist/esm/utilities/recursiveBlocks.js.map +1 -1
- package/dist/esm/utilities/schemaRepository.d.ts +2 -2
- package/dist/esm/utilities/schemaRepository.js +2 -2
- package/dist/types/fieldTypes/boolean.d.ts +1 -1
- package/dist/types/fieldTypes/color.d.ts +1 -1
- package/dist/types/fieldTypes/date.d.ts +1 -1
- package/dist/types/fieldTypes/date_time.d.ts +1 -1
- package/dist/types/fieldTypes/file.d.ts +68 -1
- package/dist/types/fieldTypes/float.d.ts +1 -1
- package/dist/types/fieldTypes/gallery.d.ts +27 -11
- package/dist/types/fieldTypes/index.d.ts +2 -2
- package/dist/types/fieldTypes/integer.d.ts +1 -1
- package/dist/types/fieldTypes/json.d.ts +1 -1
- package/dist/types/fieldTypes/lat_lon.d.ts +1 -1
- package/dist/types/fieldTypes/link.d.ts +1 -1
- package/dist/types/fieldTypes/links.d.ts +1 -1
- package/dist/types/fieldTypes/rich_text.d.ts +9 -10
- package/dist/types/fieldTypes/schema.d.ts +59 -0
- package/dist/types/fieldTypes/seo.d.ts +1 -1
- package/dist/types/fieldTypes/single_block.d.ts +31 -16
- package/dist/types/fieldTypes/slug.d.ts +1 -1
- package/dist/types/fieldTypes/string.d.ts +1 -1
- package/dist/types/fieldTypes/structured_text.d.ts +15 -16
- package/dist/types/fieldTypes/text.d.ts +1 -1
- package/dist/types/fieldTypes/video.d.ts +1 -1
- package/dist/types/generated/ApiTypes.d.ts +90 -980
- package/dist/types/generated/RawApiTypes.d.ts +156 -999
- package/dist/types/generated/resources/Field.d.ts +200 -200
- package/dist/types/generated/resources/Item.d.ts +34 -34
- package/dist/types/generated/resources/ItemVersion.d.ts +3 -1
- package/dist/types/generated/resources/ScheduledPublication.d.ts +3 -3
- package/dist/types/generated/resources/ScheduledUnpublishing.d.ts +3 -3
- package/dist/types/generated/resources/Upload.d.ts +6 -6
- package/dist/types/index.d.ts +5 -4
- package/dist/types/utilities/buildBlockRecord.d.ts +3 -5
- package/dist/types/utilities/duplicateBlockRecord.d.ts +6 -0
- package/dist/types/utilities/inspectItem.d.ts +8 -0
- package/dist/types/utilities/itemDefinition.d.ts +45 -23
- package/dist/types/utilities/nonRecursiveBlocks.d.ts +114 -0
- package/dist/{esm/utilities/fieldValue.d.ts → types/utilities/normalizedFieldValues.d.ts} +15 -14
- package/dist/types/utilities/recursiveBlocks.d.ts +124 -11
- package/dist/types/utilities/schemaRepository.d.ts +2 -2
- package/package.json +4 -4
- package/src/fieldTypes/boolean.ts +5 -3
- package/src/fieldTypes/color.ts +5 -3
- package/src/fieldTypes/date.ts +5 -4
- package/src/fieldTypes/date_time.ts +5 -3
- package/src/fieldTypes/file.ts +98 -4
- package/src/fieldTypes/float.ts +5 -3
- package/src/fieldTypes/gallery.ts +53 -20
- package/src/fieldTypes/index.ts +2 -3
- package/src/fieldTypes/integer.ts +5 -3
- package/src/fieldTypes/json.ts +5 -4
- package/src/fieldTypes/lat_lon.ts +5 -3
- package/src/fieldTypes/link.ts +7 -5
- package/src/fieldTypes/links.ts +8 -4
- package/src/fieldTypes/rich_text.ts +33 -31
- package/src/fieldTypes/schema.ts +657 -0
- package/src/fieldTypes/seo.ts +5 -4
- package/src/fieldTypes/single_block.ts +71 -46
- package/src/fieldTypes/slug.ts +5 -4
- package/src/fieldTypes/string.ts +5 -3
- package/src/fieldTypes/structured_text.ts +64 -58
- package/src/fieldTypes/text.ts +5 -4
- package/src/fieldTypes/video.ts +5 -3
- package/src/generated/ApiTypes.ts +217 -1880
- package/src/generated/Client.ts +1 -1
- package/src/generated/RawApiTypes.ts +272 -2113
- package/src/generated/resources/Item.ts +93 -187
- package/src/generated/resources/ScheduledPublication.ts +4 -15
- package/src/generated/resources/ScheduledUnpublishing.ts +4 -15
- package/src/generated/resources/Upload.ts +9 -32
- package/src/index.ts +5 -4
- package/src/utilities/buildBlockRecord.ts +4 -59
- package/src/utilities/duplicateBlockRecord.ts +52 -0
- package/src/utilities/inspectItem.ts +602 -0
- package/src/utilities/itemDefinition.ts +130 -92
- package/src/utilities/nonRecursiveBlocks.ts +406 -0
- package/src/utilities/{fieldValue.ts → normalizedFieldValues.ts} +70 -30
- package/src/utilities/recursiveBlocks.ts +484 -204
- package/src/utilities/schemaRepository.ts +2 -2
- package/dist/cjs/utilities/blocks.js.map +0 -1
- package/dist/cjs/utilities/fieldValue.js.map +0 -1
- package/dist/esm/utilities/blocks.d.ts +0 -180
- package/dist/esm/utilities/blocks.js.map +0 -1
- package/dist/esm/utilities/fieldValue.js.map +0 -1
- package/dist/types/utilities/blocks.d.ts +0 -180
- package/src/utilities/blocks.ts +0 -626
|
@@ -1,35 +1,90 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type
|
|
2
|
+
type BlockInRequest,
|
|
3
|
+
type RichTextFieldValue,
|
|
4
|
+
type RichTextFieldValueInNestedResponse,
|
|
5
|
+
type RichTextFieldValueInRequest,
|
|
6
|
+
type SingleBlockFieldValue,
|
|
7
|
+
type SingleBlockFieldValueInNestedResponse,
|
|
8
|
+
type SingleBlockFieldValueInRequest,
|
|
9
|
+
type StructuredTextFieldValue,
|
|
10
|
+
type StructuredTextFieldValueInNestedResponse,
|
|
11
|
+
type StructuredTextFieldValueInRequest,
|
|
3
12
|
isItemWithOptionalIdAndMeta,
|
|
4
13
|
} from '../fieldTypes';
|
|
5
14
|
import type * as ApiTypes from '../generated/ApiTypes';
|
|
6
|
-
import type
|
|
15
|
+
import type { ExtractNestedBlocksFromFieldValue } from './itemDefinition';
|
|
7
16
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} from './
|
|
15
|
-
import { mapFieldValueAsync, visitFieldValueAsync } from './fieldValue';
|
|
17
|
+
nonRecursiveFilterBlocksInNonLocalizedFieldValueAsync,
|
|
18
|
+
nonRecursiveFindAllBlocksInNonLocalizedFieldValueAsync,
|
|
19
|
+
nonRecursiveMapBlocksInNonLocalizedFieldValueAsync,
|
|
20
|
+
nonRecursiveReduceBlocksInNonLocalizedFieldValueAsync,
|
|
21
|
+
nonRecursiveSomeBlocksInNonLocalizedFieldValueAsync,
|
|
22
|
+
nonRecursiveVisitBlocksInNonLocalizedFieldValueAsync,
|
|
23
|
+
} from './nonRecursiveBlocks';
|
|
16
24
|
import type { SchemaRepository } from './schemaRepository';
|
|
17
25
|
|
|
26
|
+
type RecognizableFieldValue =
|
|
27
|
+
| RichTextFieldValueInNestedResponse
|
|
28
|
+
| SingleBlockFieldValueInNestedResponse
|
|
29
|
+
| StructuredTextFieldValueInNestedResponse
|
|
30
|
+
| RichTextFieldValueInRequest
|
|
31
|
+
| SingleBlockFieldValueInRequest
|
|
32
|
+
| StructuredTextFieldValueInRequest
|
|
33
|
+
| RichTextFieldValue
|
|
34
|
+
| SingleBlockFieldValue
|
|
35
|
+
| StructuredTextFieldValue;
|
|
36
|
+
|
|
18
37
|
/**
|
|
19
|
-
* Path through a field value (ie. ['content', 0, 'attributes', 'title'])
|
|
38
|
+
* Path through a non-localized field value (ie. ['content', 0, 'attributes', 'title'])
|
|
20
39
|
*/
|
|
21
40
|
export type TreePath = readonly (string | number)[];
|
|
22
41
|
|
|
23
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Traversal direction for recursive operations
|
|
44
|
+
*/
|
|
45
|
+
export type TraversalDirection = 'top-down' | 'bottom-up';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Recursively visit every block in a non-localized field value and all nested blocks within those blocks.
|
|
49
|
+
* This function traverses not only the direct blocks in the non-localized field value but also recursively
|
|
50
|
+
* visits blocks contained within the attributes of each block, creating a complete traversal
|
|
51
|
+
* of the entire block hierarchy.
|
|
52
|
+
*
|
|
53
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to visit
|
|
54
|
+
* @param fieldType - The type field (determines how the value is processed)
|
|
55
|
+
* @param schemaRepository - Repository for accessing DatoCMS schema information (to resolve block structures)
|
|
56
|
+
* @param visitor - Asynchronous function called for each block found, including nested blocks
|
|
57
|
+
* @returns Promise that resolves when all blocks and nested blocks have been visited
|
|
58
|
+
*/
|
|
59
|
+
export async function visitBlocksInNonLocalizedFieldValue<
|
|
60
|
+
T extends RecognizableFieldValue,
|
|
61
|
+
>(
|
|
62
|
+
nonLocalizedFieldValue: T,
|
|
63
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
64
|
+
schemaRepository: SchemaRepository,
|
|
65
|
+
visitor: (
|
|
66
|
+
item: ExtractNestedBlocksFromFieldValue<T>,
|
|
67
|
+
path: TreePath,
|
|
68
|
+
) => void | Promise<void>,
|
|
69
|
+
path?: TreePath,
|
|
70
|
+
): Promise<void>;
|
|
71
|
+
export async function visitBlocksInNonLocalizedFieldValue(
|
|
72
|
+
nonLocalizedFieldValue: unknown,
|
|
73
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
24
74
|
schemaRepository: SchemaRepository,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
75
|
+
visitor: (item: BlockInRequest, path: TreePath) => void | Promise<void>,
|
|
76
|
+
path?: TreePath,
|
|
77
|
+
): Promise<void>;
|
|
78
|
+
export async function visitBlocksInNonLocalizedFieldValue(
|
|
79
|
+
nonLocalizedFieldValue: unknown,
|
|
80
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
81
|
+
schemaRepository: SchemaRepository,
|
|
82
|
+
visitor: (item: BlockInRequest, path: TreePath) => void | Promise<void>,
|
|
28
83
|
path: TreePath = [],
|
|
29
84
|
): Promise<void> {
|
|
30
|
-
await
|
|
31
|
-
|
|
32
|
-
|
|
85
|
+
await nonRecursiveVisitBlocksInNonLocalizedFieldValueAsync(
|
|
86
|
+
fieldType,
|
|
87
|
+
nonLocalizedFieldValue,
|
|
33
88
|
async (block, innerPath) => {
|
|
34
89
|
await visitor(block, [...path, ...innerPath]);
|
|
35
90
|
|
|
@@ -44,46 +99,72 @@ export async function visitBlocksInFieldValues(
|
|
|
44
99
|
const fields = await schemaRepository.getRawItemTypeFields(itemType);
|
|
45
100
|
|
|
46
101
|
for (const field of fields) {
|
|
47
|
-
await
|
|
48
|
-
field,
|
|
102
|
+
await visitBlocksInNonLocalizedFieldValue(
|
|
49
103
|
block.attributes[field.attributes.api_key],
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
valueForLocale,
|
|
55
|
-
visitor,
|
|
56
|
-
[
|
|
57
|
-
...path,
|
|
58
|
-
...innerPath,
|
|
59
|
-
'attributes',
|
|
60
|
-
field.attributes.api_key,
|
|
61
|
-
...(locale ? [locale] : []),
|
|
62
|
-
],
|
|
63
|
-
),
|
|
104
|
+
field.attributes.field_type,
|
|
105
|
+
schemaRepository,
|
|
106
|
+
visitor,
|
|
107
|
+
[...path, ...innerPath, 'attributes', field.attributes.api_key],
|
|
64
108
|
);
|
|
65
109
|
}
|
|
66
110
|
},
|
|
67
111
|
);
|
|
68
112
|
}
|
|
69
113
|
|
|
70
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Recursively find all blocks that match the predicate function in a non-localized field value.
|
|
116
|
+
* Searches through all direct blocks and recursively through nested blocks within
|
|
117
|
+
* the attributes of each block, returning all matches found throughout the hierarchy.
|
|
118
|
+
*
|
|
119
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to search
|
|
120
|
+
* @param fieldType - The type field (determines how the value is processed)
|
|
121
|
+
* @param schemaRepository - Repository for accessing DatoCMS schema information (to resolve block structures)
|
|
122
|
+
* @param predicate - Asynchronous function that tests each block, including nested ones
|
|
123
|
+
* @returns Promise that resolves to an array of objects, each containing a matching block and its full path
|
|
124
|
+
*/
|
|
125
|
+
export async function findAllBlocksInNonLocalizedFieldValue<
|
|
126
|
+
T extends RecognizableFieldValue,
|
|
127
|
+
>(
|
|
128
|
+
nonLocalizedFieldValue: T,
|
|
129
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
130
|
+
schemaRepository: SchemaRepository,
|
|
131
|
+
predicate: (
|
|
132
|
+
item: ExtractNestedBlocksFromFieldValue<T>,
|
|
133
|
+
path: TreePath,
|
|
134
|
+
) => boolean | Promise<boolean>,
|
|
135
|
+
path?: TreePath,
|
|
136
|
+
): Promise<
|
|
137
|
+
Array<{ item: ExtractNestedBlocksFromFieldValue<T>; path: TreePath }>
|
|
138
|
+
>;
|
|
139
|
+
export async function findAllBlocksInNonLocalizedFieldValue(
|
|
140
|
+
nonLocalizedFieldValue: unknown,
|
|
141
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
71
142
|
schemaRepository: SchemaRepository,
|
|
72
|
-
field: RawApiTypes.Field | ApiTypes.Field,
|
|
73
|
-
value: unknown,
|
|
74
143
|
predicate: (
|
|
75
|
-
item:
|
|
144
|
+
item: BlockInRequest,
|
|
145
|
+
path: TreePath,
|
|
146
|
+
) => boolean | Promise<boolean>,
|
|
147
|
+
path?: TreePath,
|
|
148
|
+
): Promise<Array<{ item: BlockInRequest; path: TreePath }>>;
|
|
149
|
+
export async function findAllBlocksInNonLocalizedFieldValue(
|
|
150
|
+
nonLocalizedFieldValue: unknown,
|
|
151
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
152
|
+
schemaRepository: SchemaRepository,
|
|
153
|
+
predicate: (
|
|
154
|
+
item: BlockInRequest,
|
|
76
155
|
path: TreePath,
|
|
77
156
|
) => boolean | Promise<boolean>,
|
|
78
157
|
path: TreePath = [],
|
|
79
|
-
): Promise<Array<{ item:
|
|
80
|
-
const results: Array<{ item:
|
|
158
|
+
): Promise<Array<{ item: BlockInRequest; path: TreePath }>> {
|
|
159
|
+
const results: Array<{ item: BlockInRequest; path: TreePath }> = [];
|
|
81
160
|
|
|
82
|
-
const directMatches =
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
161
|
+
const directMatches =
|
|
162
|
+
await nonRecursiveFindAllBlocksInNonLocalizedFieldValueAsync(
|
|
163
|
+
fieldType,
|
|
164
|
+
nonLocalizedFieldValue,
|
|
165
|
+
async (block, innerPath) =>
|
|
166
|
+
await predicate(block, [...path, ...innerPath]),
|
|
167
|
+
);
|
|
87
168
|
|
|
88
169
|
results.push(
|
|
89
170
|
...directMatches.map(({ item, path: innerPath }) => ({
|
|
@@ -92,9 +173,9 @@ export async function findAllBlocksInFieldValues(
|
|
|
92
173
|
})),
|
|
93
174
|
);
|
|
94
175
|
|
|
95
|
-
await
|
|
96
|
-
|
|
97
|
-
|
|
176
|
+
await nonRecursiveVisitBlocksInNonLocalizedFieldValueAsync(
|
|
177
|
+
fieldType,
|
|
178
|
+
nonLocalizedFieldValue,
|
|
98
179
|
async (block, innerPath) => {
|
|
99
180
|
if (!isItemWithOptionalIdAndMeta(block)) {
|
|
100
181
|
return;
|
|
@@ -107,26 +188,14 @@ export async function findAllBlocksInFieldValues(
|
|
|
107
188
|
const fields = await schemaRepository.getRawItemTypeFields(itemType);
|
|
108
189
|
|
|
109
190
|
for (const field of fields) {
|
|
110
|
-
await
|
|
111
|
-
field,
|
|
191
|
+
const nestedResults = await findAllBlocksInNonLocalizedFieldValue(
|
|
112
192
|
block.attributes[field.attributes.api_key],
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
valueForLocale,
|
|
118
|
-
predicate,
|
|
119
|
-
[
|
|
120
|
-
...path,
|
|
121
|
-
...innerPath,
|
|
122
|
-
'attributes',
|
|
123
|
-
field.attributes.api_key,
|
|
124
|
-
...(locale ? [locale] : []),
|
|
125
|
-
],
|
|
126
|
-
);
|
|
127
|
-
results.push(...nestedResults);
|
|
128
|
-
},
|
|
193
|
+
field.attributes.field_type,
|
|
194
|
+
schemaRepository,
|
|
195
|
+
predicate,
|
|
196
|
+
[...path, ...innerPath, 'attributes', field.attributes.api_key],
|
|
129
197
|
);
|
|
198
|
+
results.push(...nestedResults);
|
|
130
199
|
}
|
|
131
200
|
},
|
|
132
201
|
);
|
|
@@ -134,85 +203,182 @@ export async function findAllBlocksInFieldValues(
|
|
|
134
203
|
return results;
|
|
135
204
|
}
|
|
136
205
|
|
|
137
|
-
|
|
206
|
+
/**
|
|
207
|
+
* Recursively filter blocks in a non-localized field value, removing those that don't match the predicate.
|
|
208
|
+
* Creates a new non-localized field value structure containing only blocks that pass the predicate test,
|
|
209
|
+
* including recursive filtering of nested blocks within block attributes. The filtering
|
|
210
|
+
* preserves the original non-localized field value structure and hierarchy.
|
|
211
|
+
*
|
|
212
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to filter
|
|
213
|
+
* @param fieldType - The type field (determines how the value is processed)
|
|
214
|
+
* @param schemaRepository - Repository for accessing DatoCMS schema information (to resolve block structures)
|
|
215
|
+
* @param predicate - Asynchronous function that tests each block, including nested ones
|
|
216
|
+
* @param options - Optional configuration object
|
|
217
|
+
* @param options.traversalDirection - Direction of traversal: 'top-down' (default) applies predicate before processing children, 'bottom-up' processes children first
|
|
218
|
+
* @returns Promise that resolves to the new non-localized field value with recursively filtered blocks
|
|
219
|
+
*/
|
|
220
|
+
export async function filterBlocksInNonLocalizedFieldValue<
|
|
221
|
+
T extends RecognizableFieldValue,
|
|
222
|
+
>(
|
|
223
|
+
nonLocalizedFieldValue: T,
|
|
224
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
138
225
|
schemaRepository: SchemaRepository,
|
|
139
|
-
field: RawApiTypes.Field | ApiTypes.Field,
|
|
140
|
-
value: unknown,
|
|
141
226
|
predicate: (
|
|
142
|
-
item:
|
|
227
|
+
item: ExtractNestedBlocksFromFieldValue<T>,
|
|
143
228
|
path: TreePath,
|
|
144
229
|
) => boolean | Promise<boolean>,
|
|
230
|
+
options?: { traversalDirection?: TraversalDirection },
|
|
231
|
+
path?: TreePath,
|
|
232
|
+
): Promise<T>;
|
|
233
|
+
export async function filterBlocksInNonLocalizedFieldValue(
|
|
234
|
+
nonLocalizedFieldValue: unknown,
|
|
235
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
236
|
+
schemaRepository: SchemaRepository,
|
|
237
|
+
predicate: (
|
|
238
|
+
item: BlockInRequest,
|
|
239
|
+
path: TreePath,
|
|
240
|
+
) => boolean | Promise<boolean>,
|
|
241
|
+
options?: { traversalDirection?: TraversalDirection },
|
|
242
|
+
path?: TreePath,
|
|
243
|
+
): Promise<unknown>;
|
|
244
|
+
export async function filterBlocksInNonLocalizedFieldValue(
|
|
245
|
+
nonLocalizedFieldValue: unknown,
|
|
246
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
247
|
+
schemaRepository: SchemaRepository,
|
|
248
|
+
predicate: (
|
|
249
|
+
item: BlockInRequest,
|
|
250
|
+
path: TreePath,
|
|
251
|
+
) => boolean | Promise<boolean>,
|
|
252
|
+
options: { traversalDirection?: TraversalDirection } = {},
|
|
145
253
|
path: TreePath = [],
|
|
146
254
|
): Promise<unknown> {
|
|
147
|
-
|
|
148
|
-
field,
|
|
149
|
-
value,
|
|
150
|
-
async (block, innerPath) => {
|
|
151
|
-
const blockPath = [...path, ...innerPath];
|
|
152
|
-
const passes = await predicate(block, blockPath);
|
|
255
|
+
const { traversalDirection = 'top-down' } = options;
|
|
153
256
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
257
|
+
const mapperFunc = async (block: BlockInRequest, innerPath: TreePath) => {
|
|
258
|
+
const blockPath = [...path, ...innerPath];
|
|
157
259
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
260
|
+
if (!isItemWithOptionalIdAndMeta(block)) {
|
|
261
|
+
return block;
|
|
262
|
+
}
|
|
161
263
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
264
|
+
const itemType = await schemaRepository.getRawItemTypeById(
|
|
265
|
+
block.relationships.item_type.data.id,
|
|
266
|
+
);
|
|
165
267
|
|
|
166
|
-
|
|
268
|
+
const fields = await schemaRepository.getRawItemTypeFields(itemType);
|
|
269
|
+
|
|
270
|
+
if (traversalDirection === 'top-down') {
|
|
271
|
+
const blockCopy = { ...block, attributes: { ...block.attributes } };
|
|
167
272
|
|
|
168
273
|
for (const field of fields) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
...blockPath,
|
|
180
|
-
'attributes',
|
|
181
|
-
field.attributes.api_key,
|
|
182
|
-
...(locale ? [locale] : []),
|
|
183
|
-
],
|
|
184
|
-
),
|
|
185
|
-
);
|
|
274
|
+
blockCopy.attributes[field.attributes.api_key] =
|
|
275
|
+
await filterBlocksInNonLocalizedFieldValue(
|
|
276
|
+
blockCopy.attributes[field.attributes.api_key],
|
|
277
|
+
field.attributes.field_type,
|
|
278
|
+
schemaRepository,
|
|
279
|
+
|
|
280
|
+
predicate,
|
|
281
|
+
options,
|
|
282
|
+
[...blockPath, 'attributes', field.attributes.api_key],
|
|
283
|
+
);
|
|
186
284
|
}
|
|
187
285
|
|
|
188
|
-
return
|
|
286
|
+
return blockCopy;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const blockCopy = { ...block, attributes: { ...block.attributes } };
|
|
290
|
+
|
|
291
|
+
for (const field of fields) {
|
|
292
|
+
blockCopy.attributes[field.attributes.api_key] =
|
|
293
|
+
await filterBlocksInNonLocalizedFieldValue(
|
|
294
|
+
blockCopy.attributes[field.attributes.api_key],
|
|
295
|
+
field.attributes.field_type,
|
|
296
|
+
schemaRepository,
|
|
297
|
+
predicate,
|
|
298
|
+
options,
|
|
299
|
+
[...blockPath, 'attributes', field.attributes.api_key],
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return blockCopy;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
const mappedValue = await nonRecursiveMapBlocksInNonLocalizedFieldValueAsync(
|
|
307
|
+
fieldType,
|
|
308
|
+
nonLocalizedFieldValue,
|
|
309
|
+
mapperFunc,
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
return nonRecursiveFilterBlocksInNonLocalizedFieldValueAsync(
|
|
313
|
+
fieldType,
|
|
314
|
+
mappedValue,
|
|
315
|
+
async (block, innerPath) => {
|
|
316
|
+
const blockPath = [...path, ...innerPath];
|
|
317
|
+
return await predicate(block, blockPath);
|
|
189
318
|
},
|
|
190
319
|
);
|
|
191
320
|
}
|
|
192
321
|
|
|
193
|
-
|
|
322
|
+
/**
|
|
323
|
+
* Recursively reduce all blocks in a non-localized field value to a single value by applying a reducer function.
|
|
324
|
+
* Processes each direct block and recursively processes nested blocks within block attributes,
|
|
325
|
+
* accumulating results from the entire block hierarchy into a single value.
|
|
326
|
+
*
|
|
327
|
+
* @template R - The type of the accumulated result
|
|
328
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to reduce
|
|
329
|
+
* @param fieldType - The type field (determines how the value is processed)
|
|
330
|
+
* @param schemaRepository - Repository for accessing DatoCMS schema information (to resolve block structures)
|
|
331
|
+
* @param reducer - Asynchronous function that processes each block and updates the accumulator
|
|
332
|
+
* @param initialNonLocalizedFieldValue - The initial value for the accumulator
|
|
333
|
+
* @returns Promise that resolves to the final accumulated value from all blocks in the hierarchy
|
|
334
|
+
*/
|
|
335
|
+
export async function reduceBlocksInNonLocalizedFieldValue<T, R>(
|
|
336
|
+
nonLocalizedFieldValue: T,
|
|
337
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
338
|
+
schemaRepository: SchemaRepository,
|
|
339
|
+
reducer: (
|
|
340
|
+
accumulator: R,
|
|
341
|
+
item: ExtractNestedBlocksFromFieldValue<T>,
|
|
342
|
+
path: TreePath,
|
|
343
|
+
) => R | Promise<R>,
|
|
344
|
+
initialValue: R,
|
|
345
|
+
path?: TreePath,
|
|
346
|
+
): Promise<R>;
|
|
347
|
+
export async function reduceBlocksInNonLocalizedFieldValue<R>(
|
|
348
|
+
nonLocalizedFieldValue: unknown,
|
|
349
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
350
|
+
schemaRepository: SchemaRepository,
|
|
351
|
+
reducer: (
|
|
352
|
+
accumulator: R,
|
|
353
|
+
item: BlockInRequest,
|
|
354
|
+
path: TreePath,
|
|
355
|
+
) => R | Promise<R>,
|
|
356
|
+
initialValue: R,
|
|
357
|
+
path?: TreePath,
|
|
358
|
+
): Promise<R>;
|
|
359
|
+
export async function reduceBlocksInNonLocalizedFieldValue<R>(
|
|
360
|
+
nonLocalizedFieldValue: unknown,
|
|
361
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
194
362
|
schemaRepository: SchemaRepository,
|
|
195
|
-
field: RawApiTypes.Field | ApiTypes.Field,
|
|
196
|
-
value: unknown,
|
|
197
363
|
reducer: (
|
|
198
364
|
accumulator: R,
|
|
199
|
-
item:
|
|
365
|
+
item: BlockInRequest,
|
|
200
366
|
path: TreePath,
|
|
201
367
|
) => R | Promise<R>,
|
|
202
368
|
initialValue: R,
|
|
203
369
|
path: TreePath = [],
|
|
204
370
|
): Promise<R> {
|
|
205
|
-
let accumulator = await
|
|
206
|
-
|
|
207
|
-
|
|
371
|
+
let accumulator = await nonRecursiveReduceBlocksInNonLocalizedFieldValueAsync(
|
|
372
|
+
fieldType,
|
|
373
|
+
nonLocalizedFieldValue,
|
|
208
374
|
async (acc, block, innerPath) =>
|
|
209
375
|
await reducer(acc, block, [...path, ...innerPath]),
|
|
210
376
|
initialValue,
|
|
211
377
|
);
|
|
212
378
|
|
|
213
|
-
await
|
|
214
|
-
|
|
215
|
-
|
|
379
|
+
await nonRecursiveVisitBlocksInNonLocalizedFieldValueAsync(
|
|
380
|
+
fieldType,
|
|
381
|
+
nonLocalizedFieldValue,
|
|
216
382
|
async (block, innerPath) => {
|
|
217
383
|
if (!isItemWithOptionalIdAndMeta(block)) {
|
|
218
384
|
return;
|
|
@@ -225,25 +391,13 @@ export async function reduceBlocksInFieldValues<R>(
|
|
|
225
391
|
const fields = await schemaRepository.getRawItemTypeFields(itemType);
|
|
226
392
|
|
|
227
393
|
for (const field of fields) {
|
|
228
|
-
await
|
|
229
|
-
field,
|
|
394
|
+
accumulator = await reduceBlocksInNonLocalizedFieldValue(
|
|
230
395
|
block.attributes[field.attributes.api_key],
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
reducer,
|
|
237
|
-
accumulator,
|
|
238
|
-
[
|
|
239
|
-
...path,
|
|
240
|
-
...innerPath,
|
|
241
|
-
'attributes',
|
|
242
|
-
field.attributes.api_key,
|
|
243
|
-
...(locale ? [locale] : []),
|
|
244
|
-
],
|
|
245
|
-
);
|
|
246
|
-
},
|
|
396
|
+
field.attributes.field_type,
|
|
397
|
+
schemaRepository,
|
|
398
|
+
reducer,
|
|
399
|
+
accumulator,
|
|
400
|
+
[...path, ...innerPath, 'attributes', field.attributes.api_key],
|
|
247
401
|
);
|
|
248
402
|
}
|
|
249
403
|
},
|
|
@@ -252,19 +406,53 @@ export async function reduceBlocksInFieldValues<R>(
|
|
|
252
406
|
return accumulator;
|
|
253
407
|
}
|
|
254
408
|
|
|
255
|
-
|
|
409
|
+
/**
|
|
410
|
+
* Recursively check if any block in the non-localized field value matches the predicate function.
|
|
411
|
+
* Tests both direct blocks and recursively tests nested blocks within block attributes.
|
|
412
|
+
* Returns true as soon as the first matching block is found anywhere in the hierarchy
|
|
413
|
+
* (short-circuit evaluation).
|
|
414
|
+
*
|
|
415
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to test
|
|
416
|
+
* @param fieldType - The type field (determines how the value is processed)
|
|
417
|
+
* @param schemaRepository - Repository for accessing DatoCMS schema information (to resolve block structures)
|
|
418
|
+
* @param predicate - Asynchronous function that tests each block, including nested ones
|
|
419
|
+
* @returns Promise that resolves to true if any block in the hierarchy matches, false otherwise
|
|
420
|
+
*/
|
|
421
|
+
export async function someBlocksInNonLocalizedFieldValue<
|
|
422
|
+
T extends RecognizableFieldValue,
|
|
423
|
+
>(
|
|
424
|
+
nonLocalizedFieldValue: T,
|
|
425
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
256
426
|
schemaRepository: SchemaRepository,
|
|
257
|
-
field: RawApiTypes.Field | ApiTypes.Field,
|
|
258
|
-
value: unknown,
|
|
259
427
|
predicate: (
|
|
260
|
-
item:
|
|
428
|
+
item: ExtractNestedBlocksFromFieldValue<T>,
|
|
429
|
+
path: TreePath,
|
|
430
|
+
) => boolean | Promise<boolean>,
|
|
431
|
+
path?: TreePath,
|
|
432
|
+
): Promise<boolean>;
|
|
433
|
+
export async function someBlocksInNonLocalizedFieldValue(
|
|
434
|
+
nonLocalizedFieldValue: unknown,
|
|
435
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
436
|
+
schemaRepository: SchemaRepository,
|
|
437
|
+
predicate: (
|
|
438
|
+
item: BlockInRequest,
|
|
439
|
+
path: TreePath,
|
|
440
|
+
) => boolean | Promise<boolean>,
|
|
441
|
+
path?: TreePath,
|
|
442
|
+
): Promise<boolean>;
|
|
443
|
+
export async function someBlocksInNonLocalizedFieldValue(
|
|
444
|
+
nonLocalizedFieldValue: unknown,
|
|
445
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
446
|
+
schemaRepository: SchemaRepository,
|
|
447
|
+
predicate: (
|
|
448
|
+
item: BlockInRequest,
|
|
261
449
|
path: TreePath,
|
|
262
450
|
) => boolean | Promise<boolean>,
|
|
263
451
|
path: TreePath = [],
|
|
264
452
|
): Promise<boolean> {
|
|
265
|
-
const directMatch = await
|
|
266
|
-
|
|
267
|
-
|
|
453
|
+
const directMatch = await nonRecursiveSomeBlocksInNonLocalizedFieldValueAsync(
|
|
454
|
+
fieldType,
|
|
455
|
+
nonLocalizedFieldValue,
|
|
268
456
|
async (block, innerPath) => await predicate(block, [...path, ...innerPath]),
|
|
269
457
|
);
|
|
270
458
|
|
|
@@ -273,9 +461,9 @@ export async function someBlocksInFieldValues(
|
|
|
273
461
|
}
|
|
274
462
|
|
|
275
463
|
let found = false;
|
|
276
|
-
await
|
|
277
|
-
|
|
278
|
-
|
|
464
|
+
await nonRecursiveVisitBlocksInNonLocalizedFieldValueAsync(
|
|
465
|
+
fieldType,
|
|
466
|
+
nonLocalizedFieldValue,
|
|
279
467
|
async (block, innerPath) => {
|
|
280
468
|
if (found || !isItemWithOptionalIdAndMeta(block)) {
|
|
281
469
|
return;
|
|
@@ -290,31 +478,17 @@ export async function someBlocksInFieldValues(
|
|
|
290
478
|
for (const field of fields) {
|
|
291
479
|
if (found) break;
|
|
292
480
|
|
|
293
|
-
await
|
|
294
|
-
field,
|
|
481
|
+
const nestedMatch = await someBlocksInNonLocalizedFieldValue(
|
|
295
482
|
block.attributes[field.attributes.api_key],
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
schemaRepository,
|
|
301
|
-
field,
|
|
302
|
-
valueForLocale,
|
|
303
|
-
predicate,
|
|
304
|
-
[
|
|
305
|
-
...path,
|
|
306
|
-
...innerPath,
|
|
307
|
-
'attributes',
|
|
308
|
-
field.attributes.api_key,
|
|
309
|
-
...(locale ? [locale] : []),
|
|
310
|
-
],
|
|
311
|
-
);
|
|
312
|
-
|
|
313
|
-
if (nestedMatch) {
|
|
314
|
-
found = true;
|
|
315
|
-
}
|
|
316
|
-
},
|
|
483
|
+
field.attributes.field_type,
|
|
484
|
+
schemaRepository,
|
|
485
|
+
predicate,
|
|
486
|
+
[...path, ...innerPath, 'attributes', field.attributes.api_key],
|
|
317
487
|
);
|
|
488
|
+
|
|
489
|
+
if (nestedMatch) {
|
|
490
|
+
found = true;
|
|
491
|
+
}
|
|
318
492
|
}
|
|
319
493
|
},
|
|
320
494
|
);
|
|
@@ -322,74 +496,180 @@ export async function someBlocksInFieldValues(
|
|
|
322
496
|
return found;
|
|
323
497
|
}
|
|
324
498
|
|
|
325
|
-
|
|
499
|
+
/**
|
|
500
|
+
* Recursively check if every block in the non-localized field value matches the predicate function.
|
|
501
|
+
* Tests both direct blocks and recursively tests nested blocks within block attributes.
|
|
502
|
+
* Returns false as soon as the first non-matching block is found anywhere in the hierarchy
|
|
503
|
+
* (short-circuit evaluation).
|
|
504
|
+
*
|
|
505
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to test
|
|
506
|
+
* @param fieldType - The type field (determines how the value is processed)
|
|
507
|
+
* @param schemaRepository - Repository for accessing DatoCMS schema information (to resolve block structures)
|
|
508
|
+
* @param predicate - Asynchronous function that tests each block, including nested ones
|
|
509
|
+
* @returns Promise that resolves to true if all blocks in the hierarchy match, false otherwise
|
|
510
|
+
*/
|
|
511
|
+
export async function everyBlockInNonLocalizedFieldValue<
|
|
512
|
+
T extends RecognizableFieldValue,
|
|
513
|
+
>(
|
|
514
|
+
nonLocalizedFieldValue: T,
|
|
515
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
326
516
|
schemaRepository: SchemaRepository,
|
|
327
|
-
field: RawApiTypes.Field | ApiTypes.Field,
|
|
328
|
-
value: unknown,
|
|
329
517
|
predicate: (
|
|
330
|
-
item:
|
|
518
|
+
item: ExtractNestedBlocksFromFieldValue<T>,
|
|
519
|
+
path: TreePath,
|
|
520
|
+
) => boolean | Promise<boolean>,
|
|
521
|
+
path?: TreePath,
|
|
522
|
+
): Promise<boolean>;
|
|
523
|
+
export async function everyBlockInNonLocalizedFieldValue(
|
|
524
|
+
nonLocalizedFieldValue: unknown,
|
|
525
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
526
|
+
schemaRepository: SchemaRepository,
|
|
527
|
+
predicate: (
|
|
528
|
+
item: BlockInRequest,
|
|
529
|
+
path: TreePath,
|
|
530
|
+
) => boolean | Promise<boolean>,
|
|
531
|
+
path?: TreePath,
|
|
532
|
+
): Promise<boolean>;
|
|
533
|
+
export async function everyBlockInNonLocalizedFieldValue(
|
|
534
|
+
nonLocalizedFieldValue: unknown,
|
|
535
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
536
|
+
schemaRepository: SchemaRepository,
|
|
537
|
+
predicate: (
|
|
538
|
+
item: BlockInRequest,
|
|
331
539
|
path: TreePath,
|
|
332
540
|
) => boolean | Promise<boolean>,
|
|
333
541
|
path: TreePath = [],
|
|
334
542
|
): Promise<boolean> {
|
|
335
|
-
return !(await
|
|
543
|
+
return !(await someBlocksInNonLocalizedFieldValue(
|
|
544
|
+
nonLocalizedFieldValue,
|
|
545
|
+
fieldType,
|
|
336
546
|
schemaRepository,
|
|
337
|
-
field,
|
|
338
|
-
value,
|
|
339
547
|
async (item, path) => !(await predicate(item, path)),
|
|
340
548
|
path,
|
|
341
549
|
));
|
|
342
550
|
}
|
|
343
551
|
|
|
344
|
-
|
|
552
|
+
// Converts fields
|
|
553
|
+
// RichTextFieldValueInNestedResponse<Block1>
|
|
554
|
+
// into their as-request variant
|
|
555
|
+
// RichTextFieldValueInRequest<Block1>
|
|
556
|
+
type FieldValueInRequest<T> = T extends RichTextFieldValueInNestedResponse<
|
|
557
|
+
infer D
|
|
558
|
+
>
|
|
559
|
+
? RichTextFieldValueInRequest<D>
|
|
560
|
+
: T extends SingleBlockFieldValueInNestedResponse<infer D>
|
|
561
|
+
? SingleBlockFieldValueInRequest<D>
|
|
562
|
+
: T extends StructuredTextFieldValueInNestedResponse<infer DB, infer DI>
|
|
563
|
+
? StructuredTextFieldValueInRequest<DB, DI>
|
|
564
|
+
: T extends StructuredTextFieldValueInNestedResponse<infer DB>
|
|
565
|
+
? StructuredTextFieldValueInRequest<DB>
|
|
566
|
+
: T;
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Recursively transform blocks in a non-localized field value by applying a mapping function to each block.
|
|
570
|
+
* Creates a new non-localized field value structure with transformed blocks while preserving the original
|
|
571
|
+
* structure. Applies the mapping function to both direct blocks and recursively to nested
|
|
572
|
+
* blocks within block attributes throughout the entire hierarchy.
|
|
573
|
+
*
|
|
574
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to transform
|
|
575
|
+
* @param fieldType - The type field (determines how the value is processed)
|
|
576
|
+
* @param schemaRepository - Repository for accessing DatoCMS schema information (to resolve block structures)
|
|
577
|
+
* @param mapper - Asynchronous function that transforms each block, including nested ones
|
|
578
|
+
* @param options - Optional configuration object
|
|
579
|
+
* @param options.traversalDirection - Direction of traversal: 'top-down' (default) applies mapper before processing children, 'bottom-up' processes children first
|
|
580
|
+
* @returns Promise that resolves to the new non-localized field value with recursively transformed blocks
|
|
581
|
+
*/
|
|
582
|
+
export async function mapBlocksInNonLocalizedFieldValue<
|
|
583
|
+
T extends RecognizableFieldValue,
|
|
584
|
+
>(
|
|
585
|
+
nonLocalizedFieldValue: T,
|
|
586
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
587
|
+
schemaRepository: SchemaRepository,
|
|
588
|
+
mapper: (
|
|
589
|
+
item: ExtractNestedBlocksFromFieldValue<T>,
|
|
590
|
+
path: TreePath,
|
|
591
|
+
) => BlockInRequest | Promise<BlockInRequest>,
|
|
592
|
+
options?: { traversalDirection?: TraversalDirection },
|
|
593
|
+
path?: TreePath,
|
|
594
|
+
): Promise<FieldValueInRequest<T>>;
|
|
595
|
+
export async function mapBlocksInNonLocalizedFieldValue(
|
|
596
|
+
nonLocalizedFieldValue: unknown,
|
|
597
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
598
|
+
schemaRepository: SchemaRepository,
|
|
599
|
+
mapper: (
|
|
600
|
+
item: BlockInRequest,
|
|
601
|
+
path: TreePath,
|
|
602
|
+
) => BlockInRequest | Promise<BlockInRequest>,
|
|
603
|
+
options?: { traversalDirection?: TraversalDirection },
|
|
604
|
+
path?: TreePath,
|
|
605
|
+
): Promise<unknown>;
|
|
606
|
+
export async function mapBlocksInNonLocalizedFieldValue(
|
|
607
|
+
nonLocalizedFieldValue: unknown,
|
|
608
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
345
609
|
schemaRepository: SchemaRepository,
|
|
346
|
-
field: RawApiTypes.Field | ApiTypes.Field,
|
|
347
|
-
value: unknown,
|
|
348
610
|
mapper: (
|
|
349
|
-
item:
|
|
611
|
+
item: BlockInRequest,
|
|
350
612
|
path: TreePath,
|
|
351
|
-
) =>
|
|
613
|
+
) => BlockInRequest | Promise<BlockInRequest>,
|
|
614
|
+
options: { traversalDirection?: TraversalDirection } = {},
|
|
352
615
|
path: TreePath = [],
|
|
353
|
-
) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
616
|
+
): Promise<unknown> {
|
|
617
|
+
const { traversalDirection = 'top-down' } = options;
|
|
618
|
+
|
|
619
|
+
return nonRecursiveMapBlocksInNonLocalizedFieldValueAsync(
|
|
620
|
+
fieldType,
|
|
621
|
+
nonLocalizedFieldValue,
|
|
357
622
|
async (block, innerPath) => {
|
|
358
|
-
const
|
|
623
|
+
const blockPath = [...path, ...innerPath];
|
|
359
624
|
|
|
360
|
-
if (!isItemWithOptionalIdAndMeta(
|
|
361
|
-
return
|
|
625
|
+
if (!isItemWithOptionalIdAndMeta(block)) {
|
|
626
|
+
return await mapper(block, blockPath);
|
|
362
627
|
}
|
|
363
628
|
|
|
364
629
|
const itemType = await schemaRepository.getRawItemTypeById(
|
|
365
|
-
|
|
630
|
+
block.relationships.item_type.data.id,
|
|
366
631
|
);
|
|
367
632
|
|
|
368
633
|
const fields = await schemaRepository.getRawItemTypeFields(itemType);
|
|
369
634
|
|
|
635
|
+
if (traversalDirection === 'top-down') {
|
|
636
|
+
const newBlock = await mapper(block, blockPath);
|
|
637
|
+
|
|
638
|
+
if (!isItemWithOptionalIdAndMeta(newBlock)) {
|
|
639
|
+
return newBlock;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
for (const field of fields) {
|
|
643
|
+
newBlock.attributes[field.attributes.api_key] =
|
|
644
|
+
await mapBlocksInNonLocalizedFieldValue(
|
|
645
|
+
newBlock.attributes[field.attributes.api_key],
|
|
646
|
+
field.attributes.field_type,
|
|
647
|
+
schemaRepository,
|
|
648
|
+
mapper,
|
|
649
|
+
options,
|
|
650
|
+
[...blockPath, 'attributes', field.attributes.api_key],
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
return newBlock;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const blockCopy = { ...block };
|
|
658
|
+
|
|
370
659
|
for (const field of fields) {
|
|
371
|
-
|
|
372
|
-
await
|
|
373
|
-
field,
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
mapper,
|
|
381
|
-
[
|
|
382
|
-
...path,
|
|
383
|
-
...innerPath,
|
|
384
|
-
'attributes',
|
|
385
|
-
field.attributes.api_key,
|
|
386
|
-
...(locale ? [locale] : []),
|
|
387
|
-
],
|
|
388
|
-
),
|
|
660
|
+
blockCopy.attributes[field.attributes.api_key] =
|
|
661
|
+
await mapBlocksInNonLocalizedFieldValue(
|
|
662
|
+
blockCopy.attributes[field.attributes.api_key],
|
|
663
|
+
field.attributes.field_type,
|
|
664
|
+
schemaRepository,
|
|
665
|
+
|
|
666
|
+
mapper,
|
|
667
|
+
options,
|
|
668
|
+
[...blockPath, 'attributes', field.attributes.api_key],
|
|
389
669
|
);
|
|
390
670
|
}
|
|
391
671
|
|
|
392
|
-
return
|
|
672
|
+
return await mapper(blockCopy, blockPath);
|
|
393
673
|
},
|
|
394
674
|
);
|
|
395
675
|
}
|