@datocms/cma-client 5.1.4 → 5.1.6

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.
Files changed (51) hide show
  1. package/dist/cjs/fieldTypes/gallery.js +0 -2
  2. package/dist/cjs/fieldTypes/gallery.js.map +1 -1
  3. package/dist/cjs/fieldTypes/links.js +0 -2
  4. package/dist/cjs/fieldTypes/links.js.map +1 -1
  5. package/dist/cjs/fieldTypes/rich_text.js +0 -4
  6. package/dist/cjs/fieldTypes/rich_text.js.map +1 -1
  7. package/dist/cjs/generated/Client.js +1 -1
  8. package/dist/cjs/generated/resources/Item.js +2 -2
  9. package/dist/cjs/generated/resources/Item.js.map +1 -1
  10. package/dist/cjs/utilities/fieldValue.js +14 -9
  11. package/dist/cjs/utilities/fieldValue.js.map +1 -1
  12. package/dist/cjs/utilities/schemaRepository.js +64 -0
  13. package/dist/cjs/utilities/schemaRepository.js.map +1 -1
  14. package/dist/esm/fieldTypes/gallery.d.ts +1 -1
  15. package/dist/esm/fieldTypes/gallery.js +0 -2
  16. package/dist/esm/fieldTypes/gallery.js.map +1 -1
  17. package/dist/esm/fieldTypes/links.d.ts +1 -1
  18. package/dist/esm/fieldTypes/links.js +0 -2
  19. package/dist/esm/fieldTypes/links.js.map +1 -1
  20. package/dist/esm/fieldTypes/rich_text.js +0 -4
  21. package/dist/esm/fieldTypes/rich_text.js.map +1 -1
  22. package/dist/esm/generated/ApiTypes.d.ts +753 -8
  23. package/dist/esm/generated/Client.js +1 -1
  24. package/dist/esm/generated/RawApiTypes.d.ts +754 -9
  25. package/dist/esm/generated/resources/Item.js +2 -2
  26. package/dist/esm/generated/resources/Item.js.map +1 -1
  27. package/dist/esm/utilities/fieldValue.d.ts +18 -19
  28. package/dist/esm/utilities/fieldValue.js +14 -9
  29. package/dist/esm/utilities/fieldValue.js.map +1 -1
  30. package/dist/esm/utilities/itemDefinition.d.ts +27 -14
  31. package/dist/esm/utilities/schemaRepository.d.ts +64 -0
  32. package/dist/esm/utilities/schemaRepository.js +64 -0
  33. package/dist/esm/utilities/schemaRepository.js.map +1 -1
  34. package/dist/types/fieldTypes/gallery.d.ts +1 -1
  35. package/dist/types/fieldTypes/links.d.ts +1 -1
  36. package/dist/types/generated/ApiTypes.d.ts +753 -8
  37. package/dist/types/generated/RawApiTypes.d.ts +754 -9
  38. package/dist/types/utilities/fieldValue.d.ts +18 -19
  39. package/dist/types/utilities/itemDefinition.d.ts +27 -14
  40. package/dist/types/utilities/schemaRepository.d.ts +64 -0
  41. package/package.json +4 -4
  42. package/src/fieldTypes/gallery.ts +1 -2
  43. package/src/fieldTypes/links.ts +1 -2
  44. package/src/fieldTypes/rich_text.ts +0 -4
  45. package/src/generated/ApiTypes.ts +761 -10
  46. package/src/generated/Client.ts +1 -1
  47. package/src/generated/RawApiTypes.ts +761 -9
  48. package/src/generated/resources/Item.ts +2 -2
  49. package/src/utilities/fieldValue.ts +96 -79
  50. package/src/utilities/itemDefinition.ts +99 -72
  51. package/src/utilities/schemaRepository.ts +64 -0
@@ -7,7 +7,7 @@ import type * as RawApiTypes from '../generated/RawApiTypes';
7
7
  * for various locales structured as an object, such as
8
8
  * `{ "en": "Hello", "it": "Ciao" }`
