@stackbit/cms-core 0.1.26-gitcms.3 → 0.1.26-gitcms.5

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 (96) hide show
  1. package/dist/content-store-utils.d.ts +5 -5
  2. package/dist/content-store-utils.d.ts.map +1 -1
  3. package/dist/content-store-utils.js +8 -6
  4. package/dist/content-store-utils.js.map +1 -1
  5. package/dist/content-store.d.ts +9 -6
  6. package/dist/content-store.d.ts.map +1 -1
  7. package/dist/content-store.js +7 -7
  8. package/dist/content-store.js.map +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/services/git.d.ts +6 -6
  14. package/dist/services/git.d.ts.map +1 -1
  15. package/dist/services/git.js +34 -29
  16. package/dist/services/git.js.map +1 -1
  17. package/dist/services/run.d.ts +5 -15
  18. package/dist/services/run.d.ts.map +1 -1
  19. package/dist/services/run.js +12 -13
  20. package/dist/services/run.js.map +1 -1
  21. package/dist/types/content-store-document-fields.d.ts +600 -0
  22. package/dist/types/content-store-document-fields.d.ts.map +1 -0
  23. package/dist/types/content-store-document-fields.js +3 -0
  24. package/dist/types/content-store-document-fields.js.map +1 -0
  25. package/dist/types/content-store-documents.d.ts +99 -0
  26. package/dist/types/content-store-documents.d.ts.map +1 -0
  27. package/dist/types/content-store-documents.js +3 -0
  28. package/dist/types/content-store-documents.js.map +1 -0
  29. package/dist/types/content-store-types.d.ts +75 -0
  30. package/dist/types/content-store-types.d.ts.map +1 -0
  31. package/dist/types/content-store-types.js.map +1 -0
  32. package/dist/types/content-store-update-operation.d.ts +61 -0
  33. package/dist/types/content-store-update-operation.d.ts.map +1 -0
  34. package/dist/types/content-store-update-operation.js +3 -0
  35. package/dist/types/content-store-update-operation.js.map +1 -0
  36. package/dist/types/index.d.ts +6 -0
  37. package/dist/types/index.d.ts.map +1 -0
  38. package/dist/types/index.js +18 -0
  39. package/dist/types/index.js.map +1 -0
  40. package/dist/types/search-filter.d.ts +1 -1
  41. package/dist/types/search-filter.d.ts.map +1 -1
  42. package/dist/utils/create-update-csi-docs.d.ts +1 -1
  43. package/dist/utils/create-update-csi-docs.d.ts.map +1 -1
  44. package/dist/utils/create-update-csi-docs.js +11 -10
  45. package/dist/utils/create-update-csi-docs.js.map +1 -1
  46. package/dist/utils/csi-to-store-docs-converter.d.ts +1 -1
  47. package/dist/utils/csi-to-store-docs-converter.d.ts.map +1 -1
  48. package/dist/utils/csi-to-store-docs-converter.js +20 -4
  49. package/dist/utils/csi-to-store-docs-converter.js.map +1 -1
  50. package/dist/utils/duplicate-document.d.ts +1 -1
  51. package/dist/utils/duplicate-document.d.ts.map +1 -1
  52. package/dist/utils/duplicate-document.js +7 -0
  53. package/dist/utils/duplicate-document.js.map +1 -1
  54. package/dist/utils/search-utils.d.ts +1 -1
  55. package/dist/utils/search-utils.d.ts.map +1 -1
  56. package/dist/utils/search-utils.js +16 -16
  57. package/dist/utils/search-utils.js.map +1 -1
  58. package/dist/utils/site-map.d.ts +1 -1
  59. package/dist/utils/site-map.d.ts.map +1 -1
  60. package/dist/utils/site-map.js +9 -0
  61. package/dist/utils/site-map.js.map +1 -1
  62. package/dist/utils/store-to-api-docs-converter.d.ts +3 -3
  63. package/dist/utils/store-to-api-docs-converter.d.ts.map +1 -1
  64. package/dist/utils/store-to-api-docs-converter.js +60 -32
  65. package/dist/utils/store-to-api-docs-converter.js.map +1 -1
  66. package/dist/utils/store-to-csi-docs-converter.d.ts +1 -1
  67. package/dist/utils/store-to-csi-docs-converter.d.ts.map +1 -1
  68. package/dist/utils/store-to-csi-docs-converter.js +4 -0
  69. package/dist/utils/store-to-csi-docs-converter.js.map +1 -1
  70. package/dist/utils/timer.d.ts +1 -1
  71. package/dist/utils/timer.d.ts.map +1 -1
  72. package/package.json +5 -5
  73. package/src/content-store-utils.ts +12 -11
  74. package/src/content-store.ts +22 -19
  75. package/src/index.ts +1 -1
  76. package/src/services/git.ts +44 -43
  77. package/src/services/run.ts +10 -15
  78. package/src/types/content-store-document-fields.ts +658 -0
  79. package/src/types/content-store-documents.ts +113 -0
  80. package/src/types/content-store-types.ts +96 -0
  81. package/src/types/content-store-update-operation.ts +85 -0
  82. package/src/types/index.ts +5 -0
  83. package/src/types/search-filter.ts +26 -19
  84. package/src/utils/create-update-csi-docs.ts +16 -12
  85. package/src/utils/csi-to-store-docs-converter.ts +33 -14
  86. package/src/utils/duplicate-document.ts +8 -1
  87. package/src/utils/search-utils.ts +18 -19
  88. package/src/utils/site-map.ts +10 -1
  89. package/src/utils/store-to-api-docs-converter.ts +67 -38
  90. package/src/utils/store-to-csi-docs-converter.ts +5 -1
  91. package/src/utils/timer.ts +1 -1
  92. package/dist/content-store-types.d.ts +0 -411
  93. package/dist/content-store-types.d.ts.map +0 -1
  94. package/dist/content-store-types.js.map +0 -1
  95. package/src/content-store-types.ts +0 -527
  96. /package/dist/{content-store-types.js → types/content-store-types.js} +0 -0
