@stackbit/cms-core 0.1.13-alpha.0 → 0.1.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackbit/cms-core",
3
- "version": "0.1.13-alpha.0",
3
+ "version": "0.1.13",
4
4
  "description": "stackbit-dev",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,9 +29,9 @@
29
29
  "@babel/parser": "^7.11.5",
30
30
  "@babel/traverse": "^7.11.5",
31
31
  "@iarna/toml": "^2.2.3",
32
- "@stackbit/sdk": "^0.3.9-alpha.0",
33
- "@stackbit/types": "^0.1.7-alpha.0",
34
- "@stackbit/utils": "^0.2.13-alpha.0",
32
+ "@stackbit/sdk": "^0.3.9",
33
+ "@stackbit/types": "^0.1.7",
34
+ "@stackbit/utils": "^0.2.12",
35
35
  "chalk": "^4.0.1",
36
36
  "esm": "^3.2.25",
37
37
  "fs-extra": "^8.1.0",
@@ -45,5 +45,5 @@
45
45
  "sanitize-filename": "^1.6.3",
46
46
  "slugify": "^1.6.5"
47
47
  },
48
- "gitHead": "c655a5d1f3fa7d613fb20c173369cef8e141e633"
48
+ "gitHead": "c82a7ec57444318dbd585486d90275635373a6f0"
49
49
  }
@@ -1,7 +1,42 @@
1
1
  import { DocumentStatus, FieldType } from '@stackbit/types';
2
+ import { Model } from '@stackbit/sdk';
3
+ import * as CSITypes from '@stackbit/types';
2
4
 
3
5
  export { FieldType, DocumentStatus, Logger } from '@stackbit/types';
4
6
 
7
+ export interface ContentSourceData {
8
+ id: string;
9
+ instance: CSITypes.ContentSourceInterface;
10
+ srcType: string;
11
+ srcProjectId: string;
12
+ locales?: CSITypes.Locale[];
13
+ defaultLocaleCode?: string;
14
+ /* Array of extended and validated Models */
15
+ models: Model[];
16
+ /* Map of extended and validated Models by model name */
17
+ modelMap: Record<string, Model>;
18
+ /* Array of original Models (as provided by content source) */
19
+ csiModels: CSITypes.Model[];
20
+ /* Map of original Models (as provided by content source) by model name */
21
+ csiModelMap: Record<string, CSITypes.Model>;
22
+ /* Array of original content source Documents */
23
+ csiDocuments: CSITypes.Document[];
24
+ /* Map of original content source Documents by document ID */
25
+ csiDocumentMap: Record<string, CSITypes.Document>;
26
+ /* Array of converted content-store Documents */
27
+ documents: Document[];
28
+ /* Map of converted content-store Documents by document ID */
29
+ documentMap: Record<string, Document>;
30
+ /* Array of original content source Assets */
31
+ csiAssets: CSITypes.Asset[];
32
+ /* Map of original content source Assets by asset ID */
33
+ csiAssetMap: Record<string, CSITypes.Asset>;
34
+ /* Array of converted content-store Assets */
35
+ assets: Asset[];
36
+ /* Map of converted content-store Assets by asset ID */
37
+ assetMap: Record<string, Asset>;
38
+ }
39
+
5
40
  export interface Document {
6
41
  type: 'document';
7
42
  srcType: string;
@@ -170,7 +205,7 @@ export type DocumentFieldTypeLocalized<BaseFieldProps, LocalizedFieldProps> = Si
170
205
  BaseFieldProps & {
171
206
  label?: string;
172
207
  localized: true;
173
- locales: Record<string, { locale: string } & Exclude<LocalizedFieldProps, DocumentFieldUnsetProps>>;
208
+ locales: Record<string, { locale: string } & Omit<Exclude<LocalizedFieldProps, DocumentFieldUnsetProps>, 'isUnset'>>;
174
209
  }
175
210
  >;
176
211
 
@@ -188,7 +223,7 @@ export type DocumentFieldTypeAPI<BaseFieldProps, LocalizedFieldProps> = BaseFiel
188
223
  description?: string;
189
224
  locale?: string;
190
225
  localized?: boolean;
191
- } & ({ localized?: false; } | { localized: true; locale: string; });
226
+ } & ({ localized?: false } | { localized: true; locale: string });
192
227
 
