@stackbit/cms-core 0.1.3 → 0.1.4-alpha.1

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 (57) hide show
  1. package/dist/common/common-types.d.ts +1 -9
  2. package/dist/common/common-types.d.ts.map +1 -1
  3. package/dist/consts.d.ts +1 -24
  4. package/dist/consts.d.ts.map +1 -1
  5. package/dist/consts.js +5 -25
  6. package/dist/consts.js.map +1 -1
  7. package/dist/content-store-types.d.ts +42 -39
  8. package/dist/content-store-types.d.ts.map +1 -1
  9. package/dist/content-store-utils.d.ts +10 -0
  10. package/dist/content-store-utils.d.ts.map +1 -0
  11. package/dist/content-store-utils.js +139 -0
  12. package/dist/content-store-utils.js.map +1 -0
  13. package/dist/content-store.d.ts +18 -5
  14. package/dist/content-store.d.ts.map +1 -1
  15. package/dist/content-store.js +177 -962
  16. package/dist/content-store.js.map +1 -1
  17. package/dist/index.d.ts +2 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +3 -2
  20. package/dist/index.js.map +1 -1
  21. package/dist/types/search-filter.d.ts +42 -0
  22. package/dist/types/search-filter.d.ts.map +1 -0
  23. package/dist/types/search-filter.js +3 -0
  24. package/dist/types/search-filter.js.map +1 -0
  25. package/dist/utils/create-update-csi-docs.d.ts +69 -0
  26. package/dist/utils/create-update-csi-docs.d.ts.map +1 -0
  27. package/dist/utils/create-update-csi-docs.js +386 -0
  28. package/dist/utils/create-update-csi-docs.js.map +1 -0
  29. package/dist/utils/csi-to-store-docs-converter.d.ts +15 -0
  30. package/dist/utils/csi-to-store-docs-converter.d.ts.map +1 -0
  31. package/dist/utils/csi-to-store-docs-converter.js +287 -0
  32. package/dist/utils/csi-to-store-docs-converter.js.map +1 -0
  33. package/dist/utils/search-utils.d.ts +21 -0
  34. package/dist/utils/search-utils.d.ts.map +1 -0
  35. package/dist/utils/search-utils.js +323 -0
  36. package/dist/utils/search-utils.js.map +1 -0
  37. package/dist/utils/store-to-api-docs-converter.d.ts +5 -0
  38. package/dist/utils/store-to-api-docs-converter.d.ts.map +1 -0
  39. package/dist/utils/store-to-api-docs-converter.js +247 -0
  40. package/dist/utils/store-to-api-docs-converter.js.map +1 -0
  41. package/package.json +7 -5
  42. package/src/common/common-types.ts +1 -10
  43. package/src/consts.ts +1 -26
  44. package/src/content-store-types.ts +59 -45
  45. package/src/content-store-utils.ts +150 -0
  46. package/src/content-store.ts +168 -1090
  47. package/src/index.ts +3 -2
  48. package/src/types/search-filter.ts +53 -0
  49. package/src/utils/create-update-csi-docs.ts +457 -0
  50. package/src/utils/csi-to-store-docs-converter.ts +366 -0
  51. package/src/utils/search-utils.ts +437 -0
  52. package/src/utils/store-to-api-docs-converter.ts +246 -0
  53. package/dist/content-source-interface.d.ts +0 -338
  54. package/dist/content-source-interface.d.ts.map +0 -1
  55. package/dist/content-source-interface.js +0 -28
  56. package/dist/content-source-interface.js.map +0 -1
  57. package/src/content-source-interface.ts +0 -495