@@ -0,0 +1,113 @@
1
+ import { DocumentStatus } from '@stackbit/types';
2
+ import { DocumentField, DocumentFieldAPI, DocumentFieldAPIForType, DocumentStringLikeFieldForType } from './content-store-document-fields';
3
+
4
+ export interface Document {
5
+ type: 'document';
6
+ srcType: string;
7
+ srcProjectId: string;
8
+ srcProjectUrl: string;
9
+ srcEnvironment: string;
10
+ srcObjectId: string;
11
+ srcObjectUrl: string;
12
+ srcObjectLabel: string;
13
+ srcModelName: string;
14
+ srcModelLabel: string;
15
+ isChanged: boolean;
16
+ status: DocumentStatus;
17
+ createdAt: string;
18
+ createdBy?: string;
19
+ updatedAt: string;
20
+ updatedBy?: string[];
21
+ locale?: string;
22
+ fields: Record<string, DocumentField>;
23
+ }
24
+
25
+ export interface Asset {
26
+ type: 'asset';
27
+ srcType: string;
28
+ srcProjectId: string;
29
+ srcProjectUrl: string;
30
+ srcEnvironment: string;
31
+ srcObjectId: string;
32
+ srcObjectUrl: string;
33
+ srcObjectLabel: string;
34
+ srcModelName: string;
35
+ srcModelLabel: string;
36
+ isChanged: boolean;
37
+ status: DocumentStatus;
38
+ createdAt: string;
39
+ createdBy?: string;
40
+ updatedAt: string;
41
+ updatedBy?: string[];
42
+ locale?: string;
43
+ fields: AssetFields;
44
+ }
45
+
46
+ export type AssetFields = {
47
+ title: DocumentStringLikeFieldForType<'string'>;
48
+ file: AssetFileField;
49
+ };
50
+
51
+ export type AssetFileField = AssetFileFieldNonLocalized | AssetFileFieldLocalized;
52
+
53
+ export interface AssetFileFieldNonLocalized extends AssetFileFieldBase, AssetFileFieldProps {
54
+ label?: string;
55
+ localized?: false;
56
+ }
57
+ export interface AssetFileFieldLocalized extends AssetFileFieldBase {
58
+ label?: string;
59
+ localized: true;
60
+ locales: Record<
61
+ string,
62
+ {
63
+ locale: string;
64
+ } & AssetFileFieldProps
65
+ >;
66
+ }
67
+
68
+ export interface AssetFileFieldBase {
69
+ type: 'assetFile';
70
+ }
71
+
72
+ export interface AssetFileFieldProps {
73
+ url: string;
74
+ fileName?: string;
75
+ contentType?: string;
76
+ size?: number;
77
+ dimensions?: {
78
+ width?: number;
79
+ height?: number;
80
+ };
81
+ }
82
+
83
+ /**
84
+ * API Documents and Assets
85
+ */
86
+ export type APIObject = APIDocumentObject | APIImageObject;
87
+
88
+ export interface APIDocumentObject extends Omit<Document, 'fields' | 'type'> {
89
+ type: 'object';
90
+ fields: Record<string, DocumentFieldAPI>;
91
+ }
92
+
93
+ export interface APIImageObject extends Omit<Asset, 'fields' | 'type'> {
94
+ type: 'image';
95
+ fields: AssetFieldsAPI;
96
+ }
97
+
98
+ export type AssetFieldsAPI = {
99
+ title: DocumentFieldAPIForType<'string'>;
100
+ url: DocumentFieldAPIForType<'string'>;
101
+ };
102
+
103
+ export interface APIAsset {
104
+ objectId: string;
105
+ createdAt: string;
106
+ url: string;
107
+ title?: string;
108
+ fileName?: string;
109
+ contentType?: string;
110
+ size?: number;
111
+ width?: number;
112
+ height?: number;
113
+ }
@@ -0,0 +1,96 @@
1
+ import * as CSITypes from '@stackbit/types';
2
+ import { Model } from '@stackbit/sdk';
3
+ import { Asset, Document } from './content-store-documents';
4
+
5
+ export interface ContentSourceData {
6
+ /* Internal content source id computed by concatenating srcType and srcProjectId */
7
+ id: string;
8
+ /* The content source instance loaded from stackbitConfig.contentSources */
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
+
40
+ export interface UploadAssetData {
41
+ url: string;
42
+ data?: string;
43
+ metadata: {
44
+ name: string;
45
+ type: string;
46
+ };
47
+ }
48
+
49
+ export interface ContentChangeResultItem {
50
+ srcType: string;
51
+ srcProjectId: string;
52
+ srcObjectId: string;
53
+ }
54
+
55
+ export interface ContentChangeResult {
56
+ updatedDocuments: ContentChangeResultItem[];
57
+ updatedAssets: ContentChangeResultItem[];
58
+ deletedDocuments: ContentChangeResultItem[];
59
+ deletedAssets: ContentChangeResultItem[];
60
+ }
61
+
62
+ export interface User {
63
+ name: string;
64
+ email: string;
65
+ connections: {
66
+ type: string;
67
+ [key: string]: any;
68
+ }[];
69
+ }
70
+
71
+ export interface ValidationError {
72
+ message: string;
73
+ srcType: string;
74
+ srcProjectId: string;
75
+ srcObjectType: string;
76
+ srcObjectId: string;
77
+ fieldPath: (string | number)[];
78
+ isUniqueValidation?: boolean;
79
+ }
80
+
81
+ export interface HasAccessResult {
82
+ hasConnection: boolean;
83
+ hasPermissions: boolean;
84
+ contentSources: {
85
+ srcType: string;
86
+ srcProjectId: string;
87
+ hasConnection: boolean;
88
+ hasPermissions: boolean;
89
+ }[];
90
+ }
91
+
92
+ export interface CrossReferenceData {
93
+ refId: string;
94
+ refSrcType: string;
95
+ refProjectId: string;
96
+ }
@@ -0,0 +1,85 @@
1
+ import { FieldType } from '@stackbit/types';
2
+
3
+ export type UpdateOperation = UpdateOperationSet | UpdateOperationUnset | UpdateOperationInsert | UpdateOperationRemove | UpdateOperationReorder;
4
+
5
+ export interface UpdateOperationBase {
6
+ opType: string;
7
+ fieldPath: (string | number)[];
8
+ locale?: string;
9
+ }
10
+
11
+ export interface UpdateOperationSet extends UpdateOperationBase {
12
+ opType: 'set';
13
+ field: UpdateOperationField;
14
+ }
15
+
16
+ export interface UpdateOperationUnset extends UpdateOperationBase {
17
+ opType: 'unset';
18
+ }
19
+
20
+ export interface UpdateOperationInsert extends UpdateOperationBase {
21
+ opType: 'insert';
22
+ index?: number;
23
+ item: Exclude<UpdateOperationField, UpdateOperationListField>;
24
+ }
25
+
26
+ export interface UpdateOperationRemove extends UpdateOperationBase {
27
+ opType: 'remove';
28
+ index: number;
29
+ }
30
+
31
+ export interface UpdateOperationReorder extends UpdateOperationBase {
32
+ opType: 'reorder';
33
+ order: number[];
34
+ }
35
+
36
+ export type UpdateOperationField =
37
+ | UpdateOperationValueField
38
+ | UpdateOperationObjectField
39
+ | UpdateOperationModelField
40
+ | UpdateOperationReferenceField
41
+ | UpdateOperationCrossReferenceField
42
+ | UpdateOperationListField;
43
+
44
+ export type UpdateOperationValueFieldType = Exclude<FieldType, 'object' | 'model' | 'reference' | 'cross-reference' | 'list'>;
45
+
46
+ export type UpdateOperationValueField = DistributeUpdateOperationValueField<UpdateOperationValueFieldType>;
47
+
48
+ export type DistributeUpdateOperationValueField<Type extends UpdateOperationValueFieldType> = Type extends UpdateOperationValueFieldType
49
+ ? UpdateOperationValueFieldForType<Type>
50
+ : never;
51
+
52
+ export interface UpdateOperationValueFieldForType<Type extends UpdateOperationValueFieldType> {
53
+ type: Type;
54
+ value: any;
55
+ }
56
+
57
+ export interface UpdateOperationObjectField {
58
+ type: 'object';
59
+ object: Record<string, any>;
60
+ }
61
+
62
+ export interface UpdateOperationModelField {
63
+ type: 'model';
64
+ modelName: string;
65
+ object: Record<string, any>;
66
+ }
67
+
68
+ export interface UpdateOperationReferenceField {
69
+ type: 'reference';
70
+ refType: 'document' | 'asset';
71
+ refId: string;
72
+ }
73
+
74
+ export interface UpdateOperationCrossReferenceField {
75
+ type: 'cross-reference';
76
+ refType: 'document' | 'asset';
77
+ refId: string;
78
+ refSrcType: string;
79
+ refProjectId: string;
80
+ }
81
+
82
+ export interface UpdateOperationListField {
83
+ type: 'list';
84
+ items: any[];
85
+ }
@@ -0,0 +1,5 @@
1
+ export * from './content-store-types';
2
+ export * from './content-store-documents';
3
+ export * from './content-store-document-fields';
4
+ export * from './content-store-update-operation';
5
+ export * from './search-filter';
@@ -3,51 +3,58 @@ type Distribute<U> = U extends any ? U[] : never;
3
3
  type ValueType = string | number | Date | boolean;
4
4
 
5
5
  type BaseFilterItem = {
6
- field: string;
7
- isMeta?: boolean;
6
+ field: string;
7
+ isMeta?: boolean;
8
8
  };
9
9
 
10
10
  type EqualFilterItem = BaseFilterItem & {
11
- operator: 'eq' | 'neq';
12
- value: ValueType;
11
+ operator: 'eq' | 'neq';
12
+ value: ValueType;
13
13
  };
14
14
 
15
15
  type UndefinedFilterItem = BaseFilterItem & {
16
- operator: 'is-undefined' | 'is-not-undefined';
17
- }
16
+ operator: 'is-undefined' | 'is-not-undefined';
17
+ };
18
18
 
