@stackbit/cms-core 0.1.1 → 0.1.3-alpha.0

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 (34) hide show
  1. package/dist/content-source-interface.d.ts +3 -11
  2. package/dist/content-source-interface.d.ts.map +1 -1
  3. package/dist/content-source-interface.js.map +1 -1
  4. package/dist/content-store-types.d.ts +15 -24
  5. package/dist/content-store-types.d.ts.map +1 -1
  6. package/dist/content-store-utils.d.ts +9 -0
  7. package/dist/content-store-utils.d.ts.map +1 -0
  8. package/dist/content-store-utils.js +139 -0
  9. package/dist/content-store-utils.js.map +1 -0
  10. package/dist/content-store.d.ts +0 -1
  11. package/dist/content-store.d.ts.map +1 -1
  12. package/dist/content-store.js +99 -945
  13. package/dist/content-store.js.map +1 -1
  14. package/dist/utils/create-update-csi-docs.d.ts +68 -0
  15. package/dist/utils/create-update-csi-docs.d.ts.map +1 -0
  16. package/dist/utils/create-update-csi-docs.js +376 -0
  17. package/dist/utils/create-update-csi-docs.js.map +1 -0
  18. package/dist/utils/csi-to-store-docs-converter.d.ts +15 -0
  19. package/dist/utils/csi-to-store-docs-converter.d.ts.map +1 -0
  20. package/dist/utils/csi-to-store-docs-converter.js +287 -0
  21. package/dist/utils/csi-to-store-docs-converter.js.map +1 -0
  22. package/dist/utils/store-to-api-docs-converter.d.ts +5 -0
  23. package/dist/utils/store-to-api-docs-converter.d.ts.map +1 -0
  24. package/dist/utils/store-to-api-docs-converter.js +247 -0
  25. package/dist/utils/store-to-api-docs-converter.js.map +1 -0
  26. package/package.json +4 -4
  27. package/src/content-source-interface.ts +4 -13
  28. package/src/content-store-types.ts +12 -10
  29. package/src/content-store-utils.ts +149 -0
  30. package/src/content-store.ts +57 -1073
  31. package/src/index.ts +1 -1
  32. package/src/utils/create-update-csi-docs.ts +440 -0
  33. package/src/utils/csi-to-store-docs-converter.ts +365 -0
  34. package/src/utils/store-to-api-docs-converter.ts +246 -0
@@ -1,6 +1,6 @@
1
1
  import { DocumentStatus, FieldType } from './content-source-interface';
2
2
 
3
- export { FieldType, Logger, LeveledLogMethod, DocumentStatus } from './content-source-interface';
3
+ export { FieldType, DocumentStatus, Logger } from './content-source-interface';
4
4
 