9
9
  */
10
- export type LocalizedFieldValue<T = unknown> = Record<string, T>;
10
+ export type LocalizedFieldValue<T = unknown, L extends string = string> = Record<L, T>;
11
11
  /**
12
12
  * Determines whether a DatoCMS field is localized or not.
13
13
  *
@@ -26,11 +26,10 @@ export declare function isLocalized(field: RawApiTypes.Field | ApiTypes.Field):
26
26
  *
27
27
  * This uniform structure allows the same processing logic to work with both field types.
28
28
  */
29
- export type FieldValueEntry = {
30
- locale: string | undefined;
31
- value: unknown;
29
+ export type FieldValueEntry<T = unknown, L extends string = string> = {
30
+ locale: L | undefined;
31
+ value: T;
32
32
  };
33
- export type PossiblyLocalizedEntry = FieldValueEntry;
34
33
  /**
35
34
  * Converts a field value (localized or non-localized) into a uniform array of entries.
36
35
  *
@@ -41,19 +40,19 @@ export type PossiblyLocalizedEntry = FieldValueEntry;
41
40
  * @param value - The field value to convert (either a localized object or direct value)
42
41
  * @returns Array of entries where each entry contains a locale (string for localized, undefined for non-localized) and the corresponding value
43
42
  */
44
- export declare function fieldValueToEntries(field: RawApiTypes.Field | ApiTypes.Field, value: unknown): FieldValueEntry[];
43
+ export declare function fieldValueToEntries<T = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: T | LocalizedFieldValue<T, L>): FieldValueEntry<T, L>[];
45
44
  /**
46
45
  * Converts an array of possibly localized entries back into the appropriate field value format.
47
46
  *
48
- * This function is the inverse of `fieldValueToPossiblyLocalizedEntries`. It takes a uniform
47
+ * This function is the inverse of `fieldValueToEntries`. It takes a uniform
49
48
  * array of entries and converts them back to either a localized object or a direct value,
50
49
  * depending on the field's localization setting.
51
50
  *
52
51
  * @param field - The DatoCMS field definition that determines the output format
53
- * @param possiblyLocalizedEntries - Array of entries to convert back to field value format
52
+ * @param entries - Array of entries to convert back to field value format
54
53
  * @returns Either a localized object (for localized fields) or the direct value (for non-localized fields)
55
54
  */
56
- export declare function entriesToFieldValue(field: RawApiTypes.Field | ApiTypes.Field, possiblyLocalizedEntries: FieldValueEntry[]): any;
55
+ export declare function entriesToFieldValue<T = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, entries: FieldValueEntry<T, L>[]): T | LocalizedFieldValue<T, L>;
57
56
  /**
58
57
  * Maps field values using a provided mapping function.
59
58
  * For localized fields, applies the mapping function to each locale value.
@@ -65,7 +64,7 @@ export declare function entriesToFieldValue(field: RawApiTypes.Field | ApiTypes.
65
64
  * @param mapFn - The function to apply to each locale value or the direct value
66
65
  * @returns The mapped value with the same structure as the input
67
66
  */
68
- export declare function mapFieldValue<T>(field: RawApiTypes.Field | ApiTypes.Field, value: unknown, mapFn: (locale: string | undefined, localeValue: unknown) => T): any;
67
+ export declare function mapFieldValue<TInput = unknown, TOutput = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: TInput | LocalizedFieldValue<TInput, L>, mapFn: (locale: L | undefined, localeValue: TInput) => TOutput): TOutput | LocalizedFieldValue<TOutput, L>;
69
68
  /**
70
69
  * Maps field values using a provided mapping function (async version).
71
70
  * For localized fields, applies the mapping function to each locale value.
@@ -77,7 +76,7 @@ export declare function mapFieldValue<T>(field: RawApiTypes.Field | ApiTypes.Fie
77
76
  * @param mapFn - The function to apply to each locale value or the direct value
78
77
  * @returns The mapped value with the same structure as the input
79
78
  */