19
19
  type CompareFilterItem = BaseFilterItem & {
20
- operator: 'gte' | 'lte';
21
- value: ValueType;
20
+ operator: 'gte' | 'lte';
21
+ value: ValueType;
22
22
  };
23
23
 
24
24
  type IncludeStringFilterItem = BaseFilterItem & {
25
- operator: 'includes' | 'not-includes';
26
- value: string;
25
+ operator: 'includes' | 'not-includes';
26
+ value: string;
27
27
  };
28
28
 
29
29
  type IncludeListFilterItem = BaseFilterItem & {
30
- operator: 'in' | 'nin';
31
- values: Distribute<ValueType>;
30
+ operator: 'in' | 'nin';
31
+ values: Distribute<ValueType>;
32
32
  };
33
33
 
34
34
  type IncludeAllFilterItem = BaseFilterItem & {
35
- operator: 'all';
36
- values: Distribute<ValueType>;
35
+ operator: 'all';
36
+ values: Distribute<ValueType>;
37
37
  };
38
38
 
39
39
  type BetweenFilterItem = BaseFilterItem & {
40
- operator: 'between';
41
- startValue: ValueType;
42
- endValue: ValueType;
40
+ operator: 'between';
41
+ startValue: ValueType;
42
+ endValue: ValueType;
43
43
  };
