@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
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DatoCMS Block Field Value Processing Utilities
|
|
3
|
+
*
|
|
4
|
+
* This utility provides a unified interface for working with blocks embedded within DatoCMS field values.
|
|
5
|
+
* DatoCMS supports three field types that can contain blocks:
|
|
6
|
+
* - Modular Content fields: arrays of blocks
|
|
7
|
+
* - Single Block fields: a single block
|
|
8
|
+
* - Structured Text fields: complex document structures with embedded blocks
|
|
9
|
+
*
|
|
10
|
+
* The challenge this solves: Each field type stores blocks differently and requires different
|
|
11
|
+
* traversal logic, making it complex to perform operations like transformations, filtering,
|
|
12
|
+
* or searching across blocks regardless of their containing field type.
|
|
13
|
+
*
|
|
14
|
+
* This utility abstracts away these differences, providing a consistent API to:
|
|
15
|
+
* - Visit/iterate through all blocks in any field type
|
|
16
|
+
* - Transform blocks while preserving field structure
|
|
17
|
+
* - Filter blocks based on conditions
|
|
18
|
+
* - Search for specific blocks
|
|
19
|
+
* - Perform functional operations (map, reduce, some, every)
|
|
20
|
+
*
|
|
21
|
+
* All functions come in both sync and async variants to support different use cases,
|
|
22
|
+
* particularly useful when block transformations require async operations like API calls.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
type TreePath,
|
|
27
|
+
collectNodesAsync,
|
|
28
|
+
filterNodesAsync,
|
|
29
|
+
mapNodes,
|
|
30
|
+
mapNodesAsync,
|
|
31
|
+
} from 'datocms-structured-text-utils';
|
|
32
|
+
import type {
|
|
33
|
+
BlockInRequest,
|
|
34
|
+
RichTextFieldValue,
|
|
35
|
+
RichTextFieldValueInNestedResponse,
|
|
36
|
+
RichTextFieldValueInRequest,
|
|
37
|
+
SingleBlockFieldValue,
|
|
38
|
+
SingleBlockFieldValueInNestedResponse,
|
|
39
|
+
SingleBlockFieldValueInRequest,
|
|
40
|
+
StructuredTextFieldValue,
|
|
41
|
+
StructuredTextFieldValueInNestedResponse,
|
|
42
|
+
StructuredTextFieldValueInRequest,
|
|
43
|
+
} from '../fieldTypes';
|
|
44
|
+
import type * as ApiTypes from '../generated/ApiTypes';
|
|
45
|
+
|
|
46
|
+
type PossibleRichTextValue =
|
|
47
|
+
| RichTextFieldValue
|
|
48
|
+
| RichTextFieldValueInRequest
|
|
49
|
+
| RichTextFieldValueInNestedResponse;
|
|
50
|
+
type PossibleSingleBlockValue =
|
|
51
|
+
| SingleBlockFieldValue
|
|
52
|
+
| SingleBlockFieldValueInRequest
|
|
53
|
+
| SingleBlockFieldValueInNestedResponse;
|
|
54
|
+
type PossibleStructuredTextValue =
|
|
55
|
+
| StructuredTextFieldValue
|
|
56
|
+
| StructuredTextFieldValueInRequest
|
|
57
|
+
| StructuredTextFieldValueInNestedResponse;
|
|
58
|
+
|
|
59
|
+
async function* iterateBlocksAsync(
|
|
60
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
61
|
+
nonLocalizedFieldValue: unknown,
|
|
62
|
+
): AsyncGenerator<{ item: BlockInRequest; path: TreePath }> {
|
|
63
|
+
if (fieldType === 'rich_text') {
|
|
64
|
+
const richTextValue = nonLocalizedFieldValue as PossibleRichTextValue;
|
|
65
|
+
if (richTextValue) {
|
|
66
|
+
for (let index = 0; index < richTextValue.length; index++) {
|
|
67
|
+
const item = richTextValue[index]!;
|
|
68
|
+
yield { item, path: [index] };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (fieldType === 'single_block') {
|
|
75
|
+
const singleBlockValue = nonLocalizedFieldValue as PossibleSingleBlockValue;
|
|
76
|
+
if (singleBlockValue) {
|
|
77
|
+
yield { item: singleBlockValue, path: [] };
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (fieldType === 'structured_text') {
|
|
83
|
+
const structuredTextValue =
|
|
84
|
+
nonLocalizedFieldValue as PossibleStructuredTextValue;
|
|
85
|
+
if (structuredTextValue) {
|
|
86
|
+
const foundNodes = await collectNodesAsync(
|
|
87
|
+
structuredTextValue.document,
|
|
88
|
+
async (node) => node.type === 'block' || node.type === 'inlineBlock',
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
for (const { node, path } of foundNodes) {
|
|
92
|
+
if (node.type === 'block' || node.type === 'inlineBlock') {
|
|
93
|
+
yield { item: node.item, path };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Visit every block in a field value, calling the visitor function for each block found.
|
|
103
|
+
* Supports rich text, single block, and structured text field types.
|
|
104
|
+
*
|
|
105
|
+
* @param fieldType - The type of DatoCMS field definition that determines how the value is processed
|
|
106
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to visit
|
|
107
|
+
* @param visitor - Asynchronous function called for each block. Receives the block item and its path
|
|
108
|
+
* @returns Promise that resolves when all blocks have been visited
|
|
109
|
+
*/
|
|
110
|
+
export async function nonRecursiveVisitBlocksInNonLocalizedFieldValueAsync(
|
|
111
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
112
|
+
nonLocalizedFieldValue: unknown,
|
|
113
|
+
visitor: (item: BlockInRequest, path: TreePath) => Promise<void>,
|
|
114
|
+
): Promise<void> {
|
|
115
|
+
for await (const { item, path } of iterateBlocksAsync(
|
|
116
|
+
fieldType,
|
|
117
|
+
nonLocalizedFieldValue,
|
|
118
|
+
)) {
|
|
119
|
+
await visitor(item, path);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Transform blocks in a field value by applying a mapping function to each block.
|
|
125
|
+
* Creates a new field value structure with transformed blocks while preserving the original structure.
|
|
126
|
+
* Supports rich text, single block, and structured text field types.
|
|
127
|
+
*
|
|
128
|
+
* @param fieldType - The type of DatoCMS field definition that determines how the value is processed
|
|
129
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to transform
|
|
130
|
+
* @param mapper - Synchronous function that transforms each block. Receives block item and path, returns new block
|
|
131
|
+
* @returns The new field value with transformed blocks
|
|
132
|
+
*/
|
|
133
|
+
export function nonRecursiveMapBlocksInNonLocalizedFieldValue(
|
|
134
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
135
|
+
nonLocalizedFieldValue: unknown,
|
|
136
|
+
mapper: (item: BlockInRequest, path: TreePath) => BlockInRequest,
|
|
137
|
+
): unknown {
|
|
138
|
+
if (fieldType === 'rich_text') {
|
|
139
|
+
const richTextValue = nonLocalizedFieldValue as PossibleRichTextValue;
|
|
140
|
+
return richTextValue
|
|
141
|
+
? richTextValue.map((item, index) => mapper(item, [index]))
|
|
142
|
+
: richTextValue;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (fieldType === 'single_block') {
|
|
146
|
+
const singleBlockValue = nonLocalizedFieldValue as PossibleSingleBlockValue;
|
|
147
|
+
return singleBlockValue ? mapper(singleBlockValue, []) : null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (fieldType === 'structured_text') {
|
|
151
|
+
const structuredTextValue =
|
|
152
|
+
nonLocalizedFieldValue as PossibleStructuredTextValue;
|
|
153
|
+
|
|
154
|
+
if (!structuredTextValue) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
schema: 'dast',
|
|
160
|
+
document: mapNodes(
|
|
161
|
+
structuredTextValue.document,
|
|
162
|
+
(node, _parent, path) => {
|
|
163
|
+
if (node.type === 'block' || node.type === 'inlineBlock') {
|
|
164
|
+
return { ...node, item: mapper(node.item, path) };
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return node;
|
|
168
|
+
},
|
|
169
|
+
),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return nonLocalizedFieldValue;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Transform blocks in a field value by applying a mapping function to each block.
|
|
178
|
+
* Creates a new field value structure with transformed blocks while preserving the original structure.
|
|
179
|
+
* Supports rich text, single block, and structured text field types.
|
|
180
|
+
*
|
|
181
|
+
* @param fieldType - The type of DatoCMS field definition that determines how the value is processed
|
|
182
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to transform
|
|
183
|
+
* @param mapper - Asynchronous function that transforms each block. Receives block item and path, returns new block
|
|
184
|
+
* @returns Promise that resolves to the new field value with transformed blocks
|
|
185
|
+
*/
|
|
186
|
+
export async function nonRecursiveMapBlocksInNonLocalizedFieldValueAsync(
|
|
187
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
188
|
+
nonLocalizedFieldValue: unknown,
|
|
189
|
+
mapper: (item: BlockInRequest, path: TreePath) => Promise<BlockInRequest>,
|
|
190
|
+
): Promise<unknown> {
|
|
191
|
+
if (fieldType === 'rich_text') {
|
|
192
|
+
const richTextValue = nonLocalizedFieldValue as PossibleRichTextValue;
|
|
193
|
+
return richTextValue
|
|
194
|
+
? await Promise.all(
|
|
195
|
+
richTextValue.map((item, index) => mapper(item, [index])),
|
|
196
|
+
)
|
|
197
|
+
: richTextValue;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (fieldType === 'single_block') {
|
|
201
|
+
const singleBlockValue = nonLocalizedFieldValue as PossibleSingleBlockValue;
|
|
202
|
+
return singleBlockValue ? await mapper(singleBlockValue, []) : null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (fieldType === 'structured_text') {
|
|
206
|
+
const structuredTextValue =
|
|
207
|
+
nonLocalizedFieldValue as PossibleStructuredTextValue;
|
|
208
|
+
|
|
209
|
+
if (!structuredTextValue) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
schema: 'dast',
|
|
215
|
+
document: await mapNodesAsync(
|
|
216
|
+
structuredTextValue.document,
|
|
217
|
+
async (node, _parent, path) => {
|
|
218
|
+
if (node.type === 'block' || node.type === 'inlineBlock') {
|
|
219
|
+
return { ...node, item: await mapper(node.item, path) };
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return node;
|
|
223
|
+
},
|
|
224
|
+
),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return nonLocalizedFieldValue;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Find all blocks that match the predicate function.
|
|
233
|
+
* Searches through all blocks in the non-localized field value and returns all matches.
|
|
234
|
+
*
|
|
235
|
+
* @param fieldType - The type of DatoCMS field definition that determines how the value is processed
|
|
236
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to search
|
|
237
|
+
* @param predicate - Asynchronous function that tests each block. Should return true for matching blocks
|
|
238
|
+
* @returns Promise that resolves to an array of objects, each containing a matching block and its path
|
|
239
|
+
*/
|
|
240
|
+
export async function nonRecursiveFindAllBlocksInNonLocalizedFieldValueAsync(
|
|
241
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
242
|
+
nonLocalizedFieldValue: unknown,
|
|
243
|
+
predicate: (item: BlockInRequest, path: TreePath) => Promise<boolean>,
|
|
244
|
+
): Promise<Array<{ item: BlockInRequest; path: TreePath }>> {
|
|
245
|
+
const results: Array<{ item: BlockInRequest; path: TreePath }> = [];
|
|
246
|
+
|
|
247
|
+
for await (const { item, path } of iterateBlocksAsync(
|
|
248
|
+
fieldType,
|
|
249
|
+
nonLocalizedFieldValue,
|
|
250
|
+
)) {
|
|
251
|
+
if (await predicate(item, path)) {
|
|
252
|
+
results.push({ item, path });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return results;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Filter blocks in a field value, removing those that don't match the predicate.
|
|
261
|
+
* Creates a new field value containing only blocks that pass the predicate test.
|
|
262
|
+
* Preserves the original field value structure and hierarchy.
|
|
263
|
+
*
|
|
264
|
+
* @param fieldType - The type of DatoCMS field definition that determines how the value is processed
|
|
265
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to filter
|
|
266
|
+
* @param predicate - Asynchronous function that tests each block. Blocks returning false are removed
|
|
267
|
+
* @returns Promise that resolves to the new field value with filtered blocks
|
|
268
|
+
*/
|
|
269
|
+
export async function nonRecursiveFilterBlocksInNonLocalizedFieldValueAsync(
|
|
270
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
271
|
+
nonLocalizedFieldValue: unknown,
|
|
272
|
+
predicate: (item: BlockInRequest, path: TreePath) => Promise<boolean>,
|
|
273
|
+
): Promise<unknown> {
|
|
274
|
+
if (fieldType === 'rich_text') {
|
|
275
|
+
const filteredItems: BlockInRequest[] = [];
|
|
276
|
+
|
|
277
|
+
for await (const { item, path } of iterateBlocksAsync(
|
|
278
|
+
fieldType,
|
|
279
|
+
nonLocalizedFieldValue,
|
|
280
|
+
)) {
|
|
281
|
+
if (await predicate(item, path)) {
|
|
282
|
+
filteredItems.push(item);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return filteredItems;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (fieldType === 'single_block') {
|
|
290
|
+
for await (const { item, path } of iterateBlocksAsync(
|
|
291
|
+
fieldType,
|
|
292
|
+
nonLocalizedFieldValue,
|
|
293
|
+
)) {
|
|
294
|
+
if (await predicate(item, path)) {
|
|
295
|
+
return item;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (fieldType === 'structured_text') {
|
|
302
|
+
const structuredTextValue =
|
|
303
|
+
nonLocalizedFieldValue as PossibleStructuredTextValue;
|
|
304
|
+
|
|
305
|
+
if (!structuredTextValue) {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const filteredDocument = await filterNodesAsync(
|
|
310
|
+
structuredTextValue.document,
|
|
311
|
+
async (node, _parent, path) => {
|
|
312
|
+
if (node.type === 'block' || node.type === 'inlineBlock') {
|
|
313
|
+
return await predicate(node.item, path);
|
|
314
|
+
}
|
|
315
|
+
return true;
|
|
316
|
+
},
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
return filteredDocument
|
|
320
|
+
? {
|
|
321
|
+
schema: 'dast',
|
|
322
|
+
document: filteredDocument,
|
|
323
|
+
}
|
|
324
|
+
: null;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return nonLocalizedFieldValue;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Reduce all blocks in a field value to a single value by applying a reducer function.
|
|
332
|
+
* Processes each block in the non-localized field value and accumulates the results into a single value.
|
|
333
|
+
*
|
|
334
|
+
* @template R - The type of the accumulated result
|
|
335
|
+
* @param fieldType - The type of DatoCMS field definition that determines how the value is processed
|
|
336
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to reduce
|
|
337
|
+
* @param reducer - Asynchronous function that processes each block and updates the accumulator
|
|
338
|
+
* @param initialValue - The initial value for the accumulator
|
|
339
|
+
* @returns Promise that resolves to the final accumulated value
|
|
340
|
+
*/
|
|
341
|
+
export async function nonRecursiveReduceBlocksInNonLocalizedFieldValueAsync<R>(
|
|
342
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
343
|
+
nonLocalizedFieldValue: unknown,
|
|
344
|
+
reducer: (accumulator: R, item: BlockInRequest, path: TreePath) => Promise<R>,
|
|
345
|
+
initialValue: R,
|
|
346
|
+
): Promise<R> {
|
|
347
|
+
let accumulator = initialValue;
|
|
348
|
+
|
|
349
|
+
for await (const { item, path } of iterateBlocksAsync(
|
|
350
|
+
fieldType,
|
|
351
|
+
nonLocalizedFieldValue,
|
|
352
|
+
)) {
|
|
353
|
+
accumulator = await reducer(accumulator, item, path);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return accumulator;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Check if any block in the non-localized field value matches the predicate function.
|
|
361
|
+
* Returns true as soon as the first matching block is found (short-circuit evaluation).
|
|
362
|
+
*
|
|
363
|
+
* @param fieldType - The type of DatoCMS field definition that determines how the value is processed
|
|
364
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to test
|
|
365
|
+
* @param predicate - Asynchronous function that tests each block. Should return true for matching blocks
|
|
366
|
+
* @returns Promise that resolves to true if any block matches, false otherwise
|
|
367
|
+
*/
|
|
368
|
+
export async function nonRecursiveSomeBlocksInNonLocalizedFieldValueAsync(
|
|
369
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
370
|
+
nonLocalizedFieldValue: unknown,
|
|
371
|
+
predicate: (item: BlockInRequest, path: TreePath) => Promise<boolean>,
|
|
372
|
+
): Promise<boolean> {
|
|
373
|
+
for await (const { item, path } of iterateBlocksAsync(
|
|
374
|
+
fieldType,
|
|
375
|
+
nonLocalizedFieldValue,
|
|
376
|
+
)) {
|
|
377
|
+
if (await predicate(item, path)) {
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Check if every block in the non-localized field value matches the predicate function.
|
|
387
|
+
* Returns false as soon as the first non-matching block is found (short-circuit evaluation).
|
|
388
|
+
*
|
|
389
|
+
* @param fieldType - The type of DatoCMS field definition that determines how the value is processed
|
|
390
|
+
* @param nonLocalizedFieldValue - The non-localized field value containing blocks to test
|
|
391
|
+
* @param predicate - Asynchronous function that tests each block. Should return true for valid blocks
|
|
392
|
+
* @returns Promise that resolves to true if all blocks match, false otherwise
|
|
393
|
+
*/
|
|
394
|
+
export async function nonRecursiveEveryBlockInNonLocalizedFieldValueAsync(
|
|
395
|
+
fieldType: ApiTypes.Field['field_type'],
|
|
396
|
+
nonLocalizedFieldValue: unknown,
|
|
397
|
+
predicate: (item: BlockInRequest, path: TreePath) => Promise<boolean>,
|
|
398
|
+
): Promise<boolean> {
|
|
399
|
+
return !(await nonRecursiveSomeBlocksInNonLocalizedFieldValueAsync(
|
|
400
|
+
fieldType,
|
|
401
|
+
nonLocalizedFieldValue,
|
|
402
|
+
async (item, path) => {
|
|
403
|
+
return !(await predicate(item, path));
|
|
404
|
+
},
|
|
405
|
+
));
|
|
406
|
+
}
|
|
@@ -47,6 +47,25 @@ export function isLocalized(
|
|
|
47
47
|
return 'attributes' in field ? field.attributes.localized : field.localized;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
export function isLocalizedFieldValue<T = unknown, L extends string = string>(
|
|
51
|
+
value: unknown,
|
|
52
|
+
): value is LocalizedFieldValue<T, L> {
|
|
53
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const keys = Object.keys(value);
|
|
58
|
+
|
|
59
|
+
if (keys.length === 0) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const localePattern =
|
|
64
|
+
/^[A-Za-z]{2,4}(-[A-Za-z]{4})?(-([A-Za-z]{2}|[0-9]{3}))?$/;
|
|
65
|
+
|
|
66
|
+
return keys.every((key) => localePattern.test(key));
|
|
67
|
+
}
|
|
68
|
+
|
|
50
69
|
/**
|
|
51
70
|
* A normalized entry that represents a single value from either a localized or non-localized field.
|
|
52
71
|
*
|
|
@@ -55,7 +74,10 @@ export function isLocalized(
|
|
|
55
74
|
*
|
|
56
75
|
* This uniform structure allows the same processing logic to work with both field types.
|
|
57
76
|
*/
|
|
58
|
-
export type
|
|
77
|
+
export type NormalizedFieldValueEntry<
|
|
78
|
+
T = unknown,
|
|
79
|
+
L extends string = string,
|
|
80
|
+
> = {
|
|
59
81
|
locale: L | undefined;
|
|
60
82
|
value: T;
|
|
61
83
|
};
|
|
@@ -70,10 +92,13 @@ export type FieldValueEntry<T = unknown, L extends string = string> = {
|
|
|
70
92
|
* @param value - The field value to convert (either a localized object or direct value)
|
|
71
93
|
* @returns Array of entries where each entry contains a locale (string for localized, undefined for non-localized) and the corresponding value
|
|
72
94
|
*/
|
|
73
|
-
export function
|
|
95
|
+
export function toNormalizedFieldValueEntries<
|
|
96
|
+
T = unknown,
|
|
97
|
+
L extends string = string,
|
|
98
|
+
>(
|
|
74
99
|
field: RawApiTypes.Field | ApiTypes.Field,
|
|
75
100
|
value: T | LocalizedFieldValue<T, L>,
|
|
76
|
-
):
|
|
101
|
+
): NormalizedFieldValueEntry<T, L>[] {
|
|
77
102
|
if (isLocalized(field)) {
|
|
78
103
|
const localizedValue = value as LocalizedFieldValue<T, L>;
|
|
79
104
|
|
|
@@ -89,7 +114,7 @@ export function fieldValueToEntries<T = unknown, L extends string = string>(
|
|
|
89
114
|
/**
|
|
90
115
|
* Converts an array of possibly localized entries back into the appropriate field value format.
|
|
91
116
|
*
|
|
92
|
-
* This function is the inverse of `
|
|
117
|
+
* This function is the inverse of `toNormalizedFieldValueEntries`. It takes a uniform
|
|
93
118
|
* array of entries and converts them back to either a localized object or a direct value,
|
|
94
119
|
* depending on the field's localization setting.
|
|
95
120
|
*
|
|
@@ -97,9 +122,12 @@ export function fieldValueToEntries<T = unknown, L extends string = string>(
|
|
|
97
122
|
* @param entries - Array of entries to convert back to field value format
|
|
98
123
|
* @returns Either a localized object (for localized fields) or the direct value (for non-localized fields)
|
|
99
124
|
*/
|
|
100
|
-
export function
|
|
125
|
+
export function fromNormalizedFieldValueEntries<
|
|
126
|
+
T = unknown,
|
|
127
|
+
L extends string = string,
|
|
128
|
+
>(
|
|
101
129
|
field: RawApiTypes.Field | ApiTypes.Field,
|
|
102
|
-
entries:
|
|
130
|
+
entries: NormalizedFieldValueEntry<T, L>[],
|
|
103
131
|
): T | LocalizedFieldValue<T, L> {
|
|
104
132
|
if (isLocalized(field)) {
|
|
105
133
|
return Object.fromEntries(
|
|
@@ -125,7 +153,7 @@ export function entriesToFieldValue<T = unknown, L extends string = string>(
|
|
|
125
153
|
* @param mapFn - The function to apply to each locale value or the direct value
|
|
126
154
|
* @returns The mapped value with the same structure as the input
|
|
127
155
|
*/
|
|
128
|
-
export function
|
|
156
|
+
export function mapNormalizedFieldValues<
|
|
129
157
|
TInput = unknown,
|
|
130
158
|
TOutput = unknown,
|
|
131
159
|
L extends string = string,
|
|
@@ -134,12 +162,12 @@ export function mapFieldValue<
|
|
|
134
162
|
value: TInput | LocalizedFieldValue<TInput, L>,
|
|
135
163
|
mapFn: (locale: L | undefined, localeValue: TInput) => TOutput,
|
|
136
164
|
): TOutput | LocalizedFieldValue<TOutput, L> {
|
|
137
|
-
const entries =
|
|
165
|
+
const entries = toNormalizedFieldValueEntries<TInput, L>(field, value);
|
|
138
166
|
const mappedEntries = entries.map(({ locale, value }) => ({
|
|
139
167
|
locale,
|
|
140
168
|
value: mapFn(locale, value),
|
|
141
169
|
}));
|
|
142
|
-
return
|
|
170
|
+
return fromNormalizedFieldValueEntries<TOutput, L>(field, mappedEntries);
|
|
143
171
|
}
|
|
144
172
|
|
|
145
173
|
/**
|
|
@@ -153,7 +181,7 @@ export function mapFieldValue<
|
|
|
153
181
|
* @param mapFn - The function to apply to each locale value or the direct value
|
|
154
182
|
* @returns The mapped value with the same structure as the input
|
|
155
183
|
*/
|
|
156
|
-
export async function
|
|
184
|
+
export async function mapNormalizedFieldValuesAsync<
|
|
157
185
|
TInput = unknown,
|
|
158
186
|
TOutput = unknown,
|
|
159
187
|
L extends string = string,
|
|
@@ -162,14 +190,14 @@ export async function mapFieldValueAsync<
|
|
|
162
190
|
value: TInput | LocalizedFieldValue<TInput, L>,
|
|
163
191
|
mapFn: (locale: L | undefined, localeValue: TInput) => Promise<TOutput>,
|
|
164
192
|
): Promise<TOutput | LocalizedFieldValue<TOutput, L>> {
|
|
165
|
-
const entries =
|
|
193
|
+
const entries = toNormalizedFieldValueEntries<TInput, L>(field, value);
|
|
166
194
|
const mappedEntries = await Promise.all(
|
|
167
195
|
entries.map(async ({ locale, value }) => ({
|
|
168
196
|
locale,
|
|
169
197
|
value: await mapFn(locale, value),
|
|
170
198
|
})),
|
|
171
199
|
);
|
|
172
|
-
return
|
|
200
|
+
return fromNormalizedFieldValueEntries<TOutput, L>(field, mappedEntries);
|
|
173
201
|
}
|
|
174
202
|
|
|
175
203
|
/**
|
|
@@ -182,18 +210,21 @@ export async function mapFieldValueAsync<
|
|
|
182
210
|
* @param filterFn - The function to test each locale value or the direct value
|
|
183
211
|
* @returns The filtered value with the same structure as the input
|
|
184
212
|
*/
|
|
185
|
-
export function
|
|
213
|
+
export function filterNormalizedFieldValues<
|
|
214
|
+
T = unknown,
|
|
215
|
+
L extends string = string,
|
|
216
|
+
>(
|
|
186
217
|
field: RawApiTypes.Field | ApiTypes.Field,
|
|
187
218
|
value: T | LocalizedFieldValue<T, L>,
|
|
188
219
|
filterFn: (locale: L | undefined, localeValue: T) => boolean,
|
|
189
220
|
): T | LocalizedFieldValue<T, L> | undefined {
|
|
190
|
-
const entries =
|
|
221
|
+
const entries = toNormalizedFieldValueEntries<T, L>(field, value);
|
|
191
222
|
const filteredEntries = entries.filter((entry) =>
|
|
192
223
|
filterFn(entry.locale, entry.value),
|
|
193
224
|
);
|
|
194
225
|
|
|
195
226
|
if (isLocalized(field)) {
|
|
196
|
-
return
|
|
227
|
+
return fromNormalizedFieldValueEntries<T, L>(field, filteredEntries);
|
|
197
228
|
}
|
|
198
229
|
|
|
199
230
|
return filteredEntries.length > 0 ? filteredEntries[0]?.value : undefined;
|
|
@@ -209,7 +240,7 @@ export function filterFieldValue<T = unknown, L extends string = string>(
|
|
|
209
240
|
* @param filterFn - The function to test each locale value or the direct value
|
|
210
241
|
* @returns The filtered value with the same structure as the input
|
|
211
242
|
*/
|
|
212
|
-
export async function
|
|
243
|
+
export async function filterNormalizedFieldValuesAsync<
|
|
213
244
|
T = unknown,
|
|
214
245
|
L extends string = string,
|
|
215
246
|
>(
|
|
@@ -217,7 +248,7 @@ export async function filterFieldValueAsync<
|
|
|
217
248
|
value: T | LocalizedFieldValue<T, L>,
|
|
218
249
|
filterFn: (locale: L | undefined, localeValue: T) => Promise<boolean>,
|
|
219
250
|
): Promise<T | LocalizedFieldValue<T, L> | undefined> {
|
|
220
|
-
const entries =
|
|
251
|
+
const entries = toNormalizedFieldValueEntries<T, L>(field, value);
|
|
221
252
|
const results = await Promise.all(
|
|
222
253
|
entries.map(async ({ locale, value }) => ({
|
|
223
254
|
locale,
|
|
@@ -231,7 +262,7 @@ export async function filterFieldValueAsync<
|
|
|
231
262
|
.map(({ locale, value }) => ({ locale, value }));
|
|
232
263
|
|
|
233
264
|
if (isLocalized(field)) {
|
|
234
|
-
return
|
|
265
|
+
return fromNormalizedFieldValueEntries<T, L>(field, filteredEntries);
|
|
235
266
|
}
|
|
236
267
|
|
|
237
268
|
return filteredEntries.length > 0 ? filteredEntries[0]?.value : undefined;
|
|
@@ -247,12 +278,15 @@ export async function filterFieldValueAsync<
|
|
|
247
278
|
* @param testFn - The function to test each locale value or the direct value
|
|
248
279
|
* @returns true if at least one value passes the test, false otherwise
|
|
249
280
|
*/
|
|
250
|
-
export function
|
|
281
|
+
export function someNormalizedFieldValues<
|
|
282
|
+
T = unknown,
|
|
283
|
+
L extends string = string,
|
|
284
|
+
>(
|
|
251
285
|
field: RawApiTypes.Field | ApiTypes.Field,
|
|
252
286
|
value: T | LocalizedFieldValue<T, L>,
|
|
253
287
|
testFn: (locale: L | undefined, localeValue: T) => boolean,
|
|
254
288
|
): boolean {
|
|
255
|
-
const entries =
|
|
289
|
+
const entries = toNormalizedFieldValueEntries<T, L>(field, value);
|
|
256
290
|
return entries.some(({ locale, value }) => testFn(locale, value));
|
|
257
291
|
}
|
|
258
292
|
|
|
@@ -266,7 +300,7 @@ export function someFieldValue<T = unknown, L extends string = string>(
|
|
|
266
300
|
* @param testFn - The function to test each locale value or the direct value
|
|
267
301
|
* @returns true if at least one value passes the test, false otherwise
|
|
268
302
|
*/
|
|
269
|
-
export async function
|
|
303
|
+
export async function someNormalizedFieldValuesAsync<
|
|
270
304
|
T = unknown,
|
|
271
305
|
L extends string = string,
|
|
272
306
|
>(
|
|
@@ -274,7 +308,7 @@ export async function someFieldValueAsync<
|
|
|
274
308
|
value: T | LocalizedFieldValue<T, L>,
|
|
275
309
|
testFn: (locale: L | undefined, localeValue: T) => Promise<boolean>,
|
|
276
310
|
): Promise<boolean> {
|
|
277
|
-
const entries =
|
|
311
|
+
const entries = toNormalizedFieldValueEntries<T, L>(field, value);
|
|
278
312
|
const results = await Promise.all(
|
|
279
313
|
entries.map(({ locale, value }) => testFn(locale, value)),
|
|
280
314
|
);
|
|
@@ -291,12 +325,15 @@ export async function someFieldValueAsync<
|
|
|
291
325
|
* @param testFn - The function to test each locale value or the direct value
|
|
292
326
|
* @returns true if all values pass the test, false otherwise
|
|
293
327
|
*/
|
|
294
|
-
export function
|
|
328
|
+
export function everyNormalizedFieldValue<
|
|
329
|
+
T = unknown,
|
|
330
|
+
L extends string = string,
|
|
331
|
+
>(
|
|
295
332
|
field: RawApiTypes.Field | ApiTypes.Field,
|
|
296
333
|
value: T | LocalizedFieldValue<T, L>,
|
|
297
334
|
testFn: (locale: L | undefined, localeValue: T) => boolean,
|
|
298
335
|
): boolean {
|
|
299
|
-
return !
|
|
336
|
+
return !someNormalizedFieldValues(
|
|
300
337
|
field,
|
|
301
338
|
value,
|
|
302
339
|
(locale, localeValue) => !testFn(locale, localeValue),
|
|
@@ -313,7 +350,7 @@ export function everyFieldValue<T = unknown, L extends string = string>(
|
|
|
313
350
|
* @param testFn - The function to test each locale value or the direct value
|
|
314
351
|
* @returns true if all values pass the test, false otherwise
|
|
315
352
|
*/
|
|
316
|
-
export async function
|
|
353
|
+
export async function everyNormalizedFieldValueAsync<
|
|
317
354
|
T = unknown,
|
|
318
355
|
L extends string = string,
|
|
319
356
|
>(
|
|
@@ -321,7 +358,7 @@ export async function everyFieldValueAsync<
|
|
|
321
358
|
value: T | LocalizedFieldValue<T, L>,
|
|
322
359
|
testFn: (locale: L | undefined, localeValue: T) => Promise<boolean>,
|
|
323
360
|
): Promise<boolean> {
|
|
324
|
-
return !(await
|
|
361
|
+
return !(await someNormalizedFieldValuesAsync(
|
|
325
362
|
field,
|
|
326
363
|
value,
|
|
327
364
|
async (locale, localeValue) => !(await testFn(locale, localeValue)),
|
|
@@ -337,12 +374,15 @@ export async function everyFieldValueAsync<
|
|
|
337
374
|
* @param value - The field value (either localized object or direct value)
|
|
338
375
|
* @param visitFn - The function to call for each locale value or the direct value
|
|
339
376
|
*/
|
|
340
|
-
export function
|
|
377
|
+
export function visitNormalizedFieldValues<
|
|
378
|
+
T = unknown,
|
|
379
|
+
L extends string = string,
|
|
380
|
+
>(
|
|
341
381
|
field: RawApiTypes.Field | ApiTypes.Field,
|
|
342
382
|
value: T | LocalizedFieldValue<T, L>,
|
|
343
383
|
visitFn: (locale: L | undefined, localeValue: T) => void,
|
|
344
384
|
): void {
|
|
345
|
-
const entries =
|
|
385
|
+
const entries = toNormalizedFieldValueEntries<T, L>(field, value);
|
|
346
386
|
for (const { locale, value } of entries) {
|
|
347
387
|
visitFn(locale, value);
|
|
348
388
|
}
|
|
@@ -357,7 +397,7 @@ export function visitFieldValue<T = unknown, L extends string = string>(
|
|
|
357
397
|
* @param value - The field value (either localized object or direct value)
|
|
358
398
|
* @param visitFn - The function to call for each locale value or the direct value
|
|
359
399
|
*/
|
|
360
|
-
export async function
|
|
400
|
+
export async function visitNormalizedFieldValuesAsync<
|
|
361
401
|
T = unknown,
|
|
362
402
|
L extends string = string,
|
|
363
403
|
>(
|
|
@@ -365,6 +405,6 @@ export async function visitFieldValueAsync<
|
|
|
365
405
|
value: T | LocalizedFieldValue<T, L>,
|
|
366
406
|
visitFn: (locale: L | undefined, localeValue: T) => Promise<void>,
|
|
367
407
|
): Promise<void> {
|
|
368
|
-
const entries =
|
|
408
|
+
const entries = toNormalizedFieldValueEntries<T, L>(field, value);
|
|
369
409
|
await Promise.all(entries.map(({ locale, value }) => visitFn(locale, value)));
|
|
370
410
|
}
|