@@ -0,0 +1,366 @@
1
+ import _ from 'lodash';
2
+ import { Field, FieldListProps, FieldModelProps, FieldObjectProps, FieldSpecificProps, Model } from '@stackbit/sdk';
3
+ import { isLocalizedField } from '@stackbit/types';
4
+ import * as CSITypes from '@stackbit/types';
5
+
6
+ import * as ContentStoreTypes from '../content-store-types';
7
+ import { IMAGE_MODEL } from '../common/common-schema';
8
+
9
+ export function mapCSIAssetsToStoreAssets({
10
+ csiAssets,
11
+ contentSourceInstance,
12
+ defaultLocaleCode
13
+ }: {
14
+ csiAssets: CSITypes.Asset[];
15
+ contentSourceInstance: CSITypes.ContentSourceInterface;
16
+ defaultLocaleCode?: string;
17
+ }): ContentStoreTypes.Asset[] {
18
+ const extra = getMetadataFromContentStore({ contentSourceInstance });
19
+ return csiAssets.map((csiAsset) =>
20
+ sourceAssetToStoreAsset({
21
+ csiAsset,
22
+ defaultLocaleCode,
23
+ extra
24
+ })
25
+ );
26
+ }
27
+
28
+ function sourceAssetToStoreAsset({
29
+ csiAsset,
30
+ defaultLocaleCode,
31
+ extra
32
+ }: {
33
+ csiAsset: CSITypes.Asset;
34
+ defaultLocaleCode?: string;
35
+ extra: { srcType: string; srcProjectId: string; srcProjectUrl: string; srcEnvironment: string };
36
+ }): ContentStoreTypes.Asset {
37
+ return {
38
+ type: 'asset',
39
+ ...extra,
40
+ srcObjectId: csiAsset.id,
41
+ srcObjectUrl: csiAsset.manageUrl,
42
+ srcObjectLabel: getObjectLabel(csiAsset.fields, IMAGE_MODEL, defaultLocaleCode),
43
+ srcModelName: IMAGE_MODEL.name,
44
+ srcModelLabel: IMAGE_MODEL.label!,
45
+ isChanged: csiAsset.status === 'added' || csiAsset.status === 'modified',
46
+ status: csiAsset.status,
47
+ createdAt: csiAsset.createdAt,
48
+ createdBy: csiAsset.createdBy,
49
+ updatedAt: csiAsset.updatedAt,
50
+ updatedBy: csiAsset.updatedBy,
51
+ fields: {
52
+ title: {
53
+ label: 'Title',
54
+ ...csiAsset.fields.title
55
+ },
56
+ file: {
57
+ label: 'File',
58
+ ...csiAsset.fields.file
59
+ }
60
+ }
61
+ };
62
+ }
63
+
64
+ export function mapCSIDocumentsToStoreDocuments({
65
+ csiDocuments,
66
+ contentSourceInstance,
67
+ modelMap,
68
+ defaultLocaleCode
69
+ }: {
70
+ csiDocuments: CSITypes.Document[];
71
+ contentSourceInstance: CSITypes.ContentSourceInterface;
72
+ modelMap: Record<string, Model>;
73
+ defaultLocaleCode?: string;
74
+ }): ContentStoreTypes.Document[] {
75
+ const extra = getMetadataFromContentStore({ contentSourceInstance });
76
+ return csiDocuments.map((csiDocument) =>
77
+ mapCSIDocumentToStoreDocument({
78
+ csiDocument,
79
+ model: modelMap[csiDocument.modelName]!,
80
+ modelMap,
81
+ defaultLocaleCode,
82
+ extra
83
+ })
84
+ );
85
+ }
86
+
87
+ function mapCSIDocumentToStoreDocument({
88
+ csiDocument,
89
+ model,
90
+ modelMap,
91
+ defaultLocaleCode,
92
+ extra
93
+ }: {
94
+ csiDocument: CSITypes.Document;
95
+ model: Model;
96
+ modelMap: Record<string, Model>;
97
+ defaultLocaleCode?: string;
98
+ extra: { srcType: string; srcProjectId: string; srcProjectUrl: string; srcEnvironment: string };
99
+ }): ContentStoreTypes.Document {
100
+ return {
101
+ type: 'document',
102
+ ...extra,
103
+ srcObjectId: csiDocument.id,
104
+ srcObjectUrl: csiDocument.manageUrl,
105
+ srcObjectLabel: getObjectLabel(csiDocument.fields, model, defaultLocaleCode),
106
+ srcModelLabel: model.label ?? _.startCase(csiDocument.modelName),
107
+ srcModelName: csiDocument.modelName,
108
+ isChanged: csiDocument.status === 'added' || csiDocument.status === 'modified',
109
+ status: csiDocument.status,
110
+ createdAt: csiDocument.createdAt,
111
+ createdBy: csiDocument.createdBy,
112
+ updatedAt: csiDocument.updatedAt,
113
+ updatedBy: csiDocument.updatedBy,
114
+ fields: mapCSIFieldsToStoreFields({
115
+ csiDocumentFields: csiDocument.fields,
116
+ modelFields: model.fields ?? [],
117
+ context: {
118
+ modelMap,
119
+ defaultLocaleCode
120
+ }
121
+ })
122
+ };
123
+ }
124
+
125
+ type MapContext = {
126
+ modelMap: Record<string, Model>;
127
+ defaultLocaleCode?: string;
128
+ };
129
+
130
+ function mapCSIFieldsToStoreFields({
131
+ csiDocumentFields,
132
+ modelFields,
133
+ context
134
+ }: {
135
+ csiDocumentFields: Record<string, CSITypes.DocumentField>;
136
+ modelFields: Field[];
137
+ context: MapContext;
138
+ }): Record<string, ContentStoreTypes.DocumentField> {
139
+ return modelFields.reduce((result: Record<string, ContentStoreTypes.DocumentField>, modelField) => {
140
+ const csiDocumentField = csiDocumentFields[modelField.name];
141
+ const docField = mapCSIFieldToStoreField({
142
+ csiDocumentField,
143
+ modelField,
144
+ context
145
+ });
146
+ docField.label = modelField.label;
147
+ result[modelField.name] = docField;
148
+ return result;
149
+ }, {});
150
+ }
151
+
152
+ function mapCSIFieldToStoreField({
153
+ csiDocumentField,
154
+ modelField,
155
+ context
156
+ }: {
157
+ csiDocumentField: CSITypes.DocumentField | undefined;
158
+ modelField: FieldSpecificProps;
159
+ context: MapContext;
160
+ }): ContentStoreTypes.DocumentField {
161
+ if (!csiDocumentField) {
162
+ const isUnset = ['object', 'model', 'reference', 'richText', 'markdown', 'image', 'file', 'json'].includes(modelField.type);
163
+ return {
164
+ type: modelField.type,
165
+ ...(isUnset ? { isUnset } : null),
166
+ ...(modelField.type === 'list' ? { items: [] } : null)
167
+ } as ContentStoreTypes.DocumentField;
168
+ }
169
+ // TODO: check if need to add "options" to "enum" and subtype/min/max to "number"
170
+ switch (modelField.type) {
171
+ case 'object':
172
+ return mapObjectField(csiDocumentField as CSITypes.DocumentObjectField, modelField, context);
173
+ case 'model':
174
+ return mapModelField(csiDocumentField as CSITypes.DocumentModelField, modelField, context);
175
+ case 'list':
176
+ return mapListField(csiDocumentField as CSITypes.DocumentListField, modelField, context);
177
+ case 'richText':
178
+ return mapRichTextField(csiDocumentField as CSITypes.DocumentRichTextField);
179
+ case 'markdown':
180
+ return mapMarkdownField(csiDocumentField as CSITypes.DocumentValueField);
181
+ default:
182
+ return csiDocumentField as ContentStoreTypes.DocumentField;
183
+ }
184
+ }
185
+
186
+ function mapObjectField(
187
+ csiDocumentField: CSITypes.DocumentObjectField,
188
+ modelField: FieldObjectProps,
189
+ context: MapContext
190
+ ): ContentStoreTypes.DocumentObjectField {
191
+ if (!isLocalizedField(csiDocumentField)) {
192
+ return {
193
+ type: csiDocumentField.type,
194
+ srcObjectLabel: getObjectLabel(csiDocumentField.fields ?? {}, modelField ?? [], context.defaultLocaleCode),
195
+ fields: mapCSIFieldsToStoreFields({
196
+ csiDocumentFields: csiDocumentField.fields ?? {},
197
+ modelFields: modelField.fields ?? [],
198
+ context
199
+ })
200
+ };
201
+ }
202
+ return {
203
+ type: csiDocumentField.type,
204
+ localized: true,
205
+ locales: _.mapValues(csiDocumentField.locales, (locale) => {
206
+ return {
207
+ locale: locale.locale,
208
+ srcObjectLabel: getObjectLabel(locale.fields ?? {}, modelField, locale.locale),
209
+ fields: mapCSIFieldsToStoreFields({
210
+ csiDocumentFields: locale.fields ?? {},
211
+ modelFields: modelField.fields ?? [],
212
+ context
213
+ })
214
+ };
215
+ })
216
+ };
217
+ }
218
+
219
+ function mapModelField(csiDocumentField: CSITypes.DocumentModelField, modelField: FieldModelProps, context: MapContext): ContentStoreTypes.DocumentModelField {
220
+ if (!isLocalizedField(csiDocumentField)) {
221
+ const model = context.modelMap[csiDocumentField.modelName]!;
222
+ return {
223
+ type: csiDocumentField.type,
224
+ srcObjectLabel: getObjectLabel(csiDocumentField.fields ?? {}, model, context.defaultLocaleCode),
225
+ srcModelName: csiDocumentField.modelName,
226
+ srcModelLabel: model.label ?? _.startCase(model.name),
227
+ fields: mapCSIFieldsToStoreFields({
228
+ csiDocumentFields: csiDocumentField.fields ?? {},
229
+ modelFields: model.fields ?? [],
230
+ context
231
+ })
232
+ };
233
+ }
234
+ return {
235
+ type: csiDocumentField.type,
236
+ localized: true,
237
+ locales: _.mapValues(csiDocumentField.locales, (locale) => {
238
+ const model = context.modelMap[locale.modelName]!;
239
+ return {
240
+ locale: locale.locale,
241
+ srcObjectLabel: getObjectLabel(locale.fields ?? {}, model, locale.locale),
242
+ srcModelName: locale.modelName,
243
+ srcModelLabel: model.label ?? _.startCase(model.name),
244
+ fields: mapCSIFieldsToStoreFields({
245
+ csiDocumentFields: locale.fields ?? {},
246
+ modelFields: model.fields ?? [],
247
+ context
248
+ })
249
+ };
250
+ })
251
+ };
252
+ }
253
+
254
+ function mapListField(csiDocumentField: CSITypes.DocumentListField, modelField: FieldListProps, context: MapContext): ContentStoreTypes.DocumentListField {
255
+ if (!isLocalizedField(csiDocumentField)) {
256
+ return {
257
+ type: csiDocumentField.type,
258
+ items: csiDocumentField.items.map((item) =>
259
+ mapCSIFieldToStoreField({
260
+ csiDocumentField: item,
261
+ modelField: modelField.items ?? { type: 'string' },
262
+ context
263
+ })
264
+ )
265
+ };
266
+ }
267
+ return {
268
+ type: csiDocumentField.type,
269
+ localized: true,
270
+ locales: _.mapValues(csiDocumentField.locales, (locale) => {
271
+ return {
272
+ locale: locale.locale,
273
+ items: (locale.items ?? []).map((item) =>
274
+ mapCSIFieldToStoreField({
275
+ csiDocumentField: item,
276
+ modelField: modelField.items ?? { type: 'string' },
277
+ context
278
+ })
279
+ )
280
+ };
281
+ })
282
+ };
283
+ }
284
+
285
+ function mapRichTextField(csiDocumentField: CSITypes.DocumentRichTextField): ContentStoreTypes.DocumentRichTextField {
286
+ if (!isLocalizedField(csiDocumentField)) {
287
+ return {
288
+ ...csiDocumentField,
289
+ multiElement: true
290
+ };
291
+ }
292
+ return {
293
+ type: csiDocumentField.type,
294
+ localized: true,
295
+ locales: _.mapValues(csiDocumentField.locales, (locale) => {
296
+ return {
297
+ ...locale,
298
+ multiElement: true
299
+ };
300
+ })
301
+ };
302
+ }
303
+
304
+ function mapMarkdownField(csiDocumentField: CSITypes.DocumentValueField): ContentStoreTypes.DocumentMarkdownField {
305
+ if (!isLocalizedField(csiDocumentField)) {
306
+ return {
307
+ type: 'markdown',
308
+ value: csiDocumentField.value,
309
+ multiElement: true
310
+ };
311
+ }
312
+ return {
313
+ type: 'markdown',
314
+ localized: true,
315
+ locales: _.mapValues(csiDocumentField.locales, (locale) => {
316
+ return {
317
+ ...locale,
318
+ multiElement: true
319
+ };
320
+ })
321
+ };
322
+ }
323
+
324
+ function getMetadataFromContentStore({
325
+ contentSourceInstance
326
+ }: {
327
+ contentSourceInstance: CSITypes.ContentSourceInterface;
328
+ }): {
329
+ srcType: string;
330
+ srcProjectId: string;
331
+ srcProjectUrl: string;
332
+ srcEnvironment: string;
333
+ } {
334
+ return {
335
+ srcType: contentSourceInstance.getContentSourceType(),
336
+ srcProjectId: contentSourceInstance.getProjectId(),
337
+ srcProjectUrl: contentSourceInstance.getProjectManageUrl(),
338
+ srcEnvironment: contentSourceInstance.getProjectEnvironment()
339
+ };
340
+ }
341
+
342
+ function getObjectLabel(
343
+ documentFields: Record<string, CSITypes.DocumentField | CSITypes.AssetFileField>,
344
+ modelOrObjectField: Model | FieldObjectProps,
345
+ locale?: string
346
+ ): string {
347
+ const labelField = modelOrObjectField.labelField;
348
+ let label = null;
349
+ if (labelField) {
350
+ const field = _.get(documentFields, labelField, null);
351
+ if (field && ['string', 'url', 'slug', 'text', 'markdown', 'number', 'enum', 'date', 'datetime', 'color', 'image', 'file'].includes(field.type)) {
352
+ if (isLocalizedField(field) && locale) {
353
+ label = _.get(field, ['locales', locale, 'value'], null);
354
+ } else if (!isLocalizedField(field)) {
355
+ label = _.get(field, 'value', null);
356
+ }
357
+ }
358
+ }
359
+ if (!label) {
360
+ label = _.get(modelOrObjectField, 'label');
361
+ }
362
+ if (!label && _.has(modelOrObjectField, 'name')) {
363
+ label = _.startCase(_.get(modelOrObjectField, 'name'));
364
+ }
365
+ return label;
366
+ }