80
- export declare function mapFieldValueAsync<T>(field: RawApiTypes.Field | ApiTypes.Field, value: unknown, mapFn: (locale: string | undefined, localeValue: unknown) => Promise<T>): Promise<any>;
79
+ export declare function mapFieldValueAsync<TInput = unknown, TOutput = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: TInput | LocalizedFieldValue<TInput, L>, mapFn: (locale: L | undefined, localeValue: TInput) => Promise<TOutput>): Promise<TOutput | LocalizedFieldValue<TOutput, L>>;
81
80
  /**
82
81
  * Filters field values using a provided filter function.
83
82
  * For localized fields, filters each locale value.
@@ -88,7 +87,7 @@ export declare function mapFieldValueAsync<T>(field: RawApiTypes.Field | ApiType
88
87
  * @param filterFn - The function to test each locale value or the direct value
89
88
  * @returns The filtered value with the same structure as the input
90
89
  */
91
- export declare function filterFieldValue(field: RawApiTypes.Field | ApiTypes.Field, value: unknown, filterFn: (locale: string | undefined, localeValue: unknown) => boolean): any;
90
+ export declare function filterFieldValue<T = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: T | LocalizedFieldValue<T, L>, filterFn: (locale: L | undefined, localeValue: T) => boolean): T | LocalizedFieldValue<T, L> | undefined;
92
91
  /**
93
92
  * Filters field values using a provided filter function (async version).
94
93
  * For localized fields, filters each locale value.
@@ -99,7 +98,7 @@ export declare function filterFieldValue(field: RawApiTypes.Field | ApiTypes.Fie
99
98
  * @param filterFn - The function to test each locale value or the direct value
100
99
  * @returns The filtered value with the same structure as the input
101
100
  */
102
- export declare function filterFieldValueAsync(field: RawApiTypes.Field | ApiTypes.Field, value: unknown, filterFn: (locale: string | undefined, localeValue: unknown) => Promise<boolean>): Promise<any>;
101
+ export declare function filterFieldValueAsync<T = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: T | LocalizedFieldValue<T, L>, filterFn: (locale: L | undefined, localeValue: T) => Promise<boolean>): Promise<T | LocalizedFieldValue<T, L> | undefined>;
103
102
  /**
104
103
  * Tests whether at least one field value passes the test implemented by the provided function.
105
104
  * For localized fields, tests each locale value.
@@ -110,7 +109,7 @@ export declare function filterFieldValueAsync(field: RawApiTypes.Field | ApiType
110
109
  * @param testFn - The function to test each locale value or the direct value
111
110
  * @returns true if at least one value passes the test, false otherwise
112
111
  */
113
- export declare function someFieldValue(field: RawApiTypes.Field | ApiTypes.Field, value: unknown, testFn: (locale: string | undefined, localeValue: unknown) => boolean): boolean;
112
+ export declare function someFieldValue<T = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: T | LocalizedFieldValue<T, L>, testFn: (locale: L | undefined, localeValue: T) => boolean): boolean;
114
113
  /**
115
114
  * Tests whether at least one field value passes the test implemented by the provided function (async version).
116
115
  * For localized fields, tests each locale value.
@@ -121,7 +120,7 @@ export declare function someFieldValue(field: RawApiTypes.Field | ApiTypes.Field
121
120
  * @param testFn - The function to test each locale value or the direct value
122
121
  * @returns true if at least one value passes the test, false otherwise
123
122
  */
124
- export declare function someFieldValueAsync(field: RawApiTypes.Field | ApiTypes.Field, value: unknown, testFn: (locale: string | undefined, localeValue: unknown) => Promise<boolean>): Promise<boolean>;
123
+ export declare function someFieldValueAsync<T = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: T | LocalizedFieldValue<T, L>, testFn: (locale: L | undefined, localeValue: T) => Promise<boolean>): Promise<boolean>;
125
124
  /**
126
125
  * Tests whether all field values pass the test implemented by the provided function.
127
126
  * For localized fields, tests each locale value.
@@ -132,7 +131,7 @@ export declare function someFieldValueAsync(field: RawApiTypes.Field | ApiTypes.
132
131
  * @param testFn - The function to test each locale value or the direct value
133
132
  * @returns true if all values pass the test, false otherwise
134
133
  */