5
5
  export interface Document {
6
6
  type: 'document';
@@ -168,7 +168,7 @@ export type DocumentFieldTypeLocalized<BaseFieldProps, LocalizedFieldProps> = Si
168
168
  BaseFieldProps & {
169
169
  label?: string;
170
170
  localized: true;
171
- locales: Record<string, { locale: string } & Omit<LocalizedFieldProps, 'isUnset'>>;
171
+ locales: Record<string, { locale: string } & Exclude<LocalizedFieldProps, DocumentFieldUnsetProps>>;
172
172
  }
173
173
  >;
174
174
 
@@ -221,6 +221,8 @@ export type DocumentValueFieldProps = {
221
221
  value: any;
222
222
  };
223
223
 
224
+ export type DocumentFieldUnsetProps = { isUnset: true };
225
+
224
226
  // object
225
227
  export type DocumentObjectField = DocumentObjectFieldLocalized | DocumentObjectFieldNonLocalized;
226
228
  export type DocumentObjectFieldLocalized = DocumentFieldTypeLocalized<DocumentObjectFieldBase, DocumentObjectFieldProps>;
@@ -230,22 +232,22 @@ export type DocumentObjectFieldBase = { type: 'object' };
230
232
  export type DocumentObjectFieldPropsCommon = {
231
233
  srcObjectLabel: string;
232
234
  };
233
- export type DocumentObjectFieldProps = { isUnset: true } | ({ isUnset?: false; fields: Record<string, DocumentField> } & DocumentObjectFieldPropsCommon);
234
- export type DocumentObjectFieldPropsAPI = { isUnset: true } | ({ isUnset?: false; fields: Record<string, DocumentFieldAPI> } & DocumentObjectFieldPropsCommon);
235
+ export type DocumentObjectFieldProps = DocumentFieldUnsetProps | ({ isUnset?: false; fields: Record<string, DocumentField> } & DocumentObjectFieldPropsCommon);
236
+ export type DocumentObjectFieldPropsAPI = DocumentFieldUnsetProps | ({ isUnset?: false; fields: Record<string, DocumentFieldAPI> } & DocumentObjectFieldPropsCommon);
235
237
 
236
238
  // model
237
239
  export type DocumentModelField = DocumentModelFieldLocalized | DocumentModelFieldNonLocalized;
238
240
  export type DocumentModelFieldLocalized = DocumentFieldTypeLocalized<DocumentModelFieldBase, DocumentModelFieldProps>;
239
241
  export type DocumentModelFieldNonLocalized = DocumentFieldTypeNonLocalized<DocumentModelFieldBase, DocumentModelFieldProps>;
240
- export type DocumentModelFieldAPI = DocumentFieldTypeAPI<DocumentModelFieldBase, DocumentModelFieldPropsAPI>;
242
+ export type DocumentModelFieldAPI = DocumentFieldTypeAPI<{ type: 'object' }, DocumentModelFieldPropsAPI>;
241
243
  export type DocumentModelFieldBase = { type: 'model' };
242
244
  export type DocumentModelFieldPropsCommon = {
243
245
  srcObjectLabel: string;
244
246
  srcModelName: string;
245
247
  srcModelLabel: string;
246
248
  };
247
- export type DocumentModelFieldProps = { isUnset: true } | ({ isUnset?: false; fields: Record<string, DocumentField> } & DocumentModelFieldPropsCommon);
248
- export type DocumentModelFieldPropsAPI = { isUnset: true } | ({ isUnset?: false; fields: Record<string, DocumentFieldAPI> } & DocumentModelFieldPropsCommon);
249
+ export type DocumentModelFieldProps = DocumentFieldUnsetProps | ({ isUnset?: false; fields: Record<string, DocumentField> } & DocumentModelFieldPropsCommon);
250
+ export type DocumentModelFieldPropsAPI = DocumentFieldUnsetProps | ({ isUnset?: false; fields: Record<string, DocumentFieldAPI> } & DocumentModelFieldPropsCommon);
249
251
 
250
252
  // reference
251
253
  export type DocumentReferenceField = DocumentReferenceFieldLocalized | DocumentReferenceFieldNonLocalized;
@@ -256,7 +258,7 @@ export type DocumentReferenceFieldBase = {
256
258
  type: 'reference';
257
259
  refType: 'document' | 'asset';
258
260
  };
259
- export type DocumentReferenceFieldProps = { isUnset: true } | { isUnset?: false; refId: string };
261
+ export type DocumentReferenceFieldProps = DocumentFieldUnsetProps | { isUnset?: false; refId: string };
260
262
  export type DocumentReferenceFieldBaseAPI = {
261
263
  type: 'unresolved_reference';
262
264
  refType: 'object' | 'image';
@@ -312,8 +314,8 @@ export type DocumentImageFieldLocalized = DocumentFieldTypeLocalized<DocumentIma
312
314
  export type DocumentImageFieldNonLocalized = DocumentFieldTypeNonLocalized<DocumentImageFieldBase, DocumentImageFieldProps>;
313
315
  export type DocumentImageFieldAPI = DocumentFieldTypeAPI<DocumentImageFieldBase, DocumentImageFieldPropsAPI>;
314
316
  export type DocumentImageFieldBase = { type: 'image' };
315
- export type DocumentImageFieldProps = { isUnset: true } | { isUnset?: false; fields: AssetFieldsAPI };
316
- export type DocumentImageFieldPropsAPI = { isUnset: true } | { isUnset?: false; fields: AssetFieldsAPI };
317
+ export type DocumentImageFieldProps = DocumentFieldUnsetProps | { isUnset?: false; fields: AssetFieldsAPI };
318
+ export type DocumentImageFieldPropsAPI = DocumentFieldUnsetProps | { isUnset?: false; fields: AssetFieldsAPI };
317
319
 
318
320
  // assetFile
319
321
  export type AssetFileField = AssetFileFieldLocalized | AssetFileFieldNonLocalized;
@@ -0,0 +1,149 @@
1
+ import _ from 'lodash';
2
+ import { Field, FieldList, FieldListItems, FieldListProps, FieldObjectProps, FieldSpecificProps, Model } from '@stackbit/sdk';
3
+
4
+ import * as ContentStoreTypes from './content-store-types';
5
+ import * as CSITypes from './content-source-interface';
6
+
7
+ export function getContentSourceIdForContentSource(contentSource: CSITypes.ContentSourceInterface): string {
8
+ return getContentSourceId(contentSource.getContentSourceType(), contentSource.getProjectId());
9
+ }
10
+
11
+ export function getContentSourceId(contentSourceType: string, srcProjectId: string) {
12
+ return contentSourceType + ':' + srcProjectId;
13
+ }
14
+
15
+ export function getUserContextForSrcType(srcType: string, user?: ContentStoreTypes.User): unknown {
16
+ return user?.connections?.find((connection) => connection.type === srcType);
17
+ }
18
+
19
+ export function getDocumentFieldForLocale<Type extends ContentStoreTypes.FieldType>(
20
+ docField: ContentStoreTypes.DocumentFieldForType<Type>,
21
+ locale?: string
22
+ ): ContentStoreTypes.DocumentFieldNonLocalizedForType<Type> | null {
23
+ if (docField.localized) {
24
+ if (!locale) {
25
+ return null;
26
+ }
27
+ const { localized, locales, ...base } = docField;
28
+ const localizedField = locales[locale];
29
+ if (!localizedField) {
30
+ return null;
31
+ }
32
+ return ({
33
+ ...base,
34
+ ...localizedField
35
+ } as unknown) as ContentStoreTypes.DocumentFieldNonLocalizedForType<Type>;
36
+ } else {
37
+ return docField;
38
+ }
39
+ }
40
+
41
+ export function getModelFieldForFieldAtPath(
42
+ document: ContentStoreTypes.Document,
43
+ model: Model,
44
+ fieldPath: (string | number)[],
45
+ modelMap: Record<string, Model>,
46
+ locale?: string
47
+ ): Field {
48
+ if (_.isEmpty(fieldPath)) {
49
+ throw new Error('the fieldPath can not be empty');
50
+ }
51
+
52
+ function getField(docField: ContentStoreTypes.DocumentField, modelField: FieldSpecificProps, fieldPath: (string | number)[]): Field {
53
+ const fieldName = _.head(fieldPath);
54
+ if (typeof fieldName === 'undefined') {
55
+ throw new Error('the first fieldPath item must be string');
56
+ }
57
+ const childFieldPath = _.tail(fieldPath);
58
+ let childDocField: ContentStoreTypes.DocumentField | undefined;
59
+ let childModelField: Field | undefined;
60
+ switch (docField.type) {
61
+ case 'object':
62
+ const localizedObjectField = getDocumentFieldForLocale(docField, locale);
63
+ if (!localizedObjectField) {
64
+ throw new Error(`locale for field was not found`);
65
+ }
66
+ if (localizedObjectField.isUnset) {
67
+ throw new Error(`field is not set`);
68
+ }
69
+ childDocField = localizedObjectField.fields[fieldName];
70
+ childModelField = _.find((modelField as FieldObjectProps).fields, (field) => field.name === fieldName);
71
+ if (!childDocField || !childModelField) {
72
+ throw new Error(`field ${fieldName} doesn't exist`);
73
+ }
74
+ if (childFieldPath.length === 0) {
75
+ return childModelField;
76
+ }
77
+ return getField(childDocField, childModelField, childFieldPath);
78
+ case 'model':
79
+ const localizedModelField = getDocumentFieldForLocale(docField, locale);
80
+ if (!localizedModelField) {
81
+ throw new Error(`locale for field was not found`);
82
+ }
83
+ if (localizedModelField.isUnset) {
84
+ throw new Error(`field is not set`);
85
+ }
86
+ const modelName = localizedModelField.srcModelName;
87
+ const childModel = modelMap[modelName];
88
+ if (!childModel) {
89
+ throw new Error(`model ${modelName} doesn't exist`);
90
+ }
91
+ childModelField = _.find(childModel.fields, (field) => field.name === fieldName);
92
+ childDocField = localizedModelField.fields![fieldName];
93
+ if (!childDocField || !childModelField) {
94
+ throw new Error(`field ${fieldName} doesn't exist`);
95
+ }
96
+ if (childFieldPath.length === 0) {
97
+ return childModelField;
98
+ }
99
+ return getField(childDocField, childModelField!, childFieldPath);
100
+ case 'list':
101
+ const localizedListField = getDocumentFieldForLocale(docField, locale);
102
+ if (!localizedListField) {
103
+ throw new Error(`locale for field was not found`);
104
+ }
105
+ const listItem = localizedListField.items && localizedListField.items[fieldName as number];
106
+ const listItemsModel = (modelField as FieldListProps).items;
107
+ if (!listItem || !listItemsModel) {
108
+ throw new Error(`field ${fieldName} doesn't exist`);
109
+ }
110
+ if (childFieldPath.length === 0) {
111
+ return modelField as FieldList;
112
+ }
113
+ if (!Array.isArray(listItemsModel)) {
114
+ return getField(listItem, listItemsModel, childFieldPath);
115
+ } else {
116
+ const fieldListItems = (listItemsModel as FieldListItems[]).find((listItemsModel) => listItemsModel.type === listItem.type);
117
+ if (!fieldListItems) {
118
+ throw new Error('cannot find matching field model');
119
+ }
120
+ return getField(listItem, fieldListItems, childFieldPath);
121
+ }
122
+ default:
123
+ if (!_.isEmpty(childFieldPath)) {
124
+ throw new Error('illegal fieldPath');
125
+ }
126
+ return modelField as Field;
127
+ }
128
+ }
129
+
130
+ const fieldName = _.head(fieldPath);
131
+ const childFieldPath = _.tail(fieldPath);
132
+
133
+ if (typeof fieldName !== 'string') {
134
+ throw new Error('the first fieldPath item must be string');
135
+ }
136
+
137
+ const childDocField = document.fields[fieldName];
138
+ const childModelField = _.find(model.fields, { name: fieldName });
139
+
140
+ if (!childDocField || !childModelField) {
141
+ throw new Error(`field ${fieldName} doesn't exist`);
142
+ }
143
+
144
+ if (childFieldPath.length === 0) {
145
+ return childModelField;
146
+ }
147
+
148
+ return getField(childDocField, childModelField, childFieldPath);
149
+ }