44
44
 
45
- export type SearchFilterItem = EqualFilterItem | UndefinedFilterItem | CompareFilterItem | IncludeStringFilterItem | IncludeListFilterItem | IncludeAllFilterItem | BetweenFilterItem;
45
+ export type SearchFilterItem =
46
+ | EqualFilterItem
47
+ | UndefinedFilterItem
48
+ | CompareFilterItem
49
+ | IncludeStringFilterItem
50
+ | IncludeListFilterItem
51
+ | IncludeAllFilterItem
52
+ | BetweenFilterItem;
46
53
 
47
54
  export type SearchFilter = LogicalOperator;
48
55
 
49
56
  type LogicalOperator = LogicalAndOperator;
50
57
 
51
58
  type LogicalAndOperator = {
52
- 'and': SearchFilterItem[];
59
+ and: SearchFilterItem[];
53
60
  };
@@ -2,11 +2,11 @@ import _ from 'lodash';
2
2
  import slugify from 'slugify';
3
3
 
4
4
  import { Model as SDKModel } from '@stackbit/sdk';
5
- import { Model as CSIModel, Field, FieldSpecificProps, UpdateOperationListFieldItem } from '@stackbit/types';
5
+ import { Model as CSIModel, Field, FieldSpecificProps, UpdateOperationListFieldItem, isOneOfFieldTypes } from '@stackbit/types';
6
6
  import { fieldPathToString, mapPromise } from '@stackbit/utils';