135
- export declare function everyFieldValue(field: RawApiTypes.Field | ApiTypes.Field, value: unknown, testFn: (locale: string | undefined, localeValue: unknown) => boolean): boolean;
134
+ export declare function everyFieldValue<T = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: T | LocalizedFieldValue<T, L>, testFn: (locale: L | undefined, localeValue: T) => boolean): boolean;
136
135
  /**
137
136
  * Tests whether all field values pass the test implemented by the provided function (async version).
138
137
  * For localized fields, tests each locale value.
@@ -143,7 +142,7 @@ export declare function everyFieldValue(field: RawApiTypes.Field | ApiTypes.Fiel
143
142
  * @param testFn - The function to test each locale value or the direct value
144
143
  * @returns true if all values pass the test, false otherwise
145
144
  */
146
- export declare function everyFieldValueAsync(field: RawApiTypes.Field | ApiTypes.Field, value: unknown, testFn: (locale: string | undefined, localeValue: unknown) => Promise<boolean>): Promise<boolean>;
145
+ export declare function everyFieldValueAsync<T = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: T | LocalizedFieldValue<T, L>, testFn: (locale: L | undefined, localeValue: T) => Promise<boolean>): Promise<boolean>;
147
146
  /**
148
147
  * Visits each field value with the provided function.
149
148
  * For localized fields, visits each locale value.
@@ -153,7 +152,7 @@ export declare function everyFieldValueAsync(field: RawApiTypes.Field | ApiTypes
153
152
  * @param value - The field value (either localized object or direct value)
154
153
  * @param visitFn - The function to call for each locale value or the direct value
155
154
  */
156
- export declare function visitFieldValue(field: RawApiTypes.Field | ApiTypes.Field, value: unknown, visitFn: (locale: string | undefined, localeValue: unknown) => void): void;
155
+ export declare function visitFieldValue<T = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: T | LocalizedFieldValue<T, L>, visitFn: (locale: L | undefined, localeValue: T) => void): void;
157
156
  /**
158
157
  * Visits each field value with the provided function (async version).
159
158
  * For localized fields, visits each locale value.
@@ -163,4 +162,4 @@ export declare function visitFieldValue(field: RawApiTypes.Field | ApiTypes.Fiel
163
162
  * @param value - The field value (either localized object or direct value)
164
163
  * @param visitFn - The function to call for each locale value or the direct value
165
164
  */
166
- export declare function visitFieldValueAsync(field: RawApiTypes.Field | ApiTypes.Field, value: unknown, visitFn: (locale: string | undefined, localeValue: unknown) => Promise<void>): Promise<void>;
165
+ export declare function visitFieldValueAsync<T = unknown, L extends string = string>(field: RawApiTypes.Field | ApiTypes.Field, value: T | LocalizedFieldValue<T, L>, visitFn: (locale: L | undefined, localeValue: T) => Promise<void>): Promise<void>;
@@ -12,13 +12,18 @@ type SingleBlockFieldDefinition<AllowedBlocks extends ItemTypeDefinition = ItemT
12
12
  blocks: AllowedBlocks;
13
13
  };
14
14
  type StructuredTextFieldDefinition<AllowedBlocks extends ItemTypeDefinition = ItemTypeDefinition, AllowedInlineBlocks extends ItemTypeDefinition = ItemTypeDefinition> = BaseFieldDefinition<'structured_text'> & {
15
- blocks: AllowedBlocks;
16
- inline_blocks: AllowedInlineBlocks;
15
+ blocks?: AllowedBlocks;
16
+ inline_blocks?: AllowedInlineBlocks;
17
17
  };
18
18
  /** Field definition union */