193
228
  // any field that is not 'object' | 'model' | 'reference' | 'richText' | 'markdown' | 'list'
194
229
  export type DocumentValueFieldType = Exclude<FieldType, 'object' | 'model' | 'reference' | 'markdown' | 'richText' | 'list' | 'image'>;
@@ -306,11 +341,13 @@ export type DocumentListFieldAPI = DocumentFieldTypeAPI<DocumentListFieldBase, D
306
341
  export type DocumentListFieldBase = {
307
342
  type: 'list';
308
343
  };
344
+ export type DocumentListFieldItems = Exclude<DocumentFieldNonLocalized, DocumentListFieldNonLocalized>;
309
345
  export type DocumentListFieldProps = {
310
- items: DocumentField[];
346
+ items: DocumentListFieldItems[];
311
347
  };
348
+ export type DocumentListFieldItemsAPI = Exclude<DocumentFieldAPI, DocumentListFieldAPI>;
312
349
  export type DocumentListFieldPropsAPI = {
313
- items: DocumentFieldAPI[];
350
+ items: DocumentListFieldItemsAPI[];
314
351
  };
315
352
 
316
353
  // image
@@ -1,9 +1,8 @@
1
1
  import _ from 'lodash';
2
2
  import { Model } from '@stackbit/sdk';
3
3
  import { append } from '@stackbit/utils';
4
- import { Field, FieldList, FieldListItems, FieldListProps, FieldObjectProps, FieldSpecificProps } from '@stackbit/types';
4
+ import { Field, FieldList, FieldListItems, FieldListProps, FieldObjectProps, FieldSpecificProps, SiteMapEntry } from '@stackbit/types';
5
5
  import * as CSITypes from '@stackbit/types';
6
-
7
6
  import * as ContentStoreTypes from './content-store-types';
8
7
 