7
7
  import * as CSITypes from '@stackbit/types';
8
8
 
9
- import * as ContentStoreTypes from '../content-store-types';
9
+ import * as ContentStoreTypes from '../types';
10
10
  import { getContentSourceId, getUserContextForSrcType, updateOperationValueFieldWithCrossReference } from '../content-store-utils';
11
11
 
12
12
  export type CreateDocumentCallback = ({
@@ -160,9 +160,8 @@ function extractTokensFromString(input: string): string[] {
160
160
  return input.match(/(?<={)[^}]+(?=})/g) || [];
161
161
  }
162
162
 
163
- function sanitizeSlug(slug: string) {
164
- return slug
165
- .split('/')
163
+ function sanitizeSlug(slug?: string) {
164
+ return slug?.split('/')
166
165
  .map((part) => slugify(part, { lower: true }))
167
166
  .join('/');
168
167
  }
@@ -337,10 +336,10 @@ async function createUpdateOperationFieldRecursively({
337
336
  return {
338
337
  field: {
339
338
  type: 'image',
340
- value: _.omit(value, ['$$type'])
339
+ value: _.omit(value, ['$$type']) // backwards compatibility with legacy presets
341
340
  },
342
341
  newRefDocuments: []
343
- }
342
+ };
344
343
  }
345
344
  if (_.isPlainObject(value)) {
346
345
  refId = value.$$ref ?? value.url;
@@ -403,8 +402,13 @@ async function createUpdateOperationFieldRecursively({
403
402
  newRefDocuments: [document, ...newRefDocuments]
404
403
  };
405
404
  }
406
- } else if (['string', 'text', 'json'].includes(csiModelField.type) && modelField.type === 'cross-reference') {
407
- const fieldType = csiModelField.type as 'string' | 'text' | 'json';
405
+ } else if (
406
+ csiModelField.type === 'cross-reference' ||
407
+ (isOneOfFieldTypes(csiModelField.type, ['string', 'text', 'json']) && modelField.type === 'cross-reference')
408
+ ) {
409
+ if (modelField.type !== 'cross-reference') {
410
+ throw new Error(`field type mismatch between content-source and mapped models at field path ${fieldPathToString(fieldPath)}`);
411
+ }
408
412
  let { $$ref: refId = null, $$type: modelName = null, $$refSrcType: refSrcType = null, $$refProjectId: refProjectId = null, ...rest } = value;
409
413
  let refObject;
410
414
  const newRefDocuments: CSITypes.Document[] = [];
@@ -433,7 +437,7 @@ async function createUpdateOperationFieldRecursively({
433
437
  refObject = { refId: document.id, refSrcType, refProjectId };
434
438
  }
435
439
  return {
436
- field: updateOperationValueFieldWithCrossReference(fieldType, refObject),
440
+ field: updateOperationValueFieldWithCrossReference(csiModelField.type, refObject),
437
441
  newRefDocuments
438
442
  };
439
443
  } else if (csiModelField.type === 'list') {
@@ -569,7 +573,7 @@ export async function convertOperationField({
569
573
  // ContentStore and CSI 'reference' operation field have the same format
570
574
  return operationField;
571
575
  case 'cross-reference':
572
- if (csiModelField.type !== 'string' && csiModelField.type !== 'text' && csiModelField.type !== 'json') {
576
+ if (!isOneOfFieldTypes(csiModelField.type, ['string', 'text', 'json', 'cross-reference'])) {
573
577
  throw new Error(
574
578
  `update operation with with 'cross-reference' field can be performed on 'string', 'text' and 'json' content-source field types only, got '${csiModelField.type}'`
575
579
  );
@@ -581,7 +585,7 @@ export async function convertOperationField({
581
585
  };
582
586
  return {
583
587
  type: csiModelField.type,
584
- value: csiModelField.type === 'json' ? refObject : JSON.stringify(refObject)
588
+ value: isOneOfFieldTypes(csiModelField.type, ['json', 'cross-reference']) ? refObject : JSON.stringify(refObject)
585
589
  };
586
590
  case 'list': {
587
591
  if (modelField.type !== 'list' || csiModelField.type !== 'list') {
@@ -1,9 +1,9 @@
1
1
  import _ from 'lodash';
2
2
  import { Model, ImageModel } from '@stackbit/sdk';
3
- import { Field, FieldSpecificProps, FieldList, FieldModelProps, FieldObjectProps, isLocalizedField } from '@stackbit/types';
3
+ import { Field, FieldSpecificProps, FieldList, FieldModelProps, FieldObjectProps, isLocalizedField, isDocumentFieldOneOfFieldTypes } from '@stackbit/types';
4
4
  import * as CSITypes from '@stackbit/types';
5
5
 
6
- import * as ContentStoreTypes from '../content-store-types';
6
+ import * as ContentStoreTypes from '../types';
7
7
  import { IMAGE_MODEL } from '../common/common-schema';
8
8
  import { omitByNil } from '@stackbit/utils';
9
9
 
@@ -185,13 +185,13 @@ function mapCSIFieldToStoreField({
185
185
  context: MapContext;
186
186
  }): ContentStoreTypes.DocumentField {
187
187
  if (!csiDocumentField) {
188
- const isUnset = ['object', 'model', 'reference', 'cross-reference', 'richText', 'markdown', 'image', 'file', 'json'].includes(modelField.type);
188
+ const shouldUseIsUnset = ['markdown', 'richText', 'image', 'file', 'json', 'object', 'model', 'reference', 'cross-reference'].includes(modelField.type);
189
189
  return {
190
190
  type: modelField.type,
191
191
  ...(localized
192
192
  ? { localized, locales: {} }
193
193
  : {
194
- ...(isUnset ? { isUnset } : null),
194
+ ...(shouldUseIsUnset ? { isUnset: true } : null),
195
195
  ...(modelField.type === 'list' ? { items: [] } : null)
196
196
  })
197
197
  } as ContentStoreTypes.DocumentField;
@@ -225,7 +225,7 @@ function mapCSIFieldToStoreField({
225
225
  case 'reference':
226
226
  return csiDocumentField as ContentStoreTypes.DocumentField;
227
227
  case 'cross-reference':
228
- return mapReferenceField(csiDocumentField)
228
+ return mapReferenceField(csiDocumentField);
229
229
  case 'object':
230
230
  return mapObjectField(csiDocumentField as CSITypes.DocumentObjectField, modelField, context);
231
231
  case 'model':
@@ -236,7 +236,7 @@ function mapCSIFieldToStoreField({
236
236
  case 'richText':
237
237
  return mapRichTextField(csiDocumentField as CSITypes.DocumentRichTextField);
238
238
  case 'markdown':
239
- return mapMarkdownField(csiDocumentField as CSITypes.DocumentValueField);
239
+ return mapMarkdownField(csiDocumentField as CSITypes.DocumentStringLikeField);
240
240
  default: {
241
241
  const _exhaustiveCheck: never = modelField;
242
242
  return _exhaustiveCheck;
@@ -250,7 +250,8 @@ function mapReferenceField(csiDocumentField: CSITypes.DocumentField): ContentSto
250
250
  refType: 'document',
251
251
  isUnset: true
252
252
  } as const;
253
- if (csiDocumentField.type !== 'string' && csiDocumentField.type !== 'text' && csiDocumentField.type !== 'json') {
253
+
254
+ if (!isDocumentFieldOneOfFieldTypes(csiDocumentField, ['string', 'text', 'json', 'cross-reference'])) {
254
255
  if (isLocalizedField(csiDocumentField)) {
255
256
  return {
256
257
  type: 'cross-reference',
@@ -261,6 +262,28 @@ function mapReferenceField(csiDocumentField: CSITypes.DocumentField): ContentSto
261
262
  }
262
263
  return unlocalizedUnset;
263
264
  }
265
+
266
+ if (csiDocumentField.type === 'cross-reference') {
267
+ if (isLocalizedField(csiDocumentField)) {
268
+ return {
269
+ type: 'cross-reference',
270
+ refType: 'document',
271
+ localized: true,
272
+ locales: _.reduce(
273
+ csiDocumentField.locales,
274
+ (accum: Record<string, { locale: string; refId: string; refSrcType: string; refProjectId: string }>, locale, localeKey) => {
275
+ // the documentField.type is 'cross-reference', so it is already in the correct format
276
+ accum[localeKey] = locale;
277
+ return accum;
278
+ },
279
+ {}
280
+ )
281
+ };
282
+ } else {
283
+ return csiDocumentField;
284
+ }
285
+ }
286
+
264
287
  const parseRefObject = (value: any): { refId: string; refSrcType: string; refProjectId: string } | null => {
265
288
  if (typeof value === 'string') {
266
289
  try {
@@ -278,8 +301,8 @@ function mapReferenceField(csiDocumentField: CSITypes.DocumentField): ContentSto
278
301
  }
279
302
  return null;
280
303
  };
304
+
281
305
  if (isLocalizedField(csiDocumentField)) {
282
- csiDocumentField.locales;
283
306
  return {
284
307
  type: 'cross-reference',
285
308
  refType: 'document',
@@ -438,7 +461,7 @@ function mapRichTextField(csiDocumentField: CSITypes.DocumentRichTextField): Con
438
461
  };
439
462
  }
440
463
 
441
- function mapMarkdownField(csiDocumentField: CSITypes.DocumentValueField): ContentStoreTypes.DocumentMarkdownField {
464
+ function mapMarkdownField(csiDocumentField: CSITypes.DocumentStringLikeField): ContentStoreTypes.DocumentMarkdownField {
442
465
  if (!isLocalizedField(csiDocumentField)) {
443
466
  return {
444
467
  type: 'markdown',
@@ -458,11 +481,7 @@ function mapMarkdownField(csiDocumentField: CSITypes.DocumentValueField): Conten
458
481
  };
459
482
  }
460
483
 
461
- function getMetadataFromContentStore({
462
- contentSourceInstance
463
- }: {
464
- contentSourceInstance: CSITypes.ContentSourceInterface;
465
- }): {
484
+ function getMetadataFromContentStore({ contentSourceInstance }: { contentSourceInstance: CSITypes.ContentSourceInterface }): {
466
485
  srcType: string;
467
486
  srcProjectId: string;
468
487
  srcProjectUrl: string;
@@ -1,6 +1,6 @@
1
1
  import _ from 'lodash';
2
2
 
3
- import * as ContentStoreTypes from '../content-store-types';
3
+ import * as ContentStoreTypes from '../types';
4
4
  import { getContentSourceId, getDocumentFieldForLocale } from '../content-store-utils';
5
5
  import { IMAGE_MODEL } from '../common/common-schema';
6
6
 
@@ -111,8 +111,15 @@ function mergeObjectWithDocumentField({
111
111
  break;
112
112
  }
113
113
  case 'image': {
114
+ if (typeof value !== 'undefined') {
115
+ return value;
116
+ }
114
117
  const localizedField = getDocumentFieldForLocale(documentField, locale);
115
118
  if (localizedField && !localizedField.isUnset && isPlainObjectOrUndefined(value)) {
119
+ if (localizedField?.sourceData) {
120
+ return localizedField?.sourceData;
121
+ }
122
+ //TODO needs testing, looks like we need to use the url field instead of this
116
123
  return mergeObjectWithDocumentFields({
117
124
  object: value,
118
125
  documentFields: localizedField.fields,