19
19
  export type FieldDefinition = BaseFieldDefinition<'boolean' | 'color' | 'date' | 'date_time' | 'file' | 'float' | 'gallery' | 'integer' | 'json' | 'lat_lon' | 'link' | 'links' | 'seo' | 'slug' | 'string' | 'text' | 'video' | 'unknown'> | RichTextFieldDefinition | SingleBlockFieldDefinition | StructuredTextFieldDefinition;
20
20
  /** Item type definition */
21
- export type ItemTypeDefinition<ItemTypeId extends string = string, FieldDefinitions extends Record<string, FieldDefinition> = {}> = {
21
+ export type ItemTypeDefinition<Settings extends {
22
+ locales: string;
23
+ } = {
24
+ locales: string;
25
+ }, ItemTypeId extends string = string, FieldDefinitions extends Record<string, FieldDefinition> = {}> = {
26
+ settings: Settings;
22
27
  itemTypeId: ItemTypeId;
23
28
  fields: FieldDefinitions;
24
29
  };
@@ -52,23 +57,31 @@ type FieldTypeToValue = {
52
57
  unknown: unknown;
53
58
  };
54
59
  /** Localized wrapper */
55
- type LocalizeIfNeeded<T extends FieldDefinition, Value> = T extends {
60
+ type LocalizeIfNeeded<T extends FieldDefinition, Value, Locales extends string> = T extends {
56
61
  localized: true;
57
- } ? LocalizedFieldValue<Value> : Value;
62
+ } ? LocalizedFieldValue<Value, Locales> : Value;
58
63
  /** Standard mapping */
59
- type FieldDefinitionToFieldValue<T extends FieldDefinition> = LocalizeIfNeeded<T, FieldTypeToValue[T['type']]>;
64
+ type FieldDefinitionToFieldValue<T extends FieldDefinition, Locales extends string> = LocalizeIfNeeded<T, FieldTypeToValue[T['type']], Locales>;
60
65
  /** AsRequest mapping (block fields become generic over allowed blocks) */
61
- type FieldDefinitionToFieldValueAsRequest<T extends FieldDefinition> = T extends RichTextFieldDefinition<infer B> ? LocalizeIfNeeded<T, RichTextFieldValueAsRequest<ItemTypeDefinitionToItemDefinitionAsRequest<B>>> : T extends SingleBlockFieldDefinition<infer B> ? LocalizeIfNeeded<T, SingleBlockFieldValueAsRequest<ItemTypeDefinitionToItemDefinitionAsRequest<B>>> : T extends StructuredTextFieldDefinition<infer B, infer I> ? LocalizeIfNeeded<T, StructuredTextFieldValueAsRequest<ItemTypeDefinitionToItemDefinitionAsRequest<B>, ItemTypeDefinitionToItemDefinitionAsRequest<I>>> : LocalizeIfNeeded<T, FieldTypeToValue[T['type']]>;
62
- type FieldDefinitionToFieldValueWithNestedBlocks<T extends FieldDefinition> = T extends RichTextFieldDefinition<infer B> ? LocalizeIfNeeded<T, RichTextFieldValueWithNestedBlocks<ItemTypeDefinitionToItemDefinitionWithNestedBlocks<B>>> : T extends SingleBlockFieldDefinition<infer B> ? LocalizeIfNeeded<T, SingleBlockFieldValueWithNestedBlocks<ItemTypeDefinitionToItemDefinitionWithNestedBlocks<B>>> : T extends StructuredTextFieldDefinition<infer B, infer I> ? LocalizeIfNeeded<T, StructuredTextFieldValueWithNestedBlocks<ItemTypeDefinitionToItemDefinitionWithNestedBlocks<B>, ItemTypeDefinitionToItemDefinitionWithNestedBlocks<I>>> : LocalizeIfNeeded<T, FieldTypeToValue[T['type']]>;
66
+ type FieldDefinitionToFieldValueAsRequest<T extends FieldDefinition, Locales extends string> = T extends RichTextFieldDefinition<infer B> ? LocalizeIfNeeded<T, RichTextFieldValueAsRequest<ItemTypeDefinitionToItemDefinitionAsRequest<B>>, Locales> : T extends SingleBlockFieldDefinition<infer B> ? LocalizeIfNeeded<T, SingleBlockFieldValueAsRequest<ItemTypeDefinitionToItemDefinitionAsRequest<B>>, Locales> : T extends StructuredTextFieldDefinition<infer B, infer I> ? LocalizeIfNeeded<T, StructuredTextFieldValueAsRequest<T extends {
67
+ blocks: any;
68
+ } ? ItemTypeDefinitionToItemDefinitionAsRequest<B> : never, T extends {
69
+ inline_blocks: any;
70
+ } ? ItemTypeDefinitionToItemDefinitionAsRequest<I> : never>, Locales> : LocalizeIfNeeded<T, FieldTypeToValue[T['type']], Locales>;
71
+ type FieldDefinitionToFieldValueWithNestedBlocks<T extends FieldDefinition, Locales extends string> = T extends RichTextFieldDefinition<infer B> ? LocalizeIfNeeded<T, RichTextFieldValueWithNestedBlocks<ItemTypeDefinitionToItemDefinitionWithNestedBlocks<B>>, Locales> : T extends SingleBlockFieldDefinition<infer B> ? LocalizeIfNeeded<T, SingleBlockFieldValueWithNestedBlocks<ItemTypeDefinitionToItemDefinitionWithNestedBlocks<B>>, Locales> : T extends StructuredTextFieldDefinition<infer B, infer I> ? LocalizeIfNeeded<T, StructuredTextFieldValueWithNestedBlocks<T extends {
72
+ blocks: any;
73
+ } ? ItemTypeDefinitionToItemDefinitionWithNestedBlocks<B> : never, T extends {
74
+ inline_blocks: any;
75
+ } ? ItemTypeDefinitionToItemDefinitionWithNestedBlocks<I> : never>, Locales> : LocalizeIfNeeded<T, FieldTypeToValue[T['type']], Locales>;
63
76
  /** Transformers */
64
- export type ItemTypeDefinitionToItemDefinition<T extends ItemTypeDefinition> = T extends ItemTypeDefinition ? keyof T['fields'] extends never ? ItemDefinition<T['itemTypeId']> : ItemDefinition<T['itemTypeId'], {
65
- [K in keyof T['fields']]: T['fields'][K] extends FieldDefinition ? FieldDefinitionToFieldValue<T['fields'][K]> : never;
77
+ export type ItemTypeDefinitionToItemDefinition<T extends ItemTypeDefinition<any, any, any>> = T extends ItemTypeDefinition<infer Settings, infer ItemTypeId, infer Fields> ? keyof Fields extends never ? ItemDefinition<ItemTypeId> : ItemDefinition<ItemTypeId, {
78
+ [K in keyof Fields]: Fields[K] extends FieldDefinition ? FieldDefinitionToFieldValue<Fields[K], Settings['locales']> : never;
66
79
  }> : never;
67
- export type ItemTypeDefinitionToItemDefinitionAsRequest<T extends ItemTypeDefinition> = T extends ItemTypeDefinition ? keyof T['fields'] extends never ? ItemDefinition<T['itemTypeId']> : ItemDefinition<T['itemTypeId'], Partial<{
68
- [K in keyof T['fields']]: T['fields'][K] extends FieldDefinition ? FieldDefinitionToFieldValueAsRequest<T['fields'][K]> : never;
80
+ export type ItemTypeDefinitionToItemDefinitionAsRequest<T extends ItemTypeDefinition<any, any, any>> = T extends ItemTypeDefinition<infer Settings, infer ItemTypeId, infer Fields> ? keyof Fields extends never ? ItemDefinition<ItemTypeId> : ItemDefinition<ItemTypeId, Partial<{
81
+ [K in keyof Fields]: Fields[K] extends FieldDefinition ? FieldDefinitionToFieldValueAsRequest<Fields[K], Settings['locales']> : never;
69
82
  }>> : never;
70
- export type ItemTypeDefinitionToItemDefinitionWithNestedBlocks<T extends ItemTypeDefinition> = T extends ItemTypeDefinition ? keyof T['fields'] extends never ? ItemDefinition<T['itemTypeId']> : ItemDefinition<T['itemTypeId'], {
71
- [K in keyof T['fields']]: T['fields'][K] extends FieldDefinition ? FieldDefinitionToFieldValueWithNestedBlocks<T['fields'][K]> : never;
83
+ export type ItemTypeDefinitionToItemDefinitionWithNestedBlocks<T extends ItemTypeDefinition<any, any, any>> = T extends ItemTypeDefinition<infer Settings, infer ItemTypeId, infer Fields> ? keyof Fields extends never ? ItemDefinition<ItemTypeId> : ItemDefinition<ItemTypeId, {
84
+ [K in keyof Fields]: Fields[K] extends FieldDefinition ? FieldDefinitionToFieldValueWithNestedBlocks<Fields[K], Settings['locales']> : never;
72
85
  }> : never;
73
86
  export type UnknownField = Record<string, unknown>;
74
87
  export {};
@@ -28,6 +28,70 @@ interface GenericClient {
28
28
  /**
29
29
  * Repository for DatoCMS schema entities including item types, fields, and plugins.
30
30
  * Provides caching and efficient lookup functionality for schema-related operations.
31
+ *
32
+ * ## Purpose
33
+ *
34
+ * SchemaRepository is designed to solve the performance problem of repeatedly fetching
35
+ * the same schema information during complex operations that traverse nested blocks,
36
+ * structured text, or modular content. It acts as an in-memory cache/memoization layer
37
+ * for schema entities to avoid redundant API calls.
38
+ *
39
+ * ## What it's for:
40
+ *
41
+ * - **Caching schema entities**: Automatically caches item types, fields, fieldsets,
42
+ * and plugins after the first API request, returning cached results on subsequent calls
43
+ * - **Complex traversal operations**: Essential when using utilities like
44
+ * `mapBlocksInFieldValues()` that need to repeatedly lookup block models and fields
45
+ * while traversing nested content structures
46
+ * - **Bulk operations**: Ideal for scripts that process multiple records of different
47
+ * types and need efficient access to schema information
48
+ * - **Read-heavy workflows**: Perfect for scenarios where you need to repeatedly access
49
+ * the same schema information without making redundant API calls
50
+ *
51
+ * ## What it's NOT for:
52
+ *
53
+ * - **Schema modification**: Do NOT use SchemaRepository if your script modifies models,
54
+ * fields, fieldsets, or plugins, as the cache will become stale
55
+ * - **Record/content operations**: This is only for schema entities, not for records,
56
+ * uploads, or other content
57
+ * - **Long-running applications**: The cache has no expiration or invalidation mechanism,
58
+ * so it's not suitable for applications that need fresh schema data over time
59
+ * - **Concurrent schema changes**: No protection against cache inconsistency if other
60
+ * processes modify the schema while your script runs
61
+ *
62
+ * ## Usage Pattern
63
+ *
64
+ * ```typescript
65
+ * const schemaRepository = new SchemaRepository(client);
66
+ *
67
+ * // These calls will hit the API and cache the results
68
+ * const models = await schemaRepository.getAllModels();
69
+ * const blogPost = await schemaRepository.getItemTypeByApiKey('blog_post');
70
+ *
71
+ * // These subsequent calls will return cached results (no API calls)
72
+ * const sameModels = await schemaRepository.getAllModels();
73
+ * const sameBlogPost = await schemaRepository.getItemTypeByApiKey('blog_post');
74
+ *
75
+ * // Pass the repository to utilities that need schema information
76
+ * await mapBlocksInFieldValues(schemaRepository, record, (block) => {
77
+ * // The utility will use the cached schema data internally
78
+ * });
79
+ * ```
80
+ *
81
+ * ## Performance Benefits
82
+ *
83
+ * Without SchemaRepository, a script processing structured text with nested blocks
84
+ * might make the same `client.itemTypes.list()` or `client.fields.list()` calls
85
+ * dozens of times. SchemaRepository ensures each unique schema request is made only once.
86
+ *
87
+ * ## Best Practices
88
+ *
89
+ * - Use SchemaRepository consistently throughout your script — if you need it for one
90
+ * utility call, use it for all schema operations to maximize cache efficiency
91
+ * - Create one instance per script execution, not per operation
92
+ * - Only use when you have read-only access to schema entities
93
+ * - Consider using optimistic locking for any record updates to handle potential
94
+ * version conflicts when working with cached schema information
31
95
  */
32
96
  export declare class SchemaRepository {
33
97
  private client;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datocms/cma-client",
3
- "version": "5.1.4",
3
+ "version": "5.1.6",
4
4
  "description": "JS client for DatoCMS REST Content Management API",
5
5
  "keywords": [
6
6
  "datocms",
@@ -37,13 +37,13 @@
37
37
  "url": "https://github.com/datocms/js-rest-api-clients/issues"
38
38
  },
39
39
  "dependencies": {
40
- "@datocms/rest-client-utils": "^5.1.4",
40
+ "@datocms/rest-client-utils": "^5.1.6",
41
41
  "datocms-structured-text-utils": "^5.1.1",
42
42
  "uuid": "^9.0.1"
43
43
  },
44
44
  "devDependencies": {
45
- "@datocms/dashboard-client": "^5.1.4",
45
+ "@datocms/dashboard-client": "^5.1.6",
46
46
  "@types/uuid": "^9.0.7"
47
47
  },
48
- "gitHead": "b9b3aee7d6c78acdfef811fa42a84bc42abc36f7"
48
+ "gitHead": "92b4b39626abe853ab1ce24ddd7c64d1af1b43f8"
49
49
  }
@@ -16,12 +16,11 @@ export type GalleryFieldValue = Array<{
16
16
  x: number;
17
17
  y: number;
18
18
  } | null;
19
- }> | null;
19
+ }>;
20
20
 
21
21
  export function isGalleryFieldValue(
22
22
  value: unknown,
23
23
  ): value is GalleryFieldValue {
24
- if (value === null) return true;
25
24
  return (
26
25
  Array.isArray(value) &&
27
26
  value.every(
@@ -4,10 +4,9 @@ import type { LinksSelectEditorConfiguration } from './appearance/links_select';
4
4
  import type { ItemsItemTypeValidator } from './validators/items_item_type';
5
5
  import type { SizeValidator } from './validators/size';
6
6
 
7
- export type LinksFieldValue = string[] | null;
7
+ export type LinksFieldValue = string[];
8
8
 
9
9
  export function isLinksFieldValue(value: unknown): value is LinksFieldValue {
10
- if (value === null) return true;
11
10
  return (
12
11
  Array.isArray(value) && value.every((item) => typeof item === 'string')
13
12
  );
@@ -95,8 +95,6 @@ export type RichTextFieldValueWithNestedBlocks<
95
95
  export function isRichTextFieldValue(
96
96
  value: unknown,
97
97
  ): value is RichTextFieldValue {
98
- if (value === null) return true;
99
-
100
98
  return (
101
99
  Array.isArray(value) && value.every((block) => typeof block === 'string')
102
100
  );
@@ -151,8 +149,6 @@ export function isLocalizedRichTextFieldValueAsRequest<
151
149
  export function isRichTextFieldValueWithNestedBlocks<
152
150
  D extends ItemDefinition = ItemDefinition,
153
151
  >(value: unknown): value is RichTextFieldValueWithNestedBlocks<D> {
154
- if (value === null) return true;
155
-
156
152
  if (!Array.isArray(value)) return false;
157
153
 
158
154
  return value.every((block) => {