@stackbit/cms-core 1.0.10-develop.1 → 1.0.10-develop.2

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 (69) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/consts.d.ts +1 -0
  3. package/dist/consts.d.ts.map +1 -1
  4. package/dist/consts.js +2 -1
  5. package/dist/consts.js.map +1 -1
  6. package/dist/content-store.d.ts +25 -12
  7. package/dist/content-store.d.ts.map +1 -1
  8. package/dist/content-store.js +259 -40
  9. package/dist/content-store.js.map +1 -1
  10. package/dist/types/content-store-documents.d.ts +2 -0
  11. package/dist/types/content-store-documents.d.ts.map +1 -1
  12. package/dist/types/content-store-types.d.ts +2 -1
  13. package/dist/types/content-store-types.d.ts.map +1 -1
  14. package/dist/types/search-filter.d.ts +6 -3
  15. package/dist/types/search-filter.d.ts.map +1 -1
  16. package/dist/utils/csi-to-api-docs-converter.d.ts +2 -1
  17. package/dist/utils/csi-to-api-docs-converter.d.ts.map +1 -1
  18. package/dist/utils/csi-to-api-docs-converter.js +2 -2
  19. package/dist/utils/csi-to-api-docs-converter.js.map +1 -1
  20. package/dist/utils/csi-to-store-docs-converter.d.ts.map +1 -1
  21. package/dist/utils/csi-to-store-docs-converter.js +3 -1
  22. package/dist/utils/csi-to-store-docs-converter.js.map +1 -1
  23. package/dist/utils/document-utils.d.ts +5 -0
  24. package/dist/utils/document-utils.d.ts.map +1 -0
  25. package/dist/utils/document-utils.js +46 -0
  26. package/dist/utils/document-utils.js.map +1 -0
  27. package/dist/utils/filtered-entities.d.ts +34 -0
  28. package/dist/utils/filtered-entities.d.ts.map +1 -0
  29. package/dist/utils/filtered-entities.js +177 -0
  30. package/dist/utils/filtered-entities.js.map +1 -0
  31. package/dist/utils/model-utils.d.ts +3 -0
  32. package/dist/utils/model-utils.d.ts.map +1 -1
  33. package/dist/utils/model-utils.js +8 -1
  34. package/dist/utils/model-utils.js.map +1 -1
  35. package/dist/utils/remove-hidden.d.ts +29 -0
  36. package/dist/utils/remove-hidden.d.ts.map +1 -0
  37. package/dist/utils/remove-hidden.js +199 -0
  38. package/dist/utils/remove-hidden.js.map +1 -0
  39. package/dist/utils/search-utils.d.ts.map +1 -1
  40. package/dist/utils/search-utils.js +72 -20
  41. package/dist/utils/search-utils.js.map +1 -1
  42. package/dist/utils/site-map.d.ts.map +1 -1
  43. package/dist/utils/site-map.js.map +1 -1
  44. package/dist/utils/store-to-csi-docs-converter.d.ts.map +1 -1
  45. package/dist/utils/store-to-csi-docs-converter.js +1 -0
  46. package/dist/utils/store-to-csi-docs-converter.js.map +1 -1
  47. package/dist/utils/tree-views.d.ts +8 -0
  48. package/dist/utils/tree-views.d.ts.map +1 -1
  49. package/dist/utils/tree-views.js +32 -1
  50. package/dist/utils/tree-views.js.map +1 -1
  51. package/package.json +5 -5
  52. package/src/consts.ts +2 -0
  53. package/src/content-store.ts +278 -39
  54. package/src/types/content-store-documents.ts +2 -0
  55. package/src/types/content-store-types.ts +3 -1
  56. package/src/types/search-filter.ts +7 -3
  57. package/src/utils/csi-to-api-docs-converter.ts +4 -2
  58. package/src/utils/csi-to-store-docs-converter.ts +3 -2
  59. package/src/utils/document-utils.ts +39 -0
  60. package/src/utils/filtered-entities.ts +247 -0
  61. package/src/utils/model-utils.ts +7 -0
  62. package/src/utils/search-utils.ts +94 -21
  63. package/src/utils/site-map.ts +0 -1
  64. package/src/utils/store-to-csi-docs-converter.ts +1 -0
  65. package/src/utils/tree-views.ts +43 -0
  66. package/dist/utils/custom-search-filters.d.ts +0 -12
  67. package/dist/utils/custom-search-filters.d.ts.map +0 -1
  68. package/dist/utils/custom-search-filters.js +0 -46
  69. package/dist/utils/custom-search-filters.js.map +0 -1