9
8
  export function getContentSourceIdForContentSource(contentSource: CSITypes.ContentSourceInterface): string {
@@ -159,7 +158,11 @@ export function groupModelsByContentSource({ models }: { models: CSITypes.ModelW
159
158
  return modelMapByContentSource;
160
159
  }
161
160
 
162
- export function groupDocumentsByContentSource({ documents }: { documents: CSITypes.DocumentWithSource[] }): Record<string, Record<string, CSITypes.Document[]>> {
161
+ export function groupDocumentsByContentSource({
162
+ documents
163
+ }: {
164
+ documents: CSITypes.DocumentWithSource[];
165
+ }): Record<string, Record<string, CSITypes.Document[]>> {
163
166
  const documentMapByContentSource: Record<string, Record<string, CSITypes.Document[]>> = {};
164
167
  for (const document of documents) {
165
168
  const { srcType, srcProjectId, ...rest } = document;
@@ -167,3 +170,58 @@ export function groupDocumentsByContentSource({ documents }: { documents: CSITyp
167
170
  }
168
171
  return documentMapByContentSource;
169
172
  }
173
+
174
+ export function getCSIDocumentsAndAssetsFromContentSourceDataByIds(
175
+ contentSourceData: ContentStoreTypes.ContentSourceData,
176
+ objects: { srcObjectId: string }[]
177
+ ): {
178
+ documents: CSITypes.Document[];
179
+ assets: CSITypes.Asset[];
180
+ } {
181
+ const documents: CSITypes.Document[] = [];
182
+ const assets: CSITypes.Asset[] = [];
183
+ for (const object of objects) {
184
+ if (object.srcObjectId in contentSourceData.csiDocumentMap) {
185
+ documents.push(contentSourceData.csiDocumentMap[object.srcObjectId]!);
186
+ } else if (object.srcObjectId in contentSourceData.csiAssetMap) {
187
+ assets.push(contentSourceData.csiAssetMap[object.srcObjectId]!);
188
+ }
189
+ }
190
+ return {
191
+ documents,
192
+ assets
193
+ };
194
+ }
195
+
196
+ export function getDocumentFieldLabelValueForSiteMapEntry({
197
+ siteMapEntry,
198
+ locale,
199
+ contentSourceDataById
200
+ }: {
201
+ siteMapEntry: SiteMapEntry;
202
+ locale?: string;
203
+ contentSourceDataById: Record<string, ContentStoreTypes.ContentSourceData>;
204
+ }): string | null {
205
+ if (!('document' in siteMapEntry)) {
206
+ return null;
207
+ }
208
+ const contentSourceId = getContentSourceId(siteMapEntry.document.srcType, siteMapEntry.document.srcProjectId);
209
+ const contentSourceData = contentSourceDataById[contentSourceId];
210
+ if (!contentSourceData) {
211
+ return null;
212
+ }
213
+ const labelFieldName = contentSourceData.modelMap[siteMapEntry.document.modelName]?.labelField;
214
+ const document = contentSourceData.documentMap[siteMapEntry.document.id];
215
+ if (!labelFieldName || !document) {
216
+ return null;
217
+ }
218
+ const labelField = document.fields[labelFieldName];
219
+ if (!labelField) {
220
+ return null;
221
+ }
222
+ const localizedLabelField = getDocumentFieldForLocale(labelField, locale);
223
+ if (!localizedLabelField || !('value' in localizedLabelField) || !localizedLabelField.value) {
224
+ return null;
225
+ }
226
+ return String(localizedLabelField.value);
227
+ }
@@ -3,21 +3,20 @@ import path from 'path';
3
3
  import sanitizeFilename from 'sanitize-filename';
4
4
 
5
5
  import * as CSITypes from '@stackbit/types';
6
- import { getLocalizedFieldForLocale, ModelExtension, UserCommandSpawner } from '@stackbit/types';
6
+ import { DocumentWithSource, getLocalizedFieldForLocale, ModelExtension, ModelWithSource, UserCommandSpawner } from '@stackbit/types';
7
7
  import {
8
8
  Config,
9
- Field,
10
- Model,
9
+ extendModelsWithPresetsIds,
10
+ getPresetDirs,
11
+ getYamlModelDirs,
11
12
  ImageModel,
12
- Preset,
13
- PresetMap,
14
13
  loadPresets,
15
- getYamlModelDirs,
16
- getPresetDirs,
17
14
  loadYamlModelsFromFiles,
15
+ mergeConfigModelsWithExternalModels,
18
16
  mergeConfigModelsWithModelsFromFiles,
19
- extendModelsWithPresetsIds,
20
- mergeConfigModelsWithExternalModels
17
+ Model,
18
+ Preset,
19
+ PresetMap
21
20
  } from '@stackbit/sdk';
22
21
  import { deferWhileRunning, mapPromise, reducePromise } from '@stackbit/utils';
23
22
 
@@ -26,13 +25,16 @@ import { Timer } from './utils/timer';
26
25
  import { SearchFilter } from './types/search-filter';
27
26
  import { searchDocuments } from './utils/search-utils';
28
27
  import { mapCSIAssetsToStoreAssets, mapCSIDocumentsToStoreDocuments } from './utils/csi-to-store-docs-converter';
28
+ import { mapStoreDocumentsToCSIDocumentsWithSource } from './utils/store-to-csi-docs-converter';
29
29
  import {
30
30
  getContentSourceId,
31
31
  getContentSourceIdForContentSource,
32
+ getDocumentFieldLabelValueForSiteMapEntry,
33
+ getCSIDocumentsAndAssetsFromContentSourceDataByIds,
32
34
  getModelFieldForFieldAtPath,
33
35
  getUserContextForSrcType,
34
- groupModelsByContentSource,
35
- groupDocumentsByContentSource
36
+ groupDocumentsByContentSource,
37
+ groupModelsByContentSource
36
38
  } from './content-store-utils';
37
39
  import { mapAssetsToLocalizedApiImages, mapDocumentsToLocalizedApiObjects, mapStoreAssetsToAPIAssets } from './utils/store-to-api-docs-converter';
38
40
  import { convertOperationField, createDocumentRecursively, getCreateDocumentThunk } from './utils/create-update-csi-docs';
@@ -54,39 +56,7 @@ export interface ContentSourceOptions {
54
56
  devAppRestartNeeded?: () => void;
55
57
  }
56
58
 
57
- interface ContentSourceData {
58
- id: string;
59
- instance: CSITypes.ContentSourceInterface;
60
- srcType: string;
61
- srcProjectId: string;
62
- locales?: CSITypes.Locale[];
63
- defaultLocaleCode?: string;
64
- /* Array of extended and validated Models */
65
- models: Model[];
66
- /* Map of extended and validated Models by model name */
67
- modelMap: Record<string, Model>;
68
- /* Array of original Models (as provided by content source) */
69
- csiModels: CSITypes.Model[];
70
- /* Map of original Models (as provided by content source) by model name */
71
- csiModelMap: Record<string, CSITypes.Model>;
72
- /* Array of original content source Documents */
73
- csiDocuments: CSITypes.Document[];
74
- /* Map of original content source Documents by document ID */
75
- csiDocumentMap: Record<string, CSITypes.Document>;
76
- /* Array of converted content-store Documents */
77
- documents: ContentStoreTypes.Document[];
78
- /* Map of converted content-store Documents by document ID */
79
- documentMap: Record<string, ContentStoreTypes.Document>;
80
- /* Array of original content source Assets */
81
- csiAssets: CSITypes.Asset[];
82
- /* Map of original content source Assets by asset ID */
83
- csiAssetMap: Record<string, CSITypes.Asset>;
84
- /* Array of converted content-store Assets */
85
- assets: ContentStoreTypes.Asset[];
86
- /* Map of converted content-store Assets by asset ID */
87
- assetMap: Record<string, ContentStoreTypes.Asset>;
88
- }
89
-
59
+ type ContentSourceData = ContentStoreTypes.ContentSourceData;
90
60
  type ContentSourceRawData = Omit<ContentSourceData, 'models' | 'modelMap' | 'documents' | 'documentMap'>;
91
61
 
92
62
  export class ContentStore {
@@ -687,7 +657,9 @@ export class ContentStore {
687
657
  message += `, srcProjectId: '${configModel.srcProjectId}'`;
688
658
  }
689
659
  const matchesModelsMessage = matchedCSIModels.map((model) => `srcType: '${model.srcType}', srcProjectId: '${model.srcProjectId}'`).join('; ');
690
- this.userLogger.warn(`model ${message} defined in stackbit config matches more that 1 model in the following content sources: ${matchesModelsMessage}`);
660
+ this.userLogger.warn(
661
+ `model ${message} defined in stackbit config matches more that 1 model in the following content sources: ${matchesModelsMessage}`
662
+ );
691
663
  }
692
664
 
693
665
  const modelsWithSource = contentSourceRawDataArr.reduce((accum: CSITypes.ModelWithSource[], csData) => {
@@ -905,6 +877,68 @@ export class ContentStore {
905
877
  };
906
878
  }
907
879
 
880
+ getSiteMapEntries({ locale }: { locale?: string } = {}): CSITypes.SiteMapEntry[] {
881
+ if (!this.stackbitConfig?.siteMap) {
882
+ return [];
883
+ }
884
+
885
+ // TODO: cache siteMap in processData
886
+ const siteMapOptions = _.reduce(
887
+ this.contentSourceDataById,
888
+ (accum: { models: ModelWithSource[]; documents: DocumentWithSource[] }, contentSourceData) => {
889
+ return {
890
+ models: accum.models.concat(
891
+ contentSourceData.models.map((model) => ({
892
+ srcType: contentSourceData.srcType,
893
+ srcProjectId: contentSourceData.srcProjectId,
894
+ ...model
895
+ }))
896
+ ),
897
+ documents: accum.documents.concat(mapStoreDocumentsToCSIDocumentsWithSource(contentSourceData.documents))
898
+ };
899
+ },
900
+ { models: [], documents: [] }
901
+ );
902
+
903
+ const siteMapEntries = this.stackbitConfig.siteMap(siteMapOptions).reduce((accum: CSITypes.SiteMapEntry[], siteMapEntry) => {
904
+ // The site map entries are provided by user, sanitize them and filter out illegal entries
905
+ if (!siteMapEntry) {
906
+ return accum;
907
+ }
908
+
909
+ if (typeof siteMapEntry.urlPath !== 'string') {
910
+ return accum;
911
+ }
912
+
913
+ if ('document' in siteMapEntry) {
914
+ const doc = siteMapEntry.document;
915
+ if (!doc.srcType || !doc.srcProjectId || !doc.modelName || !doc.id) {
916
+ return accum;
917
+ }
918
+ }
919
+
920
+ if (!siteMapEntry.label) {
921
+ const fieldLabelValue = getDocumentFieldLabelValueForSiteMapEntry({ siteMapEntry, locale, contentSourceDataById: this.contentSourceDataById });
922
+ siteMapEntry = {
923
+ ...siteMapEntry,
924
+ label: fieldLabelValue ?? siteMapEntry.urlPath
925
+ };
926
+ }
927
+
928
+ if (!siteMapEntry.stableId) {
929
+ siteMapEntry = {
930
+ ...siteMapEntry,
931
+ stableId: 'document' in siteMapEntry ? siteMapEntry.document.id : siteMapEntry.urlPath
932
+ };
933
+ }
934
+
935
+ accum.push(siteMapEntry);
936
+ return accum;
937
+ }, []);
938
+
939
+ return _.isEmpty(locale) ? siteMapEntries : siteMapEntries.filter((siteMapEntry) => !siteMapEntry.locale || siteMapEntry.locale === locale);
940
+ }
941
+
908
942
  getDocument({
909
943
  srcDocumentId,
910
944
  srcProjectId,
@@ -925,7 +959,7 @@ export class ContentStore {
925
959
  (documents: ContentStoreTypes.Document[], contentSourceData) => {
926
960
  const currentDocuments = _.isEmpty(locale)
927
961
  ? contentSourceData.documents
928
- : contentSourceData.documents.filter(document => !document.locale || document.locale === locale)
962
+ : contentSourceData.documents.filter((document) => !document.locale || document.locale === locale);
929
963
  return documents.concat(currentDocuments);
930
964
  },
931
965
  []
@@ -944,7 +978,7 @@ export class ContentStore {
944
978
  (assets: ContentStoreTypes.Asset[], contentSourceData) => {
945
979
  const currentAssets = _.isEmpty(locale)
946
980
  ? contentSourceData.assets
947
- : contentSourceData.assets.filter(asset => !asset.locale || asset.locale === locale)
981
+ : contentSourceData.assets.filter((asset) => !asset.locale || asset.locale === locale);
948
982
  return assets.concat(currentAssets);
949
983
  },
950
984
  []
@@ -957,10 +991,10 @@ export class ContentStore {
957
991
  this.contentSourceDataById,
958
992
  (objects: ContentStoreTypes.APIObject[], contentSourceData) => {
959
993
  const documents = hasExplicitLocale
960
- ? contentSourceData.documents.filter(document => !document.locale || document.locale === locale)
994
+ ? contentSourceData.documents.filter((document) => !document.locale || document.locale === locale)
961
995
  : contentSourceData.documents;
962
996
  const assets = hasExplicitLocale
963
- ? contentSourceData.assets.filter(asset => !asset.locale || asset.locale === locale)
997
+ ? contentSourceData.assets.filter((asset) => !asset.locale || asset.locale === locale)
964
998
  : contentSourceData.assets;
965
999
  const currentLocale = locale ?? contentSourceData.defaultLocaleCode;
966
1000
  const documentObjects = mapDocumentsToLocalizedApiObjects(documents, currentLocale);
@@ -1568,12 +1602,12 @@ export class ContentStore {
1568
1602
 
1569
1603
  contentSourceIds.forEach((contentSourceId) => {
1570
1604
  const contentSourceData = this.getContentSourceDataByIdOrThrow(contentSourceId);
1571
-
1605
+
1572
1606
  _.set(schema, [contentSourceData.srcType, contentSourceData.srcProjectId], contentSourceData.modelMap);
1573
1607
 
1574
1608
  const contentSourceDocuments = _.isEmpty(locale)
1575
- ? contentSourceData.documents
1576
- : contentSourceData.documents.filter(document => !document.locale || document.locale === locale)
1609
+ ? contentSourceData.documents
1610
+ : contentSourceData.documents.filter((document) => !document.locale || document.locale === locale);
1577
1611
  documents.push(...contentSourceDocuments);
1578
1612
 
1579
1613
  if (contentSourceData.defaultLocaleCode) {
@@ -1624,28 +1658,6 @@ export class ContentStore {
1624
1658
  }
1625
1659
  }
1626
1660
 
1627
- function getCSIDocumentsAndAssetsFromContentSourceDataByIds(
1628
- contentSourceData: ContentSourceData,
1629
- objects: { srcObjectId: string }[]
1630
- ): {
1631
- documents: CSITypes.Document[];
1632
- assets: CSITypes.Asset[];
1633
- } {
1634
- const documents: CSITypes.Document[] = [];
1635
- const assets: CSITypes.Asset[] = [];
1636
- for (const object of objects) {
1637
- if (object.srcObjectId in contentSourceData.csiDocumentMap) {
1638
- documents.push(contentSourceData.csiDocumentMap[object.srcObjectId]!);
1639
- } else if (object.srcObjectId in contentSourceData.csiAssetMap) {
1640
- assets.push(contentSourceData.csiAssetMap[object.srcObjectId]!);
1641
- }
1642
- }
1643
- return {
1644
- documents,
1645
- assets
1646
- };
1647
- }
1648
-
1649
1661
  function internalValidateContent(
1650
1662
  documents: CSITypes.Document[],
1651
1663
  assets: CSITypes.Asset[],
@@ -1,6 +1,6 @@
1
1
  import _ from 'lodash';
2
- import { Field, FieldListProps, FieldModelProps, FieldObjectProps, FieldSpecificProps, Model, ImageModel } from '@stackbit/sdk';
3
- import { isLocalizedField } from '@stackbit/types';
2
+ import { Model, ImageModel } from '@stackbit/sdk';
3
+ import { Field, FieldSpecificProps, FieldList, FieldModelProps, FieldObjectProps, isLocalizedField } from '@stackbit/types';
4
4
  import * as CSITypes from '@stackbit/types';
5
5
 
6
6
  import * as ContentStoreTypes from '../content-store-types';
@@ -163,6 +163,7 @@ function mapCSIFieldsToStoreFields({
163
163
  const docField = mapCSIFieldToStoreField({
164
164
  csiDocumentField,
165
165
  modelField,
166
+ localized: modelField.localized,
166
167
  context
167
168
  });
168
169
  // Override document field types with specific model field types.
@@ -172,9 +173,6 @@ function mapCSIFieldsToStoreFields({
172
173
  docField.type = modelField.type;
173
174
  }
174
175
  docField.label = modelField.label;
175
- if ('localized' in modelField) {
176
- docField.localized = modelField.localized;
177
- }
178
176
  result[modelField.name] = docField;
179
177
  return result;
180
178
  }, {});
@@ -183,18 +181,24 @@ function mapCSIFieldsToStoreFields({
183
181
  function mapCSIFieldToStoreField({
184
182
  csiDocumentField,
185
183
  modelField,
184
+ localized,
186
185
  context
187
186
  }: {
188
187
  csiDocumentField: CSITypes.DocumentField | undefined;
189
- modelField: FieldSpecificProps;
188
+ modelField: Field | FieldSpecificProps;
189
+ localized?: boolean;
190
190
  context: MapContext;
191
191
  }): ContentStoreTypes.DocumentField {
192
192
  if (!csiDocumentField) {
193
193
  const isUnset = ['object', 'model', 'reference', 'richText', 'markdown', 'image', 'file', 'json'].includes(modelField.type);
194
194
  return {
195
195
  type: modelField.type,
196
- ...(isUnset ? { isUnset } : null),
197
- ...(modelField.type === 'list' ? { items: [] } : null)
196
+ ...(localized
197
+ ? { localized, locales: {} }
198
+ : {
199
+ ...(isUnset ? { isUnset } : null),
200
+ ...(modelField.type === 'list' ? { items: [] } : null)
201
+ })
198
202
  } as ContentStoreTypes.DocumentField;
199
203
  }
200
204
  // TODO: check if need to add "options" to "enum" and subtype/min/max to "number"
@@ -204,7 +208,8 @@ function mapCSIFieldToStoreField({
204
208
  case 'model':
205
209
  return mapModelField(csiDocumentField as CSITypes.DocumentModelField, modelField, context);
206
210
  case 'list':
207
- return mapListField(csiDocumentField as CSITypes.DocumentListField, modelField, context);
211
+ // list can not be in list, so modelField must be FieldList
212
+ return mapListField(csiDocumentField as CSITypes.DocumentListField, modelField as FieldList, context);
208
213
  case 'richText':
209
214
  return mapRichTextField(csiDocumentField as CSITypes.DocumentRichTextField);
210
215
  case 'markdown':
@@ -282,7 +287,7 @@ function mapModelField(csiDocumentField: CSITypes.DocumentModelField, modelField
282
287
  };
283
288
  }
284
289
 
285
- function mapListField(csiDocumentField: CSITypes.DocumentListField, modelField: FieldListProps, context: MapContext): ContentStoreTypes.DocumentListField {
290
+ function mapListField(csiDocumentField: CSITypes.DocumentListField, modelField: FieldList, context: MapContext): ContentStoreTypes.DocumentListField {
286
291
  if (!isLocalizedField(csiDocumentField)) {
287
292
  return {
288
293
  type: csiDocumentField.type,
@@ -290,8 +295,10 @@ function mapListField(csiDocumentField: CSITypes.DocumentListField, modelField:
290
295
  mapCSIFieldToStoreField({
291
296
  csiDocumentField: item,
292
297
  modelField: modelField.items ?? { type: 'string' },
298
+ // list items can not be localized, only the list itself can be localized
299
+ localized: false,
293
300
  context
294
- })
301
+ }) as ContentStoreTypes.DocumentListFieldItems
295
302
  )
296
303
  };
297
304
  }
@@ -305,8 +312,10 @@ function mapListField(csiDocumentField: CSITypes.DocumentListField, modelField:
305
312
  mapCSIFieldToStoreField({
306
313
  csiDocumentField: item,
307
314
  modelField: modelField.items ?? { type: 'string' },
315
+ // list items can not be localized, only the list itself can be localized
316
+ localized: false,
308
317
  context
309
- })
318
+ }) as ContentStoreTypes.DocumentListFieldItems
310
319
  )
311
320
  };
312
321
  })
@@ -149,7 +149,7 @@ function toLocalizedAPIField(docField: ContentStoreTypes.DocumentField, locale?:
149
149
  const { type, refType, localized, locales, ...base } = docField;
150
150
  const localeProps = locales && locale ? locales[locale] : undefined;
151
151
  // if reference field isUnset === true, it behaves like a regular object
152
- if (!localeProps || localeProps.isUnset) {
152
+ if (!localeProps) {
153
153
  return {
154
154
  type: 'object',
155
155
  isUnset: true,
@@ -186,14 +186,14 @@ function toLocalizedAPIField(docField: ContentStoreTypes.DocumentField, locale?:
186
186
  return {
187
187
  ...base,
188
188
  ...localeProps,
189
- items: (localeProps?.items ?? []).map((field) => toLocalizedAPIField(field, locale, true)),
189
+ items: (localeProps?.items ?? []).map((field) => toLocalizedAPIField(field, locale, true) as ContentStoreTypes.DocumentListFieldItemsAPI),
190
190
  ...localeFields(localized)
191
191
  };
192
192
  }
193
193
  return {
194
194
  ...docField,
195
195
  ...localeFields(docField.localized),
196
- items: docField.items.map((field) => toLocalizedAPIField(field, locale, true))
196
+ items: docField.items.map((field) => toLocalizedAPIField(field, locale, true) as ContentStoreTypes.DocumentListFieldItemsAPI)
197
197
  };
198
198
  default:
199
199
  const _exhaustiveCheck: never = docField;