@@ -52,6 +52,7 @@ function sourceAssetToStoreAsset({
52
52
  updatedAt: csiAsset.updatedAt,
53
53
  updatedBy: csiAsset.updatedBy,
54
54
  locale: csiAsset.locale,
55
+ hidden: csiAsset.hidden,
55
56
  fields: {
56
57
  title: {
57
58
  label: 'Title',
@@ -166,6 +167,7 @@ function mapCSIDocumentToStoreDocument({
166
167
  createdBy: csiDocument.createdBy,
167
168
  updatedAt: csiDocument.updatedAt,
168
169
  updatedBy: csiDocument.updatedBy,
170
+ hidden: typeof csiDocument.hidden === 'boolean' ? csiDocument.hidden : model.hidden,
169
171
  locale: getDocumentLocale({ csiDocument, model }),
170
172
  fields: mapCSIFieldsToStoreFields({
171
173
  csiDocumentFields: csiDocument.fields,
@@ -825,8 +827,7 @@ function getObjectTitleFromLabelField({
825
827
  document,
826
828
  documentField,
827
829
  modelOrObjectField,
828
- delegate,
829
- locale
830
+ delegate
830
831
  }: {
831
832
  document: StackbitTypes.DocumentWithSource;
832
833
  documentField?: StackbitTypes.DocumentModelField | StackbitTypes.DocumentObjectField;
@@ -0,0 +1,39 @@
1
+ import * as StackbitTypes from '@stackbit/types';
2
+
3
+ const getModelsFromFields = (fields: StackbitTypes.DocumentField[], foundModels: Set<string>) => {
4
+ fields.forEach((field) => {
5
+ if (field.type === 'model') {
6
+ if (field.localized) {
7
+ for (const localeObject of Object.values(field.locales)) {
8
+ foundModels.add(localeObject.modelName);
9
+ getModelsFromFields(Object.values(localeObject.fields), foundModels);
10
+ }
11
+ } else {
12
+ foundModels.add(field.modelName);
13
+ getModelsFromFields(Object.values(field.fields), foundModels);
14
+ }
15
+ } else if (field.type === 'object') {
16
+ if (field.localized) {
17
+ for (const localeObject of Object.values(field.locales)) {
18
+ getModelsFromFields(Object.values(localeObject.fields), foundModels);
19
+ }
20
+ } else {
21
+ getModelsFromFields(Object.values(field.fields), foundModels);
22
+ }
23
+ } else if (field.type === 'list') {
24
+ if (field.localized) {
25
+ for (const localeObject of Object.values(field.locales)) {
26
+ getModelsFromFields(localeObject.items, foundModels);
27
+ }
28
+ } else {
29
+ getModelsFromFields(field.items, foundModels);
30
+ }
31
+ }
32
+ });
33
+ };
34
+
35
+ export function getAllModelsFromCSIDocument({ document }: { document: StackbitTypes.Document }): string[] {
36
+ const models = new Set<string>([document.modelName]);
37
+ getModelsFromFields(Object.values(document.fields), models);
38
+ return Array.from(models);
39
+ }
@@ -0,0 +1,247 @@
1
+ import * as CSITypes from '@stackbit/types';
2
+ import _ from 'lodash';
3
+ import { ContentStoreTypes } from '../';
4
+ import { STACKBIT_PRESET_MODEL_NAME } from '../consts';
5
+ import { getContentSourceDataByIdOrThrow, getContentSourceId } from '../content-store-utils';
6
+ import { mapCSIAssetsToStoreAssets, mapCSIDocumentsToStoreDocuments } from './csi-to-store-docs-converter';
7
+ import { getAllModelsFromCSIDocument } from './document-utils';
8
+
9
+ export const getFilteredDocumentsForUser = ({
10
+ user,
11
+ documents,
12
+ filterModel,
13
+ filterDocument,
14
+ contentSourceDataById,
15
+ assetSources,
16
+ createConfigDelegate,
17
+ customActionRunStateMap,
18
+ logger
19
+ }: {
20
+ user?: ContentStoreTypes.User;
21
+ filterModel: CSITypes.StackbitConfig['filterModel'];
22
+ filterDocument: CSITypes.StackbitConfig['filterDocument'];
23
+ documents: ContentStoreTypes.Document[];
24
+ contentSourceDataById: Record<string, ContentStoreTypes.ContentSourceData>;
25
+ assetSources: CSITypes.AssetSource[];
26
+ createConfigDelegate: () => CSITypes.ConfigDelegate;
27
+ customActionRunStateMap: ContentStoreTypes.CustomActionRunStateMap;
28
+ logger: CSITypes.Logger;
29
+ }): ContentStoreTypes.Document[] => {
30
+ if (!user || (!filterDocument && !filterModel)) {
31
+ return documents;
32
+ }
33
+
34
+ const documentsBySourceId = _.groupBy(documents, (object) => getContentSourceId(object.srcType, object.srcProjectId));
35
+
36
+ const transformedCsiDocuments: CSITypes.DocumentWithSource[] = [];
37
+
38
+ const resultDocuments: ContentStoreTypes.Document[] = [];
39
+
40
+ const configDelegate = createConfigDelegate();
41
+
42
+ for (const [contentSourceId, contentSourceDocuments] of Object.entries(documentsBySourceId)) {
43
+ const contentSourceData = getContentSourceDataByIdOrThrow(contentSourceId, contentSourceDataById);
44
+ const filteredModelsMap: Record<string, CSITypes.Model> = {};
45
+
46
+ contentSourceDocuments.forEach((document) => {
47
+ const csiDoc = contentSourceData.csiDocumentMap[document.srcObjectId];
48
+ if (!csiDoc) {
49
+ throw new Error(`Document with id '${document.srcObjectId}' not found in content source '${contentSourceId}'`);
50
+ }
51
+
52
+ getAllModelsFromCSIDocument({ document: csiDoc }).forEach((modelName) => {
53
+ if (!filteredModelsMap[modelName]) {
54
+ const filteredModel = getFilteredModelForUser({
55
+ user,
56
+ name: modelName,
57
+ contentSourceData,
58
+ configDelegate,
59
+ filterModel
60
+ });
61
+ filteredModelsMap[modelName] = filteredModel;
62
+ }
63
+ });
64
+ const documentModel = filteredModelsMap[document.srcModelName];
65
+ if (!documentModel) {
66
+ throw new Error(
67
+ `Can't find model with name '${document.srcModelName}' for object with id '${document.srcObjectId}' in content source '${contentSourceId}'`
68
+ );
69
+ }
70
+ if (documentModel.hidden) {
71
+ // model is hidden - return csiDocument right away as hidden
72
+ resultDocuments.push({
73
+ ...document,
74
+ hidden: true
75
+ });
76
+ return;
77
+ }
78
+
79
+ if (!filterDocument) {
80
+ // no filter function is defined, but the model is not hidden - just add this document as is
81
+ resultDocuments.push(document);
82
+ return;
83
+ }
84
+
85
+ const csiDocWithSource: CSITypes.DocumentWithSource = {
86
+ ..._.cloneDeep(csiDoc),
87
+ srcType: contentSourceData.srcType,
88
+ srcProjectId: contentSourceData.srcProjectId
89
+ };
90
+ const shouldIncludeDoc = filterDocument({
91
+ ...configDelegate,
92
+ document: csiDocWithSource,
93
+ userContext: user
94
+ });
95
+ if (typeof shouldIncludeDoc === 'undefined') {
96
+ transformedCsiDocuments.push(csiDocWithSource);
97
+ } else {
98
+ transformedCsiDocuments.push({
99
+ ...csiDocWithSource,
100
+ hidden: !shouldIncludeDoc
101
+ });
102
+ }
103
+ });
104
+
105
+ if (transformedCsiDocuments.length) {
106
+ const csResultDocuments = mapCSIDocumentsToStoreDocuments({
107
+ csiDocuments: transformedCsiDocuments,
108
+ contentSourceInstance: contentSourceData.instance,
109
+ modelMap: filteredModelsMap,
110
+ defaultLocaleCode: contentSourceData.defaultLocaleCode,
111
+ assetSources,
112
+ customActionRunStateMap,
113
+ createConfigDelegate,
114
+ logger
115
+ });
116
+
117
+ resultDocuments.push(...(csResultDocuments ?? []));
118
+ }
119
+ }
120
+
121
+ return resultDocuments;
122
+ };
123
+
124
+ export const getFilteredAssetsForUser = ({
125
+ user,
126
+ assets,
127
+ filterAsset,
128
+ configDelegate,
129
+ contentSourceDataById
130
+ }: {
131
+ user?: ContentStoreTypes.User;
132
+ assets: ContentStoreTypes.Asset[];
133
+ filterAsset: CSITypes.StackbitConfig['filterAsset'];
134
+ configDelegate: CSITypes.ConfigDelegate;
135
+ contentSourceDataById: Record<string, ContentStoreTypes.ContentSourceData>;
136
+ }): ContentStoreTypes.Asset[] => {
137
+ if (!user || !filterAsset) {
138
+ return assets;
139
+ }
140
+
141
+ const assetsBySourceId = _.groupBy(assets, (object) => getContentSourceId(object.srcType, object.srcProjectId));
142
+
143
+ const transformedCsiAssets: CSITypes.AssetWithSource[] = [];
144
+
145
+ const resultAssets: ContentStoreTypes.Asset[] = [];
146
+
147
+ for (const [contentSourceId, contentSourceAssets] of Object.entries(assetsBySourceId)) {
148
+ const contentSourceData = getContentSourceDataByIdOrThrow(contentSourceId, contentSourceDataById);
149
+
150
+ contentSourceAssets.forEach((asset) => {
151
+ const csiAsset = contentSourceData.csiAssetMap[asset.srcObjectId];
152
+ if (!csiAsset) {
153
+ throw new Error(`Asset with id '${asset.srcObjectId}' not found in content source '${contentSourceId}'`);
154
+ }
155
+
156
+ const csiAssetWithSource: CSITypes.AssetWithSource = {
157
+ ..._.cloneDeep(csiAsset),
158
+ srcType: contentSourceData.srcType,
159
+ srcProjectId: contentSourceData.srcProjectId
160
+ };
161
+ const shouldIncludeAsset = filterAsset({
162
+ ...configDelegate,
163
+ asset: csiAssetWithSource,
164
+ userContext: user
165
+ });
166
+ if (typeof shouldIncludeAsset === 'undefined') {
167
+ transformedCsiAssets.push(csiAssetWithSource);
168
+ } else {
169
+ transformedCsiAssets.push({
170
+ ...csiAssetWithSource,
171
+ hidden: !shouldIncludeAsset
172
+ });
173
+ }
174
+ });
175
+
176
+ if (transformedCsiAssets.length) {
177
+ const csResultAssets = mapCSIAssetsToStoreAssets({
178
+ csiAssets: transformedCsiAssets,
179
+ contentSourceInstance: contentSourceData.instance,
180
+ defaultLocaleCode: contentSourceData.defaultLocaleCode
181
+ });
182
+
183
+ resultAssets.push(...csResultAssets);
184
+ }
185
+ }
186
+
187
+ return resultAssets;
188
+ };
189
+
190
+ export const getContentSourceFilteredModelsForUser = ({
191
+ user,
192
+ configDelegate,
193
+ contentSourceData,
194
+ filterModel
195
+ }: {
196
+ user?: ContentStoreTypes.User;
197
+ configDelegate: CSITypes.ConfigDelegate;
198
+ contentSourceData: ContentStoreTypes.ContentSourceData;
199
+ filterModel: CSITypes.StackbitConfig['filterModel'];
200
+ }): CSITypes.Model[] => {
201
+ const filteredModels = contentSourceData.models.map((model) => {
202
+ return getFilteredModelForUser({
203
+ user,
204
+ configDelegate,
205
+ name: model.name,
206
+ contentSourceData,
207
+ filterModel
208
+ });
209
+ });
210
+ const cleanModels = filteredModels.filter((model) => model.name !== STACKBIT_PRESET_MODEL_NAME);
211
+ return cleanModels;
212
+ };
213
+
214
+ export const getFilteredModelForUser = ({
215
+ user,
216
+ name,
217
+ configDelegate,
218
+ contentSourceData,
219
+ filterModel
220
+ }: {
221
+ user?: ContentStoreTypes.User;
222
+ name: string;
223
+ configDelegate: CSITypes.ConfigDelegate;
224
+ contentSourceData: ContentStoreTypes.ContentSourceData;
225
+ filterModel: CSITypes.StackbitConfig['filterModel'];
226
+ }): CSITypes.Model => {
227
+ const model = contentSourceData.modelMap[name];
228
+ if (!model) {
229
+ throw new Error(`Model with name ${name} not found in source`);
230
+ }
231
+ if (!user || !filterModel) {
232
+ return model;
233
+ }
234
+ const modelWithSource = {
235
+ ..._.cloneDeep(model),
236
+ srcType: contentSourceData.srcType,
237
+ srcProjectId: contentSourceData.srcProjectId
238
+ };
239
+ const shouldIncludeModel = filterModel({ ...configDelegate, model: modelWithSource, userContext: user });
240
+ if (typeof shouldIncludeModel === 'undefined') {
241
+ return model;
242
+ }
243
+ return {
244
+ ...model,
245
+ hidden: !shouldIncludeModel
246
+ };
247
+ };
@@ -176,3 +176,10 @@ export function validateModels<T extends Model>({ models, logger }: { models: T[
176
176
 
177
177
  return config.models as T[];
178
178
  }
179
+
180
+ export function getModelMap<T extends Model>({ models }: { models: T[] }): Record<string, T> {
181
+ return models.reduce((res, model) => {
182
+ res[model.name] = model;
183
+ return res;
184
+ }, {} as Record<string, T>);
185
+ }
@@ -4,7 +4,7 @@ import { ScheduledAction } from '@stackbit/types';
4
4
  import { append } from '@stackbit/utils';
5
5
 
6
6
  import * as ContentStoreTypes from '../types';
7
- import { ReferenceValueType, SearchFilter, SearchFilterItem } from '../types';
7
+ import { ReferenceValueType, SearchFilter, SearchFilterItem, SearchFilterItemGrouped } from '../types';
8
8
  import { getContentSourceId, getDocumentFieldForLocale } from '../content-store-utils';
9
9
  import { META_FIELDS, MetaFieldMethod } from './meta-fields-filters';
10
10
 
@@ -55,25 +55,13 @@ export const searchDocuments = (data: {
55
55
  }
56
56
  }
57
57
 
58
- if (data.filter?.and) {
59
- // only 'and' supported for now; later we can add e.g. 'or'
60
- const matches = data.filter.and.every((filter) => {
61
- const filterFieldResult = getFieldForFilter({
62
- document,
63
- filter,
64
- context: {
65
- activeScheduledActionsByDocumentId,
66
- locale: data.locale ?? data.defaultLocales?.[contentSourceId],
67
- schema
68
- }
69
- });
70
-
71
- if ('result' in filterFieldResult) {
72
- return filterFieldResult.result;
73
- }
74
-
75
- const { field, model } = filterFieldResult;
76
- return isFieldMatchesFilter({ field, filter, document, model, locale: data.locale ?? data.defaultLocales?.[contentSourceId] });
58
+ if (data.filter) {
59
+ const matches = isFilterMatches({
60
+ filter: data.filter,
61
+ document,
62
+ locale: data.locale ?? data.defaultLocales?.[contentSourceId],
63
+ schema,
64
+ activeScheduledActionsByDocumentId
77
65
  });
78
66
 
79
67
  if (!matches) {
@@ -95,8 +83,13 @@ const isDocumentMatchesPattern = (document: ContentStoreTypes.Document, query: s
95
83
  return true;
96
84
  }
97
85
 
98
- return _.some(document.fields, (field) => {
86
+ return areFieldsMatchingPattern(Object.values(document.fields), query, locale);
87
+ };
88
+
89
+ const areFieldsMatchingPattern = (fields: ContentStoreTypes.DocumentField[], query: string, locale?: string): boolean => {
90
+ return fields.some((field) => {
99
91
  let value;
92
+
100
93
  switch (field.type) {
101
94
  case 'string':
102
95
  case 'slug':
@@ -106,6 +99,27 @@ const isDocumentMatchesPattern = (document: ContentStoreTypes.Document, query: s
106
99
  case 'html':
107
100
  value = getDocumentFieldForLocale(field, locale)?.value;
108
101
  break;
102
+
103
+ case 'list': {
104
+ const list = getDocumentFieldForLocale(field, locale);
105
+ const result = list ? areFieldsMatchingPattern(list.items, query, locale) : false;
106
+ if (result) {
107
+ return result;
108
+ }
109
+ break;
110
+ }
111
+
112
+ case 'model':
113
+ case 'object': {
114
+ const object = getDocumentFieldForLocale(field, locale);
115
+ if (object && !object.isUnset) {
116
+ const result = areFieldsMatchingPattern(Object.values(object.fields), query, locale);
117
+ if (result) {
118
+ return result;
119
+ }
120
+ }
121
+ break;
122
+ }
109
123
  }
110
124
 
111
125
  if (value) {
@@ -116,6 +130,65 @@ const isDocumentMatchesPattern = (document: ContentStoreTypes.Document, query: s
116
130
  });
117
131
  };
118
132
 
133
+ const isFilterMatches = ({
134
+ filter,
135
+ document,
136
+ locale,
137
+ schema,
138
+ activeScheduledActionsByDocumentId
139
+ }: {
140
+ filter: SearchFilterItemGrouped;
141
+ document: ContentStoreTypes.Document;
142
+ locale?: string;
143
+ schema: SearchSchema;
144
+ activeScheduledActionsByDocumentId: Record<string, ScheduledAction[]>;
145
+ }): boolean => {
146
+ if (_.intersection(Object.keys(filter), ['and', 'or', 'field']).length > 1) {
147
+ throw new Error(`Unsupported filter - 'and', 'or' and 'field' are mutually exclusive.`);
148
+ }
149
+
150
+ if ('field' in filter) {
151
+ const filterFieldResult = getFieldForFilter({
152
+ document,
153
+ filter,
154
+ context: {
155
+ activeScheduledActionsByDocumentId,
156
+ locale,
157
+ schema
158
+ }
159
+ });
160
+
161
+ if ('result' in filterFieldResult) {
162
+ return filterFieldResult.result;
163
+ }
164
+
165
+ const { field, model } = filterFieldResult;
166
+ return isFieldMatchesFilter({ field, filter, document, model, locale });
167
+ } else {
168
+ if (!('and' in filter) && !('or' in filter)) {
169
+ throw new Error(`Unsupported filter - neither 'and' nor 'or' provided`);
170
+ }
171
+
172
+ const comparisonMethod = 'and' in filter ? 'every' : 'some';
173
+ const root = 'and' in filter ? filter.and : filter.or;
174
+
175
+ if (!root.length) {
176
+ // for empty search groups - match
177
+ return true;
178
+ }
179
+
180
+ return root[comparisonMethod]((childFilter) => {
181
+ return isFilterMatches({
182
+ filter: childFilter,
183
+ document,
184
+ locale,
185
+ schema,
186
+ activeScheduledActionsByDocumentId
187
+ });
188
+ });
189
+ }
190
+ };
191
+
119
192
  const getFieldForFilter: MetaFieldMethod = ({ document, filter, context }) => {
120
193
  if (filter.isMeta) {
121
194
  const filterField = filter.field;
@@ -6,7 +6,6 @@ import * as CSITypes from '@stackbit/types';
6
6
  import * as ContentStoreTypes from '../types';
7
7
  import { mapStoreDocumentsToCSIDocumentsWithSource } from './store-to-csi-docs-converter';
8
8
  import { getContentSourceId, getDocumentFieldForLocale } from '../content-store-utils';
9
- import { createConfigDelegate } from './config-delegate';
10
9
 
11
10
  export const SiteMapStaticEntriesKey = Symbol.for('SiteMapStaticEntriesKey');
12
11
  export type SiteMapEntriesSourceKeys = string | symbol;
@@ -52,6 +52,7 @@ export function mapStoreDocumentToCSIDocumentWithSource({
52
52
  updatedBy: document.updatedBy,
53
53
  locale: document.locale,
54
54
  context: csiDocument.context,
55
+ hidden: document.hidden,
55
56
  fields: mapStoreFieldsToCSIFields(document.fields)
56
57
  };
57
58
  }
@@ -70,3 +70,46 @@ export async function getSanitizedTreeViews({
70
70
 
71
71
  return mapTreeViews(treeViews);
72
72
  }
73
+
74
+ export function removeHiddenTreeViews({
75
+ treeViews,
76
+ getDocumentForUser
77
+ }: {
78
+ treeViews: CSITypes.TreeViewNode[];
79
+ getDocumentForUser: (opts: { srcDocumentId: string; srcType: string; srcProjectId: string }) => ContentStoreTypes.Document | undefined;
80
+ }) {
81
+ const mapTreeViews = (treeViews: CSITypes.TreeViewNode[]): CSITypes.TreeViewNode[] => {
82
+ return treeViews.map((treeView) => {
83
+ let resultTreeView = treeView;
84
+
85
+ if ('document' in treeView && treeView.document) {
86
+ const document = getDocumentForUser({
87
+ srcDocumentId: treeView.document.id,
88
+ srcType: treeView.document.srcType,
89
+ srcProjectId: treeView.document.srcProjectId
90
+ });
91
+
92
+ if (!document) {
93
+ throw new Error(`Could not found a document with id ${treeView.document.id} when iterating tree views`);
94
+ }
95
+
96
+ if (document.hidden) {
97
+ resultTreeView = _.omit(treeView, ['document']) as CSITypes.TreeViewBaseNode;
98
+ }
99
+ }
100
+
101
+ if ('children' in treeView && treeView.children) {
102
+ if (treeView.stableId && treeView.label) {
103
+ resultTreeView = {
104
+ ...resultTreeView,
105
+ children: mapTreeViews(treeView.children)
106
+ };
107
+ }
108
+ }
109
+
110
+ return resultTreeView;
111
+ });
112
+ };
113
+
114
+ return mapTreeViews(treeViews);
115
+ }
@@ -1,12 +0,0 @@
1
- import * as ContentStoreTypes from '../types';
2
- import { SearchFilterItem } from '../types';
3
- import { ScheduledAction } from '@stackbit/types';
4
- import { SchemaForSearch } from './search-utils';
5
- declare type CustomFilterMethod = (filter: SearchFilterItem, document: ContentStoreTypes.Document, opts: {
6
- locale?: string;
7
- schema: SchemaForSearch;
8
- activeScheduledActionsByDocumentId: Record<string, ScheduledAction[]>;
9
- }) => boolean;
10
- export declare const CUSTOM_FILTERS: Record<string, CustomFilterMethod>;
11
- export {};
12
- //# sourceMappingURL=custom-search-filters.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"custom-search-filters.d.ts","sourceRoot":"","sources":["../../src/utils/custom-search-filters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,iBAAiB,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAqB,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAiE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEhH,aAAK,kBAAkB,GAAG,CACtB,MAAM,EAAE,gBAAgB,EACxB,QAAQ,EAAE,iBAAiB,CAAC,QAAQ,EACpC,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAC;IAAC,kCAAkC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;CAAE,KACxH,OAAO,CAAC;AAEb,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAwC7D,CAAC"}
@@ -1,46 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CUSTOM_FILTERS = void 0;
4
- const search_utils_1 = require("./search-utils");
5
- exports.CUSTOM_FILTERS = {
6
- hasSchedules: (filter, document, opts) => {
7
- var _a;
8
- const field = {
9
- type: 'boolean',
10
- value: !!((_a = opts.activeScheduledActionsByDocumentId[document.srcObjectId]) === null || _a === void 0 ? void 0 : _a.length)
11
- };
12
- return (0, search_utils_1.isBooleanFieldMatches)({ field, filter, locale: opts.locale });
13
- },
14
- scheduledActionId: (filter, document, opts) => {
15
- var _a, _b;
16
- const field = {
17
- type: 'list',
18
- items: (_b = (_a = opts.activeScheduledActionsByDocumentId[document.srcObjectId]) === null || _a === void 0 ? void 0 : _a.map((scheduledAction) => ({
19
- type: 'string',
20
- value: scheduledAction.id
21
- }))) !== null && _b !== void 0 ? _b : []
22
- };
23
- const model = {
24
- type: 'object',
25
- name: '',
26
- fields: [
27
- {
28
- name: '',
29
- type: 'list',
30
- items: {
31
- type: 'string'
32
- }
33
- }
34
- ]
35
- };
36
- return (0, search_utils_1.isListFieldMatches)({ field, filter, model, locale: opts.locale, document });
37
- },
38
- scheduledActionDate: (filter, document, opts) => {
39
- var _a, _b;
40
- return ((_b = (_a = opts.activeScheduledActionsByDocumentId[document.srcObjectId]) === null || _a === void 0 ? void 0 : _a.some((scheduledAction) => {
41
- const field = { type: 'date', value: scheduledAction.executeAt };
42
- return (0, search_utils_1.isDateFieldMatches)({ field, filter, locale: opts.locale });
43
- })) !== null && _b !== void 0 ? _b : false);
44
- }
45
- };
46
- //# sourceMappingURL=custom-search-filters.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"custom-search-filters.js","sourceRoot":"","sources":["../../src/utils/custom-search-filters.ts"],"names":[],"mappings":";;;AAIA,iDAAgH;AAQnG,QAAA,cAAc,GAAuC;IAC9D,YAAY,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;;QACrC,MAAM,KAAK,GAAG;YACV,IAAI,EAAE,SAAkB;YACxB,KAAK,EAAE,CAAC,CAAC,CAAA,MAAA,IAAI,CAAC,kCAAkC,CAAC,QAAQ,CAAC,WAAW,CAAC,0CAAE,MAAM,CAAA;SACjF,CAAC;QACF,OAAO,IAAA,oCAAqB,EAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,iBAAiB,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;;QAC1C,MAAM,KAAK,GAAsB;YAC7B,IAAI,EAAE,MAAM;YACZ,KAAK,EACD,MAAA,MAAA,IAAI,CAAC,kCAAkC,CAAC,QAAQ,CAAC,WAAW,CAAC,0CAAE,GAAG,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;gBACrF,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,eAAe,CAAC,EAAE;aAC5B,CAAC,CAAC,mCAAI,EAAE;SAChB,CAAC;QACF,MAAM,KAAK,GAAU;YACjB,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,EAAE;YACR,MAAM,EAAE;gBACJ;oBACI,IAAI,EAAE,EAAE;oBACR,IAAI,EAAE,MAAM;oBACZ,KAAK,EAAE;wBACH,IAAI,EAAE,QAAQ;qBACjB;iBACJ;aACJ;SACJ,CAAC;QACF,OAAO,IAAA,iCAAkB,EAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;;QAC5C,OAAO,CACH,MAAA,MAAA,IAAI,CAAC,kCAAkC,CAAC,QAAQ,CAAC,WAAW,CAAC,0CAAE,IAAI,CAAC,CAAC,eAAe,EAAE,EAAE;YACpF,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,MAAe,EAAE,KAAK,EAAE,eAAe,CAAC,SAAS,EAAE,CAAC;YAC1E,OAAO,IAAA,iCAAkB,EAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,CAAC,CAAC,mCAAI,KAAK,CACd,CAAC;IACN,CAAC;CACJ,CAAC"}