@webiny/api-headless-cms-ddb-es 6.3.0-beta.4 → 6.4.0-beta.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 (207) hide show
  1. package/configurations.js +27 -35
  2. package/configurations.js.map +1 -1
  3. package/definitions/entry.js +7 -9
  4. package/definitions/entry.js.map +1 -1
  5. package/definitions/group.js +7 -9
  6. package/definitions/group.js.map +1 -1
  7. package/definitions/model.js +7 -9
  8. package/definitions/model.js.map +1 -1
  9. package/definitions/types.d.ts +1 -0
  10. package/definitions/types.js +0 -3
  11. package/elasticsearch/createElasticsearchIndex.js +50 -67
  12. package/elasticsearch/createElasticsearchIndex.js.map +1 -1
  13. package/elasticsearch/deleteElasticsearchIndex.js +18 -26
  14. package/elasticsearch/deleteElasticsearchIndex.js.map +1 -1
  15. package/exports/api/cms/opensearch.js +2 -4
  16. package/feature.js +144 -153
  17. package/feature.js.map +1 -1
  18. package/features/CmsEntryOpenSearchBodyModifier/abstractions.js +2 -1
  19. package/features/CmsEntryOpenSearchBodyModifier/abstractions.js.map +1 -1
  20. package/features/CmsEntryOpenSearchBodyModifier/index.js +0 -2
  21. package/features/CmsEntryOpenSearchFieldIndex/CmsEntryOpenSearchFieldIndexRegistry.js +28 -27
  22. package/features/CmsEntryOpenSearchFieldIndex/CmsEntryOpenSearchFieldIndexRegistry.js.map +1 -1
  23. package/features/CmsEntryOpenSearchFieldIndex/abstractions/CmsEntryOpenSearchFieldIndex.js +2 -1
  24. package/features/CmsEntryOpenSearchFieldIndex/abstractions/CmsEntryOpenSearchFieldIndex.js.map +1 -1
  25. package/features/CmsEntryOpenSearchFieldIndex/abstractions/CmsEntryOpenSearchFieldIndexRegistry.js +2 -1
  26. package/features/CmsEntryOpenSearchFieldIndex/abstractions/CmsEntryOpenSearchFieldIndexRegistry.js.map +1 -1
  27. package/features/CmsEntryOpenSearchFieldIndex/constants.js +2 -1
  28. package/features/CmsEntryOpenSearchFieldIndex/constants.js.map +1 -1
  29. package/features/CmsEntryOpenSearchFieldIndex/feature.js +13 -12
  30. package/features/CmsEntryOpenSearchFieldIndex/feature.js.map +1 -1
  31. package/features/CmsEntryOpenSearchFieldIndex/fields/DateTimeFieldIndex.js +48 -65
  32. package/features/CmsEntryOpenSearchFieldIndex/fields/DateTimeFieldIndex.js.map +1 -1
  33. package/features/CmsEntryOpenSearchFieldIndex/fields/DefaultFieldIndex.js +20 -30
  34. package/features/CmsEntryOpenSearchFieldIndex/fields/DefaultFieldIndex.js.map +1 -1
  35. package/features/CmsEntryOpenSearchFieldIndex/fields/JsonFieldIndex.js +15 -16
  36. package/features/CmsEntryOpenSearchFieldIndex/fields/JsonFieldIndex.js.map +1 -1
  37. package/features/CmsEntryOpenSearchFieldIndex/fields/LongTextFieldIndex.js +15 -18
  38. package/features/CmsEntryOpenSearchFieldIndex/fields/LongTextFieldIndex.js.map +1 -1
  39. package/features/CmsEntryOpenSearchFieldIndex/fields/NumberFieldIndex.js +24 -29
  40. package/features/CmsEntryOpenSearchFieldIndex/fields/NumberFieldIndex.js.map +1 -1
  41. package/features/CmsEntryOpenSearchFieldIndex/fields/ObjectFieldIndex.js +99 -144
  42. package/features/CmsEntryOpenSearchFieldIndex/fields/ObjectFieldIndex.js.map +1 -1
  43. package/features/CmsEntryOpenSearchFieldIndex/fields/RichTextFieldIndex.js +15 -16
  44. package/features/CmsEntryOpenSearchFieldIndex/fields/RichTextFieldIndex.js.map +1 -1
  45. package/features/CmsEntryOpenSearchFieldIndex/index.js +0 -2
  46. package/features/CmsEntryOpenSearchFilter/CmsEntryOpenSearchFilterRegistry.js +26 -28
  47. package/features/CmsEntryOpenSearchFilter/CmsEntryOpenSearchFilterRegistry.js.map +1 -1
  48. package/features/CmsEntryOpenSearchFilter/abstractions/CmsEntryOpenSearchFilter.js +2 -1
  49. package/features/CmsEntryOpenSearchFilter/abstractions/CmsEntryOpenSearchFilter.js.map +1 -1
  50. package/features/CmsEntryOpenSearchFilter/abstractions/CmsEntryOpenSearchFilterRegistry.js +2 -1
  51. package/features/CmsEntryOpenSearchFilter/abstractions/CmsEntryOpenSearchFilterRegistry.js.map +1 -1
  52. package/features/CmsEntryOpenSearchFilter/constants.js +2 -1
  53. package/features/CmsEntryOpenSearchFilter/constants.js.map +1 -1
  54. package/features/CmsEntryOpenSearchFilter/feature.js +9 -8
  55. package/features/CmsEntryOpenSearchFilter/feature.js.map +1 -1
  56. package/features/CmsEntryOpenSearchFilter/fields/DefaultFilter.js +18 -15
  57. package/features/CmsEntryOpenSearchFilter/fields/DefaultFilter.js.map +1 -1
  58. package/features/CmsEntryOpenSearchFilter/fields/ObjectFilter.js +35 -53
  59. package/features/CmsEntryOpenSearchFilter/fields/ObjectFilter.js.map +1 -1
  60. package/features/CmsEntryOpenSearchFilter/fields/RefFilter.js +27 -40
  61. package/features/CmsEntryOpenSearchFilter/fields/RefFilter.js.map +1 -1
  62. package/features/CmsEntryOpenSearchFilter/index.js +0 -2
  63. package/features/CmsEntryOpenSearchFullTextSearch/abstractions.js +2 -1
  64. package/features/CmsEntryOpenSearchFullTextSearch/abstractions.js.map +1 -1
  65. package/features/CmsEntryOpenSearchFullTextSearch/index.js +0 -2
  66. package/features/CmsEntryOpenSearchIndex/BaseOpenSearchIndex.js +10 -9
  67. package/features/CmsEntryOpenSearchIndex/BaseOpenSearchIndex.js.map +1 -1
  68. package/features/CmsEntryOpenSearchIndex/abstractions.js +2 -1
  69. package/features/CmsEntryOpenSearchIndex/abstractions.js.map +1 -1
  70. package/features/CmsEntryOpenSearchIndex/feature.js +6 -5
  71. package/features/CmsEntryOpenSearchIndex/feature.js.map +1 -1
  72. package/features/CmsEntryOpenSearchIndex/index.js +0 -2
  73. package/features/CmsEntryOpenSearchQueryModifier/abstractions.js +2 -1
  74. package/features/CmsEntryOpenSearchQueryModifier/abstractions.js.map +1 -1
  75. package/features/CmsEntryOpenSearchQueryModifier/index.js +0 -2
  76. package/features/CmsEntryOpenSearchSortModifier/abstractions.js +2 -1
  77. package/features/CmsEntryOpenSearchSortModifier/abstractions.js.map +1 -1
  78. package/features/CmsEntryOpenSearchSortModifier/index.js +0 -2
  79. package/features/CmsEntryOpenSearchValueSearch/CmsEntryOpenSearchValueSearchRegistry.js +24 -20
  80. package/features/CmsEntryOpenSearchValueSearch/CmsEntryOpenSearchValueSearchRegistry.js.map +1 -1
  81. package/features/CmsEntryOpenSearchValueSearch/abstractions/CmsEntryOpenSearchValueSearch.js +2 -1
  82. package/features/CmsEntryOpenSearchValueSearch/abstractions/CmsEntryOpenSearchValueSearch.js.map +1 -1
  83. package/features/CmsEntryOpenSearchValueSearch/abstractions/CmsEntryOpenSearchValueSearchRegistry.js +2 -1
  84. package/features/CmsEntryOpenSearchValueSearch/abstractions/CmsEntryOpenSearchValueSearchRegistry.js.map +1 -1
  85. package/features/CmsEntryOpenSearchValueSearch/feature.js +9 -8
  86. package/features/CmsEntryOpenSearchValueSearch/feature.js.map +1 -1
  87. package/features/CmsEntryOpenSearchValueSearch/fields/RefSearch.js +14 -16
  88. package/features/CmsEntryOpenSearchValueSearch/fields/RefSearch.js.map +1 -1
  89. package/features/CmsEntryOpenSearchValueSearch/fields/SearchableJsonSearch.js +31 -42
  90. package/features/CmsEntryOpenSearchValueSearch/fields/SearchableJsonSearch.js.map +1 -1
  91. package/features/CmsEntryOpenSearchValueSearch/fields/TimeSearch.js +15 -17
  92. package/features/CmsEntryOpenSearchValueSearch/fields/TimeSearch.js.map +1 -1
  93. package/features/CmsEntryOpenSearchValueSearch/index.js +0 -2
  94. package/features/CmsEntryOpenSearchValuesModifier/abstractions.js +2 -1
  95. package/features/CmsEntryOpenSearchValuesModifier/abstractions.js.map +1 -1
  96. package/features/CmsEntryOpenSearchValuesModifier/index.js +0 -2
  97. package/helpers/entryIndexHelpers.js +71 -123
  98. package/helpers/entryIndexHelpers.js.map +1 -1
  99. package/helpers/fieldIdentifier.js +18 -30
  100. package/helpers/fieldIdentifier.js.map +1 -1
  101. package/helpers/index.js +0 -2
  102. package/index.js +0 -2
  103. package/operations/entry/dataLoader/DataLoaderCache.js +22 -26
  104. package/operations/entry/dataLoader/DataLoaderCache.js.map +1 -1
  105. package/operations/entry/dataLoader/constants.js +2 -1
  106. package/operations/entry/dataLoader/constants.js.map +1 -1
  107. package/operations/entry/dataLoader/createBatchScheduleFn.js +6 -15
  108. package/operations/entry/dataLoader/createBatchScheduleFn.js.map +1 -1
  109. package/operations/entry/dataLoader/getAllEntryRevisions.js +18 -29
  110. package/operations/entry/dataLoader/getAllEntryRevisions.js.map +1 -1
  111. package/operations/entry/dataLoader/getLatestRevisionByEntryId.js +27 -37
  112. package/operations/entry/dataLoader/getLatestRevisionByEntryId.js.map +1 -1
  113. package/operations/entry/dataLoader/getPublishedRevisionByEntryId.js +27 -37
  114. package/operations/entry/dataLoader/getPublishedRevisionByEntryId.js.map +1 -1
  115. package/operations/entry/dataLoader/getRevisionById.js +32 -46
  116. package/operations/entry/dataLoader/getRevisionById.js.map +1 -1
  117. package/operations/entry/dataLoader/index.js +8 -9
  118. package/operations/entry/dataLoader/index.js.map +1 -1
  119. package/operations/entry/dataLoader/types.js +0 -3
  120. package/operations/entry/dataLoaders.js +81 -99
  121. package/operations/entry/dataLoaders.js.map +1 -1
  122. package/operations/entry/elasticsearch/assignMinimumShouldMatchToQuery.js +6 -24
  123. package/operations/entry/elasticsearch/assignMinimumShouldMatchToQuery.js.map +1 -1
  124. package/operations/entry/elasticsearch/body.js +74 -125
  125. package/operations/entry/elasticsearch/body.js.map +1 -1
  126. package/operations/entry/elasticsearch/fields/createSystemField.js +6 -7
  127. package/operations/entry/elasticsearch/fields/createSystemField.js.map +1 -1
  128. package/operations/entry/elasticsearch/fields/live.js +45 -40
  129. package/operations/entry/elasticsearch/fields/live.js.map +1 -1
  130. package/operations/entry/elasticsearch/fields/location.js +45 -40
  131. package/operations/entry/elasticsearch/fields/location.js.map +1 -1
  132. package/operations/entry/elasticsearch/fields/state.js +99 -88
  133. package/operations/entry/elasticsearch/fields/state.js.map +1 -1
  134. package/operations/entry/elasticsearch/fields.js +193 -217
  135. package/operations/entry/elasticsearch/fields.js.map +1 -1
  136. package/operations/entry/elasticsearch/filtering/applyFiltering.js +32 -45
  137. package/operations/entry/elasticsearch/filtering/applyFiltering.js.map +1 -1
  138. package/operations/entry/elasticsearch/filtering/exec.js +85 -114
  139. package/operations/entry/elasticsearch/filtering/exec.js.map +1 -1
  140. package/operations/entry/elasticsearch/filtering/index.js +0 -2
  141. package/operations/entry/elasticsearch/filtering/path.js +24 -33
  142. package/operations/entry/elasticsearch/filtering/path.js.map +1 -1
  143. package/operations/entry/elasticsearch/filtering/populated.js +8 -14
  144. package/operations/entry/elasticsearch/filtering/populated.js.map +1 -1
  145. package/operations/entry/elasticsearch/filtering/values.js +11 -12
  146. package/operations/entry/elasticsearch/filtering/values.js.map +1 -1
  147. package/operations/entry/elasticsearch/fullTextSearch.js +43 -80
  148. package/operations/entry/elasticsearch/fullTextSearch.js.map +1 -1
  149. package/operations/entry/elasticsearch/fullTextSearchFields.js +7 -17
  150. package/operations/entry/elasticsearch/fullTextSearchFields.js.map +1 -1
  151. package/operations/entry/elasticsearch/initialQuery.js +37 -80
  152. package/operations/entry/elasticsearch/initialQuery.js.map +1 -1
  153. package/operations/entry/elasticsearch/keyword.js +13 -27
  154. package/operations/entry/elasticsearch/keyword.js.map +1 -1
  155. package/operations/entry/elasticsearch/plugins/operator.js +9 -20
  156. package/operations/entry/elasticsearch/plugins/operator.js.map +1 -1
  157. package/operations/entry/elasticsearch/shouldIgnoreEsResponseError.js +6 -4
  158. package/operations/entry/elasticsearch/shouldIgnoreEsResponseError.js.map +1 -1
  159. package/operations/entry/elasticsearch/sort.js +69 -92
  160. package/operations/entry/elasticsearch/sort.js.map +1 -1
  161. package/operations/entry/elasticsearch/transformValueForSearch.js +9 -14
  162. package/operations/entry/elasticsearch/transformValueForSearch.js.map +1 -1
  163. package/operations/entry/elasticsearch/types.js +0 -3
  164. package/operations/entry/index.js +1322 -1709
  165. package/operations/entry/index.js.map +1 -1
  166. package/operations/entry/keys.js +43 -63
  167. package/operations/entry/keys.js.map +1 -1
  168. package/operations/entry/recordType.js +4 -9
  169. package/operations/entry/recordType.js.map +1 -1
  170. package/operations/entry/transformations/convertEntryKeys.js +21 -26
  171. package/operations/entry/transformations/convertEntryKeys.js.map +1 -1
  172. package/operations/entry/transformations/index.js +85 -114
  173. package/operations/entry/transformations/index.js.map +1 -1
  174. package/operations/entry/transformations/modifyEntryValues.d.ts +1 -1
  175. package/operations/entry/transformations/modifyEntryValues.js +12 -17
  176. package/operations/entry/transformations/modifyEntryValues.js.map +1 -1
  177. package/operations/entry/transformations/transformEntryKeys.js +13 -16
  178. package/operations/entry/transformations/transformEntryKeys.js.map +1 -1
  179. package/operations/entry/transformations/transformEntryToIndex.js +17 -22
  180. package/operations/entry/transformations/transformEntryToIndex.js.map +1 -1
  181. package/operations/group/index.js +113 -134
  182. package/operations/group/index.js.map +1 -1
  183. package/operations/model/index.js +128 -156
  184. package/operations/model/index.js.map +1 -1
  185. package/package.json +23 -23
  186. package/tasks/createIndexTaskPlugin.js +35 -38
  187. package/tasks/createIndexTaskPlugin.js.map +1 -1
  188. package/types.js +7 -13
  189. package/types.js.map +1 -1
  190. package/values/NoValueContainer.js +8 -10
  191. package/values/NoValueContainer.js.map +1 -1
  192. package/definitions/types.js.map +0 -1
  193. package/exports/api/cms/opensearch.js.map +0 -1
  194. package/features/CmsEntryOpenSearchBodyModifier/index.js.map +0 -1
  195. package/features/CmsEntryOpenSearchFieldIndex/index.js.map +0 -1
  196. package/features/CmsEntryOpenSearchFilter/index.js.map +0 -1
  197. package/features/CmsEntryOpenSearchFullTextSearch/index.js.map +0 -1
  198. package/features/CmsEntryOpenSearchIndex/index.js.map +0 -1
  199. package/features/CmsEntryOpenSearchQueryModifier/index.js.map +0 -1
  200. package/features/CmsEntryOpenSearchSortModifier/index.js.map +0 -1
  201. package/features/CmsEntryOpenSearchValueSearch/index.js.map +0 -1
  202. package/features/CmsEntryOpenSearchValuesModifier/index.js.map +0 -1
  203. package/helpers/index.js.map +0 -1
  204. package/index.js.map +0 -1
  205. package/operations/entry/dataLoader/types.js.map +0 -1
  206. package/operations/entry/elasticsearch/filtering/index.js.map +0 -1
  207. package/operations/entry/elasticsearch/types.js.map +0 -1
@@ -12,1750 +12,1363 @@ import { StorageOperationsCmsModelPlugin } from "@webiny/api-headless-cms";
12
12
  import { createTransformer } from "./transformations/index.js";
13
13
  import { convertEntryKeysFromStorage } from "./transformations/convertEntryKeys.js";
14
14
  import { isDeletedEntryMetaField, isEntryLevelEntryMetaField, isRestoredEntryMetaField, pickEntryMetaFields } from "@webiny/api-headless-cms/constants.js";
15
- const convertToStorageEntry = params => {
16
- const {
17
- model,
18
- storageEntry
19
- } = params;
20
- const values = model.convertValueKeyToStorage({
21
- fields: model.fields,
22
- values: storageEntry.values
23
- });
24
- return {
25
- ...storageEntry,
26
- values
27
- };
28
- };
29
- export const createEntriesStorageOperations = params => {
30
- const {
31
- entity,
32
- esEntity,
33
- elasticsearch,
34
- plugins,
35
- fieldRegistry,
36
- fieldIndexRegistry,
37
- compressionHandler,
38
- bodyModifiers,
39
- sortModifiers,
40
- queryModifiers,
41
- valueSearchRegistry,
42
- fullTextSearches,
43
- valuesModifiers,
44
- filterRegistry
45
- } = params;
46
- let storageOperationsCmsModelPlugin;
47
- const getStorageOperationsCmsModelPlugin = () => {
48
- if (storageOperationsCmsModelPlugin) {
49
- return storageOperationsCmsModelPlugin;
50
- }
51
- storageOperationsCmsModelPlugin = plugins.oneByType(StorageOperationsCmsModelPlugin.type);
52
- return storageOperationsCmsModelPlugin;
53
- };
54
- const getStorageOperationsModel = model => {
55
- const plugin = getStorageOperationsCmsModelPlugin();
56
- return plugin.getModel(model);
57
- };
58
- const dataLoaders = new DataLoadersHandler({
59
- entity
60
- });
61
- const create = async (initialModel, params) => {
62
- const {
63
- entry: initialEntry,
64
- storageEntry: initialStorageEntry
65
- } = params;
66
- const model = getStorageOperationsModel(initialModel);
67
- const isPublished = initialEntry.status === "published";
68
- const locked = isPublished ? true : initialEntry.locked;
69
- initialEntry.locked = locked;
70
- initialStorageEntry.locked = locked;
71
- const transformer = createTransformer({
72
- fieldRegistry,
73
- fieldIndexRegistry,
74
- model,
75
- entry: initialEntry,
76
- storageEntry: initialStorageEntry,
77
- compressionHandler,
78
- valuesModifiers
15
+ const convertToStorageEntry = (params)=>{
16
+ const { model, storageEntry } = params;
17
+ const values = model.convertValueKeyToStorage({
18
+ fields: model.fields,
19
+ values: storageEntry.values
79
20
  });
80
- const {
81
- entry,
82
- storageEntry
83
- } = transformer.transformEntryKeys();
84
- const esEntry = transformer.transformToIndex();
85
- const {
86
- index: esIndex
87
- } = configurations.es({
88
- model
21
+ return {
22
+ ...storageEntry,
23
+ values
24
+ };
25
+ };
26
+ const createEntriesStorageOperations = (params)=>{
27
+ const { entity, esEntity, elasticsearch, plugins, fieldRegistry, fieldIndexRegistry, compressionHandler, bodyModifiers, sortModifiers, queryModifiers, valueSearchRegistry, fullTextSearches, valuesModifiers, filterRegistry } = params;
28
+ let storageOperationsCmsModelPlugin;
29
+ const getStorageOperationsCmsModelPlugin = ()=>{
30
+ if (storageOperationsCmsModelPlugin) return storageOperationsCmsModelPlugin;
31
+ storageOperationsCmsModelPlugin = plugins.oneByType(StorageOperationsCmsModelPlugin.type);
32
+ return storageOperationsCmsModelPlugin;
33
+ };
34
+ const getStorageOperationsModel = (model)=>{
35
+ const plugin = getStorageOperationsCmsModelPlugin();
36
+ return plugin.getModel(model);
37
+ };
38
+ const dataLoaders = new DataLoadersHandler({
39
+ entity
89
40
  });
90
- const revisionKeys = createEntryRevisionKeys(entry);
91
- const latestKeys = createEntryLatestKeys(entry);
92
- const publishedKeys = createEntryPublishedKeys(entry);
93
- const entityBatch = entity.createEntityWriter({
94
- put: [{
95
- ...revisionKeys,
96
- data: {
97
- ...storageEntry,
98
- locked
41
+ const create = async (initialModel, params)=>{
42
+ const { entry: initialEntry, storageEntry: initialStorageEntry } = params;
43
+ const model = getStorageOperationsModel(initialModel);
44
+ const isPublished = "published" === initialEntry.status;
45
+ const locked = isPublished ? true : initialEntry.locked;
46
+ initialEntry.locked = locked;
47
+ initialStorageEntry.locked = locked;
48
+ const transformer = createTransformer({
49
+ fieldRegistry,
50
+ fieldIndexRegistry,
51
+ model,
52
+ entry: initialEntry,
53
+ storageEntry: initialStorageEntry,
54
+ compressionHandler,
55
+ valuesModifiers
56
+ });
57
+ const { entry, storageEntry } = transformer.transformEntryKeys();
58
+ const esEntry = transformer.transformToIndex();
59
+ const { index: esIndex } = configurations.es({
60
+ model
61
+ });
62
+ const revisionKeys = createEntryRevisionKeys(entry);
63
+ const latestKeys = createEntryLatestKeys(entry);
64
+ const publishedKeys = createEntryPublishedKeys(entry);
65
+ const entityBatch = entity.createEntityWriter({
66
+ put: [
67
+ {
68
+ ...revisionKeys,
69
+ data: {
70
+ ...storageEntry,
71
+ locked
72
+ }
73
+ },
74
+ {
75
+ ...latestKeys,
76
+ data: {
77
+ ...storageEntry,
78
+ locked
79
+ }
80
+ }
81
+ ]
82
+ });
83
+ if (isPublished) entityBatch.put({
84
+ ...publishedKeys,
85
+ data: {
86
+ ...storageEntry,
87
+ locked
88
+ }
89
+ });
90
+ try {
91
+ await entityBatch.execute();
92
+ dataLoaders.clearAll({
93
+ model
94
+ });
95
+ } catch (ex) {
96
+ throw new WebinyError(ex.message || "Could not insert entry data into the DynamoDB table.", ex.code || "CREATE_ENTRY_ERROR", {
97
+ error: ex,
98
+ entry,
99
+ storageEntry
100
+ });
99
101
  }
100
- }, {
101
- ...latestKeys,
102
- data: {
103
- ...storageEntry,
104
- locked
102
+ const esLatestData = await transformer.getElasticsearchLatestEntryData();
103
+ const elasticsearchEntityBatch = esEntity.createEntityWriter({
104
+ put: [
105
+ {
106
+ ...latestKeys,
107
+ index: esIndex,
108
+ data: esLatestData
109
+ }
110
+ ]
111
+ });
112
+ if (isPublished) {
113
+ const esPublishedData = await transformer.getElasticsearchPublishedEntryData();
114
+ elasticsearchEntityBatch.put({
115
+ ...publishedKeys,
116
+ index: esIndex,
117
+ data: esPublishedData
118
+ });
105
119
  }
106
- }]
107
- });
108
- if (isPublished) {
109
- entityBatch.put({
110
- ...publishedKeys,
111
- data: {
112
- ...storageEntry,
113
- locked
120
+ try {
121
+ await elasticsearchEntityBatch.execute();
122
+ } catch (ex) {
123
+ throw new WebinyError(ex.message || "Could not insert entry data into the Elasticsearch DynamoDB table.", ex.code || "CREATE_ES_ENTRY_ERROR", {
124
+ error: ex,
125
+ entry,
126
+ esEntry
127
+ });
114
128
  }
115
- });
116
- }
117
- try {
118
- await entityBatch.execute();
119
- dataLoaders.clearAll({
120
- model
121
- });
122
- } catch (ex) {
123
- throw new WebinyError(ex.message || "Could not insert entry data into the DynamoDB table.", ex.code || "CREATE_ENTRY_ERROR", {
124
- error: ex,
125
- entry,
126
- storageEntry
127
- });
128
- }
129
- const esLatestData = await transformer.getElasticsearchLatestEntryData();
130
- const elasticsearchEntityBatch = esEntity.createEntityWriter({
131
- put: [{
132
- ...latestKeys,
133
- index: esIndex,
134
- data: esLatestData
135
- }]
136
- });
137
- if (isPublished) {
138
- const esPublishedData = await transformer.getElasticsearchPublishedEntryData();
139
- elasticsearchEntityBatch.put({
140
- ...publishedKeys,
141
- index: esIndex,
142
- data: esPublishedData
143
- });
144
- }
145
- try {
146
- await elasticsearchEntityBatch.execute();
147
- } catch (ex) {
148
- throw new WebinyError(ex.message || "Could not insert entry data into the Elasticsearch DynamoDB table.", ex.code || "CREATE_ES_ENTRY_ERROR", {
149
- error: ex,
150
- entry,
151
- esEntry
152
- });
153
- }
154
- return initialStorageEntry;
155
- };
156
- const createRevisionFrom = async (initialModel, params) => {
157
- const {
158
- entry: initialEntry,
159
- storageEntry: initialStorageEntry
160
- } = params;
161
- const model = getStorageOperationsModel(initialModel);
162
- const transformer = createTransformer({
163
- model,
164
- entry: initialEntry,
165
- storageEntry: initialStorageEntry,
166
- fieldRegistry,
167
- fieldIndexRegistry,
168
- compressionHandler,
169
- valuesModifiers
170
- });
171
- const {
172
- entry,
173
- storageEntry
174
- } = transformer.transformEntryKeys();
175
- const revisionKeys = createEntryRevisionKeys(entry);
176
- const latestKeys = createEntryLatestKeys(entry);
177
- const publishedKeys = createEntryPublishedKeys(entry);
178
-
179
- // We'll need this flag below.
180
- const isPublished = entry.status === "published";
181
- const esLatestData = await transformer.getElasticsearchLatestEntryData();
182
- const entityBatch = entity.createEntityWriter({
183
- put: [{
184
- ...revisionKeys,
185
- data: storageEntry
186
- }, {
187
- ...latestKeys,
188
- data: storageEntry
189
- }]
190
- });
191
- if (isPublished) {
192
- entityBatch.put({
193
- ...publishedKeys,
194
- data: storageEntry
195
- });
196
-
197
- // Unpublish previously published revision (if any).
198
- const [publishedRevisionStorageEntry] = await dataLoaders.getPublishedRevisionByEntryId({
199
- model,
200
- ids: [entry.id]
201
- });
202
- if (publishedRevisionStorageEntry) {
203
- const publishedRevisionKey = createEntryRevisionKeys(publishedRevisionStorageEntry);
204
- entityBatch.put({
205
- ...publishedRevisionKey,
206
- data: {
207
- ...publishedRevisionStorageEntry,
208
- status: CONTENT_ENTRY_STATUS.UNPUBLISHED
209
- }
210
- });
211
- }
212
- }
213
- try {
214
- await entityBatch.execute();
215
- dataLoaders.clearAll({
216
- model
217
- });
218
- } catch (ex) {
219
- throw new WebinyError(ex.message || "Could not create revision from given entry in the DynamoDB table.", ex.code || "CREATE_REVISION_ERROR", {
220
- error: ex,
221
- entry,
222
- storageEntry
223
- });
224
- }
225
- const {
226
- index: esIndex
227
- } = configurations.es({
228
- model
229
- });
230
- const elasticsearchEntityBatch = esEntity.createEntityWriter({
231
- put: [{
232
- ...latestKeys,
233
- index: esIndex,
234
- data: esLatestData
235
- }]
236
- });
237
- if (isPublished) {
238
- const esPublishedData = await transformer.getElasticsearchPublishedEntryData();
239
- elasticsearchEntityBatch.put({
240
- ...publishedKeys,
241
- index: esIndex,
242
- data: esPublishedData
243
- });
244
- }
245
- try {
246
- await elasticsearchEntityBatch.execute();
247
- } catch (ex) {
248
- throw new WebinyError(ex.message || "Could not update latest entry in the DynamoDB Elasticsearch table.", ex.code || "CREATE_REVISION_ERROR", {
249
- error: ex,
250
- entry
251
- });
252
- }
253
- /**
254
- * There are no modifications on the entry created so just return the data.
255
- */
256
- return initialStorageEntry;
257
- };
258
- const update = async (initialModel, params) => {
259
- const {
260
- entry: initialEntry,
261
- storageEntry: initialStorageEntry
262
- } = params;
263
- const model = getStorageOperationsModel(initialModel);
264
- const transformer = createTransformer({
265
- valuesModifiers,
266
- model,
267
- entry: initialEntry,
268
- storageEntry: initialStorageEntry,
269
- fieldRegistry,
270
- fieldIndexRegistry,
271
- compressionHandler
272
- });
273
- const {
274
- entry,
275
- storageEntry
276
- } = transformer.transformEntryKeys();
277
- const isPublished = entry.status === "published";
278
- const locked = isPublished ? true : entry.locked;
279
- const revisionKeys = createEntryRevisionKeys(entry);
280
- const latestKeys = createEntryLatestKeys(entry);
281
- const publishedKeys = createEntryPublishedKeys(entry);
282
-
283
- /**
284
- * We need the latest entry to check if it needs to be updated.
285
- */
286
- const [latestStorageEntry] = await dataLoaders.getLatestRevisionByEntryId({
287
- model,
288
- ids: [entry.id]
289
- });
290
- const [publishedStorageEntry] = await dataLoaders.getPublishedRevisionByEntryId({
291
- model,
292
- ids: [entry.id]
293
- });
294
- const entityBatch = entity.createEntityWriter({
295
- put: [{
296
- ...revisionKeys,
297
- data: {
298
- ...storageEntry,
299
- locked
129
+ return initialStorageEntry;
130
+ };
131
+ const createRevisionFrom = async (initialModel, params)=>{
132
+ const { entry: initialEntry, storageEntry: initialStorageEntry } = params;
133
+ const model = getStorageOperationsModel(initialModel);
134
+ const transformer = createTransformer({
135
+ model,
136
+ entry: initialEntry,
137
+ storageEntry: initialStorageEntry,
138
+ fieldRegistry,
139
+ fieldIndexRegistry,
140
+ compressionHandler,
141
+ valuesModifiers
142
+ });
143
+ const { entry, storageEntry } = transformer.transformEntryKeys();
144
+ const revisionKeys = createEntryRevisionKeys(entry);
145
+ const latestKeys = createEntryLatestKeys(entry);
146
+ const publishedKeys = createEntryPublishedKeys(entry);
147
+ const isPublished = "published" === entry.status;
148
+ const esLatestData = await transformer.getElasticsearchLatestEntryData();
149
+ const entityBatch = entity.createEntityWriter({
150
+ put: [
151
+ {
152
+ ...revisionKeys,
153
+ data: storageEntry
154
+ },
155
+ {
156
+ ...latestKeys,
157
+ data: storageEntry
158
+ }
159
+ ]
160
+ });
161
+ if (isPublished) {
162
+ entityBatch.put({
163
+ ...publishedKeys,
164
+ data: storageEntry
165
+ });
166
+ const [publishedRevisionStorageEntry] = await dataLoaders.getPublishedRevisionByEntryId({
167
+ model,
168
+ ids: [
169
+ entry.id
170
+ ]
171
+ });
172
+ if (publishedRevisionStorageEntry) {
173
+ const publishedRevisionKey = createEntryRevisionKeys(publishedRevisionStorageEntry);
174
+ entityBatch.put({
175
+ ...publishedRevisionKey,
176
+ data: {
177
+ ...publishedRevisionStorageEntry,
178
+ status: CONTENT_ENTRY_STATUS.UNPUBLISHED
179
+ }
180
+ });
181
+ }
300
182
  }
301
- }]
302
- });
303
- if (isPublished) {
304
- entityBatch.put({
305
- ...publishedKeys,
306
- data: {
307
- ...storageEntry,
308
- locked
183
+ try {
184
+ await entityBatch.execute();
185
+ dataLoaders.clearAll({
186
+ model
187
+ });
188
+ } catch (ex) {
189
+ throw new WebinyError(ex.message || "Could not create revision from given entry in the DynamoDB table.", ex.code || "CREATE_REVISION_ERROR", {
190
+ error: ex,
191
+ entry,
192
+ storageEntry
193
+ });
309
194
  }
310
- });
311
- }
312
- const elasticsearchEntityBatch = esEntity.createEntityWriter();
313
- const {
314
- index: esIndex
315
- } = configurations.es({
316
- model
317
- });
318
-
319
- /**
320
- * If the latest entry is the one being updated, we need to create a new latest entry records.
321
- */
322
- if (latestStorageEntry) {
323
- const updatingLatestRevision = latestStorageEntry.id === entry.id;
324
- if (updatingLatestRevision) {
325
- /**
326
- * First we update the regular DynamoDB table.
327
- */
328
- entityBatch.put({
329
- ...latestKeys,
330
- data: storageEntry
195
+ const { index: esIndex } = configurations.es({
196
+ model
331
197
  });
332
-
333
- /**
334
- * And then update the Elasticsearch table to propagate changes to the Elasticsearch
335
- */
336
- const elasticsearchLatestData = await transformer.getElasticsearchLatestEntryData();
337
- elasticsearchEntityBatch.put({
338
- ...latestKeys,
339
- index: esIndex,
340
- data: elasticsearchLatestData
341
- });
342
- } else {
343
- /**
344
- * If not updating latest revision, we still want to update the latest revision's
345
- * entry-level meta fields to match the current revision's entry-level meta fields.
346
- */
347
- const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
348
- const updatedLatestStorageEntry = {
349
- ...latestKeys,
350
- data: {
351
- ...latestStorageEntry,
352
- ...updatedEntryLevelMetaFields
353
- }
198
+ const elasticsearchEntityBatch = esEntity.createEntityWriter({
199
+ put: [
200
+ {
201
+ ...latestKeys,
202
+ index: esIndex,
203
+ data: esLatestData
204
+ }
205
+ ]
206
+ });
207
+ if (isPublished) {
208
+ const esPublishedData = await transformer.getElasticsearchPublishedEntryData();
209
+ elasticsearchEntityBatch.put({
210
+ ...publishedKeys,
211
+ index: esIndex,
212
+ data: esPublishedData
213
+ });
214
+ }
215
+ try {
216
+ await elasticsearchEntityBatch.execute();
217
+ } catch (ex) {
218
+ throw new WebinyError(ex.message || "Could not update latest entry in the DynamoDB Elasticsearch table.", ex.code || "CREATE_REVISION_ERROR", {
219
+ error: ex,
220
+ entry
221
+ });
222
+ }
223
+ return initialStorageEntry;
224
+ };
225
+ const update = async (initialModel, params)=>{
226
+ const { entry: initialEntry, storageEntry: initialStorageEntry } = params;
227
+ const model = getStorageOperationsModel(initialModel);
228
+ const transformer = createTransformer({
229
+ valuesModifiers,
230
+ model,
231
+ entry: initialEntry,
232
+ storageEntry: initialStorageEntry,
233
+ fieldRegistry,
234
+ fieldIndexRegistry,
235
+ compressionHandler
236
+ });
237
+ const { entry, storageEntry } = transformer.transformEntryKeys();
238
+ const isPublished = "published" === entry.status;
239
+ const locked = isPublished ? true : entry.locked;
240
+ const revisionKeys = createEntryRevisionKeys(entry);
241
+ const latestKeys = createEntryLatestKeys(entry);
242
+ const publishedKeys = createEntryPublishedKeys(entry);
243
+ const [latestStorageEntry] = await dataLoaders.getLatestRevisionByEntryId({
244
+ model,
245
+ ids: [
246
+ entry.id
247
+ ]
248
+ });
249
+ const [publishedStorageEntry] = await dataLoaders.getPublishedRevisionByEntryId({
250
+ model,
251
+ ids: [
252
+ entry.id
253
+ ]
254
+ });
255
+ const entityBatch = entity.createEntityWriter({
256
+ put: [
257
+ {
258
+ ...revisionKeys,
259
+ data: {
260
+ ...storageEntry,
261
+ locked
262
+ }
263
+ }
264
+ ]
265
+ });
266
+ if (isPublished) entityBatch.put({
267
+ ...publishedKeys,
268
+ data: {
269
+ ...storageEntry,
270
+ locked
271
+ }
272
+ });
273
+ const elasticsearchEntityBatch = esEntity.createEntityWriter();
274
+ const { index: esIndex } = configurations.es({
275
+ model
276
+ });
277
+ if (latestStorageEntry) {
278
+ const updatingLatestRevision = latestStorageEntry.id === entry.id;
279
+ if (updatingLatestRevision) {
280
+ entityBatch.put({
281
+ ...latestKeys,
282
+ data: storageEntry
283
+ });
284
+ const elasticsearchLatestData = await transformer.getElasticsearchLatestEntryData();
285
+ elasticsearchEntityBatch.put({
286
+ ...latestKeys,
287
+ index: esIndex,
288
+ data: elasticsearchLatestData
289
+ });
290
+ } else {
291
+ const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
292
+ const updatedLatestStorageEntry = {
293
+ ...latestKeys,
294
+ data: {
295
+ ...latestStorageEntry,
296
+ ...updatedEntryLevelMetaFields
297
+ }
298
+ };
299
+ entityBatch.put({
300
+ ...updatedLatestStorageEntry,
301
+ PK: createPartitionKey({
302
+ id: latestStorageEntry.id,
303
+ tenant: model.tenant
304
+ }),
305
+ SK: createRevisionSortKey(latestStorageEntry)
306
+ });
307
+ entityBatch.put({
308
+ ...updatedLatestStorageEntry
309
+ });
310
+ const latestEsEntry = await esEntity.getClean(latestKeys);
311
+ if (latestEsEntry) {
312
+ const latestEsEntryDataDecompressed = await compressionHandler.decompress(latestEsEntry.data);
313
+ const updatedLatestEntry = await compressionHandler.compress({
314
+ ...latestEsEntryDataDecompressed,
315
+ ...updatedEntryLevelMetaFields
316
+ });
317
+ elasticsearchEntityBatch.put({
318
+ ...latestKeys,
319
+ index: esIndex,
320
+ data: updatedLatestEntry
321
+ });
322
+ }
323
+ }
324
+ }
325
+ if (isPublished && publishedStorageEntry?.id === entry.id) {
326
+ const elasticsearchPublishedData = await transformer.getElasticsearchPublishedEntryData();
327
+ elasticsearchEntityBatch.put({
328
+ ...publishedKeys,
329
+ index: esIndex,
330
+ data: elasticsearchPublishedData
331
+ });
332
+ }
333
+ try {
334
+ await entityBatch.execute();
335
+ dataLoaders.clearAll({
336
+ model
337
+ });
338
+ } catch (ex) {
339
+ throw new WebinyError(ex.message || "Could not update entry DynamoDB records.", ex.code || "UPDATE_ENTRY_ERROR", {
340
+ error: ex,
341
+ entry,
342
+ storageEntry
343
+ });
344
+ }
345
+ try {
346
+ await elasticsearchEntityBatch.execute();
347
+ } catch (ex) {
348
+ throw new WebinyError(ex.message || "Could not update entry DynamoDB Elasticsearch records.", ex.code || "UPDATE_ES_ENTRY_ERROR", {
349
+ error: ex,
350
+ entry
351
+ });
352
+ }
353
+ return initialStorageEntry;
354
+ };
355
+ const move = async (initialModel, id, folderId)=>{
356
+ const model = getStorageOperationsModel(initialModel);
357
+ const partitionKey = createPartitionKey({
358
+ id,
359
+ tenant: model.tenant
360
+ });
361
+ const queryAllParams = {
362
+ partitionKey,
363
+ options: {
364
+ gte: " "
365
+ }
354
366
  };
355
-
356
- /**
357
- * First we update the regular DynamoDB table. Two updates are needed:
358
- * - one for the actual revision record
359
- * - one for the latest record
360
- */
361
- entityBatch.put({
362
- ...updatedLatestStorageEntry,
363
- PK: createPartitionKey({
364
- id: latestStorageEntry.id,
367
+ const latestSortKey = createLatestSortKey();
368
+ const publishedSortKey = createPublishedSortKey();
369
+ const records = await entity.queryAll(queryAllParams);
370
+ let latestRecord;
371
+ let publishedRecord;
372
+ const entityBatch = entity.createEntityWriter();
373
+ for (const record of records){
374
+ entityBatch.put({
375
+ ...record,
376
+ data: {
377
+ ...record.data,
378
+ location: {
379
+ ...record.data.location,
380
+ folderId
381
+ }
382
+ }
383
+ });
384
+ if (record.SK === publishedSortKey) publishedRecord = record.data;
385
+ else if (record.SK === latestSortKey) latestRecord = record.data;
386
+ }
387
+ try {
388
+ await entityBatch.execute();
389
+ dataLoaders.clearAll({
390
+ model
391
+ });
392
+ } catch (ex) {
393
+ throw new WebinyError(ex.message || "Could not move all entry records from in the DynamoDB table.", ex.code || "MOVE_ENTRY_ERROR", {
394
+ error: ex,
395
+ id
396
+ });
397
+ }
398
+ const esEntityReader = esEntity.createEntityReader();
399
+ if (publishedRecord) esEntityReader.get({
400
+ PK: partitionKey,
401
+ SK: publishedSortKey
402
+ });
403
+ if (latestRecord) esEntityReader.get({
404
+ PK: partitionKey,
405
+ SK: latestSortKey
406
+ });
407
+ if (0 === esEntityReader.total) return;
408
+ const esRecords = await esEntityReader.execute();
409
+ const esItems = (await Promise.all(esRecords.map(async (record)=>{
410
+ if (!record) return null;
411
+ return {
412
+ ...record,
413
+ data: await compressionHandler.decompress(record.data)
414
+ };
415
+ }))).filter((item)=>!!item);
416
+ if (0 === esItems.length) return;
417
+ try {
418
+ const elasticsearchEntityBatch = esEntity.createEntityWriter({
419
+ put: await Promise.all(esItems.map(async (item)=>({
420
+ ...item,
421
+ data: await compressionHandler.compress({
422
+ ...item.data,
423
+ location: {
424
+ ...item.data?.location,
425
+ folderId
426
+ }
427
+ })
428
+ })))
429
+ });
430
+ await elasticsearchEntityBatch.execute();
431
+ } catch (ex) {
432
+ throw new WebinyError(ex.message || "Could not move entry DynamoDB Elasticsearch records.", ex.code || "MOVE_ES_ENTRY_ERROR", {
433
+ error: ex,
434
+ partitionKey
435
+ });
436
+ }
437
+ };
438
+ const moveToBin = async (initialModel, params)=>{
439
+ const { entry: initialEntry, storageEntry: initialStorageEntry } = params;
440
+ const model = getStorageOperationsModel(initialModel);
441
+ const transformer = createTransformer({
442
+ valuesModifiers,
443
+ model,
444
+ entry: initialEntry,
445
+ storageEntry: initialStorageEntry,
446
+ fieldRegistry,
447
+ fieldIndexRegistry,
448
+ compressionHandler
449
+ });
450
+ const { entry, storageEntry } = transformer.transformEntryKeys();
451
+ const partitionKey = createPartitionKey({
452
+ id: entry.id,
365
453
  tenant: model.tenant
366
- }),
367
- SK: createRevisionSortKey(latestStorageEntry)
368
454
  });
369
- entityBatch.put({
370
- ...updatedLatestStorageEntry
455
+ const queryAllParams = {
456
+ partitionKey,
457
+ options: {
458
+ gte: " "
459
+ }
460
+ };
461
+ const latestSortKey = createLatestSortKey();
462
+ const publishedSortKey = createPublishedSortKey();
463
+ const records = await entity.queryAll(queryAllParams);
464
+ const updatedEntryMetaFields = pickEntryMetaFields(entry, isDeletedEntryMetaField);
465
+ let latestRecord;
466
+ let publishedRecord;
467
+ const entityBatch = entity.createEntityWriter();
468
+ for (const record of records){
469
+ entityBatch.put({
470
+ ...record,
471
+ data: {
472
+ ...record.data,
473
+ ...updatedEntryMetaFields,
474
+ wbyDeleted: storageEntry.wbyDeleted,
475
+ location: storageEntry.location,
476
+ binOriginalFolderId: storageEntry.binOriginalFolderId
477
+ }
478
+ });
479
+ if (record.SK === publishedSortKey) publishedRecord = record.data;
480
+ else if (record.SK === latestSortKey) latestRecord = record.data;
481
+ }
482
+ try {
483
+ await entityBatch.execute();
484
+ dataLoaders.clearAll({
485
+ model
486
+ });
487
+ } catch (ex) {
488
+ throw new WebinyError(ex.message || "Could mark as deleted all entry records from in the DynamoDB table.", ex.code || "MOVE_ENTRY_TO_BIN_ERROR", {
489
+ error: ex,
490
+ entry,
491
+ storageEntry
492
+ });
493
+ }
494
+ const esEntityReader = esEntity.createEntityReader();
495
+ if (publishedRecord) esEntityReader.get({
496
+ PK: partitionKey,
497
+ SK: publishedSortKey
498
+ });
499
+ if (latestRecord) esEntityReader.get({
500
+ PK: partitionKey,
501
+ SK: latestSortKey
371
502
  });
372
-
373
- /**
374
- * Update the Elasticsearch table to propagate changes to the Elasticsearch.
375
- */
376
- const latestEsEntry = await esEntity.getClean(latestKeys);
377
- if (latestEsEntry) {
378
- const latestEsEntryDataDecompressed = await compressionHandler.decompress(latestEsEntry.data);
379
- const updatedLatestEntry = await compressionHandler.compress({
380
- ...latestEsEntryDataDecompressed,
381
- ...updatedEntryLevelMetaFields
382
- });
383
- elasticsearchEntityBatch.put({
384
- ...latestKeys,
385
- index: esIndex,
386
- data: updatedLatestEntry
387
- });
503
+ if (0 === esEntityReader.total) return;
504
+ const esRecords = await esEntityReader.execute();
505
+ const esItems = (await Promise.all(esRecords.map(async (record)=>{
506
+ if (!record) return null;
507
+ return {
508
+ ...record,
509
+ data: await compressionHandler.decompress(record.data)
510
+ };
511
+ }))).filter((item)=>!!item);
512
+ if (0 === esItems.length) return;
513
+ const elasticsearchEntityBatch = esEntity.createEntityWriter();
514
+ for (const item of esItems)elasticsearchEntityBatch.put({
515
+ ...item,
516
+ data: await compressionHandler.compress({
517
+ ...item.data,
518
+ ...updatedEntryMetaFields,
519
+ wbyDeleted: entry.wbyDeleted,
520
+ location: entry.location,
521
+ binOriginalFolderId: entry.binOriginalFolderId
522
+ })
523
+ });
524
+ try {
525
+ await elasticsearchEntityBatch.execute();
526
+ } catch (ex) {
527
+ throw new WebinyError(ex.message || "Could not mark as deleted entry records from DynamoDB Elasticsearch table.", ex.code || "MOVE_ENTRY_TO_BIN_ERROR", {
528
+ error: ex,
529
+ entry,
530
+ storageEntry
531
+ });
388
532
  }
389
- }
390
- }
391
- if (isPublished && publishedStorageEntry?.id === entry.id) {
392
- const elasticsearchPublishedData = await transformer.getElasticsearchPublishedEntryData();
393
- elasticsearchEntityBatch.put({
394
- ...publishedKeys,
395
- index: esIndex,
396
- data: elasticsearchPublishedData
397
- });
398
- }
399
- try {
400
- await entityBatch.execute();
401
- dataLoaders.clearAll({
402
- model
403
- });
404
- } catch (ex) {
405
- throw new WebinyError(ex.message || "Could not update entry DynamoDB records.", ex.code || "UPDATE_ENTRY_ERROR", {
406
- error: ex,
407
- entry,
408
- storageEntry
409
- });
410
- }
411
- try {
412
- await elasticsearchEntityBatch.execute();
413
- } catch (ex) {
414
- throw new WebinyError(ex.message || "Could not update entry DynamoDB Elasticsearch records.", ex.code || "UPDATE_ES_ENTRY_ERROR", {
415
- error: ex,
416
- entry
417
- });
418
- }
419
- return initialStorageEntry;
420
- };
421
- const move = async (initialModel, id, folderId) => {
422
- const model = getStorageOperationsModel(initialModel);
423
- const partitionKey = createPartitionKey({
424
- id,
425
- tenant: model.tenant
426
- });
427
- /**
428
- * First we need to fetch all the records in the regular DynamoDB table.
429
- */
430
- const queryAllParams = {
431
- partitionKey,
432
- options: {
433
- gte: " "
434
- }
435
533
  };
436
- const latestSortKey = createLatestSortKey();
437
- const publishedSortKey = createPublishedSortKey();
438
- const records = await entity.queryAll(queryAllParams);
439
- /**
440
- * Then update the folderId in each record and prepare it to be stored.
441
- */
442
- let latestRecord = undefined;
443
- let publishedRecord = undefined;
444
- const entityBatch = entity.createEntityWriter();
445
- for (const record of records) {
446
- entityBatch.put({
447
- ...record,
448
- data: {
449
- ...record.data,
450
- location: {
451
- ...record.data.location,
452
- folderId
453
- }
534
+ const restoreFromBin = async (initialModel, params)=>{
535
+ const { entry: initialEntry, storageEntry: initialStorageEntry } = params;
536
+ const model = getStorageOperationsModel(initialModel);
537
+ const transformer = createTransformer({
538
+ valuesModifiers,
539
+ model,
540
+ entry: initialEntry,
541
+ storageEntry: initialStorageEntry,
542
+ fieldRegistry,
543
+ fieldIndexRegistry,
544
+ compressionHandler
545
+ });
546
+ const { entry, storageEntry } = transformer.transformEntryKeys();
547
+ const updatedEntryMetaFields = pickEntryMetaFields(entry, isRestoredEntryMetaField);
548
+ const partitionKey = createPartitionKey({
549
+ id: entry.id,
550
+ tenant: model.tenant
551
+ });
552
+ const queryAllParams = {
553
+ partitionKey,
554
+ options: {
555
+ gte: " "
556
+ }
557
+ };
558
+ const latestSortKey = createLatestSortKey();
559
+ const publishedSortKey = createPublishedSortKey();
560
+ const records = await entity.queryAll(queryAllParams);
561
+ let latestRecord;
562
+ let publishedRecord;
563
+ const entityBatch = entity.createEntityWriter();
564
+ for (const record of records){
565
+ entityBatch.put({
566
+ ...record,
567
+ data: {
568
+ ...record.data,
569
+ ...updatedEntryMetaFields,
570
+ wbyDeleted: storageEntry.wbyDeleted,
571
+ location: storageEntry.location,
572
+ binOriginalFolderId: storageEntry.binOriginalFolderId
573
+ }
574
+ });
575
+ if (record.SK === publishedSortKey) publishedRecord = record.data;
576
+ else if (record.SK === latestSortKey) latestRecord = record.data;
454
577
  }
455
- });
456
-
457
- /**
458
- * We need to get the published and latest records, so we can update the Elasticsearch.
459
- */
460
- if (record.SK === publishedSortKey) {
461
- publishedRecord = record.data;
462
- } else if (record.SK === latestSortKey) {
463
- latestRecord = record.data;
464
- }
465
- }
466
- try {
467
- await entityBatch.execute();
468
- dataLoaders.clearAll({
469
- model
470
- });
471
- } catch (ex) {
472
- throw new WebinyError(ex.message || "Could not move all entry records from in the DynamoDB table.", ex.code || "MOVE_ENTRY_ERROR", {
473
- error: ex,
474
- id
475
- });
476
- }
477
- const esEntityReader = esEntity.createEntityReader();
478
- if (publishedRecord) {
479
- esEntityReader.get({
480
- PK: partitionKey,
481
- SK: publishedSortKey
482
- });
483
- }
484
- if (latestRecord) {
485
- esEntityReader.get({
486
- PK: partitionKey,
487
- SK: latestSortKey
488
- });
489
- }
490
- if (esEntityReader.total === 0) {
491
- return;
492
- }
493
- const esRecords = await esEntityReader.execute();
494
- const esItems = (await Promise.all(esRecords.map(async record => {
495
- if (!record) {
496
- return null;
497
- }
498
- return {
499
- ...record,
500
- data: await compressionHandler.decompress(record.data)
501
- };
502
- }))).filter(item => !!item);
503
- if (esItems.length === 0) {
504
- return;
505
- }
506
- try {
507
- const elasticsearchEntityBatch = esEntity.createEntityWriter({
508
- put: await Promise.all(esItems.map(async item => {
509
- return {
578
+ try {
579
+ await entityBatch.execute();
580
+ dataLoaders.clearAll({
581
+ model
582
+ });
583
+ } catch (ex) {
584
+ throw new WebinyError(ex.message || "Could not restore all entry records from in the DynamoDB table.", ex.code || "RESTORE_ENTRY_ERROR", {
585
+ error: ex,
586
+ entry,
587
+ storageEntry
588
+ });
589
+ }
590
+ const esEntityReader = esEntity.createEntityReader();
591
+ if (publishedRecord) esEntityReader.get({
592
+ PK: partitionKey,
593
+ SK: publishedSortKey
594
+ });
595
+ if (latestRecord) esEntityReader.get({
596
+ PK: partitionKey,
597
+ SK: latestSortKey
598
+ });
599
+ const esRecords = await esEntityReader.execute();
600
+ const esItems = (await Promise.all(esRecords.map(async (record)=>{
601
+ if (!record) return null;
602
+ return {
603
+ ...record,
604
+ data: await compressionHandler.decompress(record.data)
605
+ };
606
+ }))).filter((item)=>!!item);
607
+ if (0 === esItems.length) return initialStorageEntry;
608
+ const elasticsearchEntityBatch = esEntity.createEntityWriter();
609
+ for (const item of esItems)elasticsearchEntityBatch.put({
510
610
  ...item,
511
611
  data: await compressionHandler.compress({
512
- ...item.data,
513
- location: {
514
- ...item.data?.location,
515
- folderId
516
- }
612
+ ...item.data,
613
+ ...updatedEntryMetaFields,
614
+ wbyDeleted: entry.wbyDeleted,
615
+ location: entry.location,
616
+ binOriginalFolderId: entry.binOriginalFolderId
517
617
  })
518
- };
519
- }))
520
- });
521
- await elasticsearchEntityBatch.execute();
522
- } catch (ex) {
523
- throw new WebinyError(ex.message || "Could not move entry DynamoDB Elasticsearch records.", ex.code || "MOVE_ES_ENTRY_ERROR", {
524
- error: ex,
525
- partitionKey
526
- });
527
- }
528
- };
529
- const moveToBin = async (initialModel, params) => {
530
- const {
531
- entry: initialEntry,
532
- storageEntry: initialStorageEntry
533
- } = params;
534
- const model = getStorageOperationsModel(initialModel);
535
- const transformer = createTransformer({
536
- valuesModifiers,
537
- model,
538
- entry: initialEntry,
539
- storageEntry: initialStorageEntry,
540
- fieldRegistry,
541
- fieldIndexRegistry,
542
- compressionHandler
543
- });
544
- const {
545
- entry,
546
- storageEntry
547
- } = transformer.transformEntryKeys();
548
- const partitionKey = createPartitionKey({
549
- id: entry.id,
550
- tenant: model.tenant
551
- });
552
-
553
- /**
554
- * First we need to fetch all the records in the regular DynamoDB table.
555
- */
556
- const queryAllParams = {
557
- partitionKey,
558
- options: {
559
- gte: " "
560
- }
618
+ });
619
+ try {
620
+ await elasticsearchEntityBatch.execute();
621
+ } catch (ex) {
622
+ throw new WebinyError(ex.message || "Could not restore entry records from DynamoDB Elasticsearch table.", ex.code || "RESTORE_ENTRY_ERROR", {
623
+ error: ex,
624
+ entry,
625
+ storageEntry
626
+ });
627
+ }
628
+ return initialStorageEntry;
561
629
  };
562
- const latestSortKey = createLatestSortKey();
563
- const publishedSortKey = createPublishedSortKey();
564
- const records = await entity.queryAll(queryAllParams);
565
-
566
- /**
567
- * Let's pick the `deleted` meta fields from the entry.
568
- */
569
- const updatedEntryMetaFields = pickEntryMetaFields(entry, isDeletedEntryMetaField);
570
-
571
- /**
572
- * Then update all the records with data received.
573
- */
574
- let latestRecord = undefined;
575
- let publishedRecord = undefined;
576
- const entityBatch = entity.createEntityWriter();
577
- for (const record of records) {
578
- entityBatch.put({
579
- ...record,
580
- data: {
581
- ...record.data,
582
- ...updatedEntryMetaFields,
583
- wbyDeleted: storageEntry.wbyDeleted,
584
- location: storageEntry.location,
585
- binOriginalFolderId: storageEntry.binOriginalFolderId
630
+ const deleteEntry = async (initialModel, params)=>{
631
+ const { entry } = params;
632
+ const id = entry.id || entry.entryId;
633
+ const model = getStorageOperationsModel(initialModel);
634
+ const partitionKey = createPartitionKey({
635
+ id,
636
+ tenant: model.tenant
637
+ });
638
+ const items = await entity.queryAll({
639
+ partitionKey,
640
+ options: {
641
+ gte: " "
642
+ }
643
+ });
644
+ const esItems = await esEntity.queryAll({
645
+ partitionKey,
646
+ options: {
647
+ gte: " "
648
+ }
649
+ });
650
+ const entityBatch = entity.createEntityWriter({
651
+ delete: items.map((item)=>({
652
+ PK: item.PK,
653
+ SK: item.SK
654
+ }))
655
+ });
656
+ const elasticsearchEntityBatch = esEntity.createEntityWriter({
657
+ delete: esItems.map((item)=>({
658
+ PK: item.PK,
659
+ SK: item.SK
660
+ }))
661
+ });
662
+ try {
663
+ await entityBatch.execute();
664
+ dataLoaders.clearAll({
665
+ model
666
+ });
667
+ } catch (ex) {
668
+ throw new WebinyError(ex.message || "Could not destroy entry records from DynamoDB table.", ex.code || "DELETE_ENTRY_ERROR", {
669
+ error: ex,
670
+ id
671
+ });
672
+ }
673
+ try {
674
+ await elasticsearchEntityBatch.execute();
675
+ } catch (ex) {
676
+ throw new WebinyError(ex.message || "Could not destroy entry records from DynamoDB Elasticsearch table.", ex.code || "DELETE_ENTRY_ERROR", {
677
+ error: ex,
678
+ id
679
+ });
586
680
  }
587
- });
588
-
589
- /**
590
- * We need to get the published and latest records, so we can update the Elasticsearch.
591
- */
592
- if (record.SK === publishedSortKey) {
593
- publishedRecord = record.data;
594
- } else if (record.SK === latestSortKey) {
595
- latestRecord = record.data;
596
- }
597
- }
598
-
599
- /**
600
- * We write the records back to the primary DynamoDB table.
601
- */
602
- try {
603
- await entityBatch.execute();
604
- dataLoaders.clearAll({
605
- model
606
- });
607
- } catch (ex) {
608
- throw new WebinyError(ex.message || "Could mark as deleted all entry records from in the DynamoDB table.", ex.code || "MOVE_ENTRY_TO_BIN_ERROR", {
609
- error: ex,
610
- entry,
611
- storageEntry
612
- });
613
- }
614
-
615
- /**
616
- * We need to get the published and latest records from Elasticsearch.
617
- */
618
- const esEntityReader = esEntity.createEntityReader();
619
- if (publishedRecord) {
620
- esEntityReader.get({
621
- PK: partitionKey,
622
- SK: publishedSortKey
623
- });
624
- }
625
- if (latestRecord) {
626
- esEntityReader.get({
627
- PK: partitionKey,
628
- SK: latestSortKey
629
- });
630
- }
631
- if (esEntityReader.total === 0) {
632
- return;
633
- }
634
- const esRecords = await esEntityReader.execute();
635
- const esItems = (await Promise.all(esRecords.map(async record => {
636
- if (!record) {
637
- return null;
638
- }
639
- return {
640
- ...record,
641
- data: await compressionHandler.decompress(record.data)
642
- };
643
- }))).filter(item => !!item);
644
- if (esItems.length === 0) {
645
- return;
646
- }
647
-
648
- /**
649
- * We update all ES records with data received.
650
- */
651
- const elasticsearchEntityBatch = esEntity.createEntityWriter();
652
- for (const item of esItems) {
653
- elasticsearchEntityBatch.put({
654
- ...item,
655
- data: await compressionHandler.compress({
656
- ...item.data,
657
- ...updatedEntryMetaFields,
658
- wbyDeleted: entry.wbyDeleted,
659
- location: entry.location,
660
- binOriginalFolderId: entry.binOriginalFolderId
661
- })
662
- });
663
- }
664
-
665
- /**
666
- * We write the records back to the primary DynamoDB Elasticsearch table.
667
- */
668
- try {
669
- await elasticsearchEntityBatch.execute();
670
- } catch (ex) {
671
- throw new WebinyError(ex.message || "Could not mark as deleted entry records from DynamoDB Elasticsearch table.", ex.code || "MOVE_ENTRY_TO_BIN_ERROR", {
672
- error: ex,
673
- entry,
674
- storageEntry
675
- });
676
- }
677
- };
678
- const restoreFromBin = async (initialModel, params) => {
679
- const {
680
- entry: initialEntry,
681
- storageEntry: initialStorageEntry
682
- } = params;
683
- const model = getStorageOperationsModel(initialModel);
684
- const transformer = createTransformer({
685
- valuesModifiers,
686
- model,
687
- entry: initialEntry,
688
- storageEntry: initialStorageEntry,
689
- fieldRegistry,
690
- fieldIndexRegistry,
691
- compressionHandler
692
- });
693
- const {
694
- entry,
695
- storageEntry
696
- } = transformer.transformEntryKeys();
697
-
698
- /**
699
- * Let's pick the `restored` meta fields from the storage entry.
700
- */
701
- const updatedEntryMetaFields = pickEntryMetaFields(entry, isRestoredEntryMetaField);
702
- const partitionKey = createPartitionKey({
703
- id: entry.id,
704
- tenant: model.tenant
705
- });
706
-
707
- /**
708
- * First we need to fetch all the records in the regular DynamoDB table.
709
- */
710
- const queryAllParams = {
711
- partitionKey,
712
- options: {
713
- gte: " "
714
- }
715
681
  };
716
- const latestSortKey = createLatestSortKey();
717
- const publishedSortKey = createPublishedSortKey();
718
- const records = await entity.queryAll(queryAllParams);
719
-
720
- /**
721
- * Then update all the records with data received.
722
- */
723
- let latestRecord = undefined;
724
- let publishedRecord = undefined;
725
- const entityBatch = entity.createEntityWriter();
726
- for (const record of records) {
727
- entityBatch.put({
728
- ...record,
729
- data: {
730
- ...record.data,
731
- ...updatedEntryMetaFields,
732
- wbyDeleted: storageEntry.wbyDeleted,
733
- location: storageEntry.location,
734
- binOriginalFolderId: storageEntry.binOriginalFolderId
682
+ const deleteRevision = async (initialModel, params)=>{
683
+ const { entry, latestEntry, latestStorageEntry: initialLatestStorageEntry } = params;
684
+ const model = getStorageOperationsModel(initialModel);
685
+ const partitionKey = createPartitionKey({
686
+ id: entry.id,
687
+ tenant: model.tenant
688
+ });
689
+ const { index } = configurations.es({
690
+ model
691
+ });
692
+ const [publishedStorageEntry] = await dataLoaders.getPublishedRevisionByEntryId({
693
+ model,
694
+ ids: [
695
+ entry.id
696
+ ]
697
+ });
698
+ const entityBatch = entity.createEntityWriter({
699
+ delete: [
700
+ {
701
+ PK: partitionKey,
702
+ SK: createRevisionSortKey(entry)
703
+ }
704
+ ]
705
+ });
706
+ const elasticsearchEntityBatch = esEntity.createEntityWriter();
707
+ if (publishedStorageEntry?.id === entry.id) {
708
+ entityBatch.delete({
709
+ PK: partitionKey,
710
+ SK: createPublishedSortKey()
711
+ });
712
+ elasticsearchEntityBatch.delete({
713
+ PK: partitionKey,
714
+ SK: createPublishedSortKey()
715
+ });
735
716
  }
736
- });
737
-
738
- /**
739
- * We need to get the published and latest records, so we can update the Elasticsearch.
740
- */
741
- if (record.SK === publishedSortKey) {
742
- publishedRecord = record.data;
743
- } else if (record.SK === latestSortKey) {
744
- latestRecord = record.data;
745
- }
746
- }
747
-
748
- /**
749
- * We write the records back to the primary DynamoDB table.
750
- */
751
- try {
752
- await entityBatch.execute();
753
- dataLoaders.clearAll({
754
- model
755
- });
756
- } catch (ex) {
757
- throw new WebinyError(ex.message || "Could not restore all entry records from in the DynamoDB table.", ex.code || "RESTORE_ENTRY_ERROR", {
758
- error: ex,
759
- entry,
760
- storageEntry
761
- });
762
- }
763
-
764
- /**
765
- * We need to get the published and latest records from Elasticsearch.
766
- */
767
- const esEntityReader = esEntity.createEntityReader();
768
- if (publishedRecord) {
769
- esEntityReader.get({
770
- PK: partitionKey,
771
- SK: publishedSortKey
772
- });
773
- }
774
- if (latestRecord) {
775
- esEntityReader.get({
776
- PK: partitionKey,
777
- SK: latestSortKey
778
- });
779
- }
780
- const esRecords = await esEntityReader.execute();
781
- const esItems = (await Promise.all(esRecords.map(async record => {
782
- if (!record) {
783
- return null;
784
- }
785
- return {
786
- ...record,
787
- data: await compressionHandler.decompress(record.data)
788
- };
789
- }))).filter(item => !!item);
790
- if (esItems.length === 0) {
791
- return initialStorageEntry;
792
- }
793
-
794
- /**
795
- * We update all ES records with data received.
796
- */
797
- const elasticsearchEntityBatch = esEntity.createEntityWriter();
798
- for (const item of esItems) {
799
- elasticsearchEntityBatch.put({
800
- ...item,
801
- data: await compressionHandler.compress({
802
- ...item.data,
803
- ...updatedEntryMetaFields,
804
- wbyDeleted: entry.wbyDeleted,
805
- location: entry.location,
806
- binOriginalFolderId: entry.binOriginalFolderId
807
- })
808
- });
809
- }
810
-
811
- /**
812
- * We write the records back to the primary DynamoDB Elasticsearch table.
813
- */
814
- try {
815
- await elasticsearchEntityBatch.execute();
816
- } catch (ex) {
817
- throw new WebinyError(ex.message || "Could not restore entry records from DynamoDB Elasticsearch table.", ex.code || "RESTORE_ENTRY_ERROR", {
818
- error: ex,
819
- entry,
820
- storageEntry
821
- });
822
- }
823
- return initialStorageEntry;
824
- };
825
- const deleteEntry = async (initialModel, params) => {
826
- const {
827
- entry
828
- } = params;
829
- const id = entry.id || entry.entryId;
830
- const model = getStorageOperationsModel(initialModel);
831
- const partitionKey = createPartitionKey({
832
- id,
833
- tenant: model.tenant
834
- });
835
- const items = await entity.queryAll({
836
- partitionKey,
837
- options: {
838
- gte: " "
839
- }
840
- });
841
- const esItems = await esEntity.queryAll({
842
- partitionKey,
843
- options: {
844
- gte: " "
845
- }
846
- });
847
- const entityBatch = entity.createEntityWriter({
848
- delete: items.map(item => {
849
- return {
850
- PK: item.PK,
851
- SK: item.SK
852
- };
853
- })
854
- });
855
- const elasticsearchEntityBatch = esEntity.createEntityWriter({
856
- delete: esItems.map(item => {
857
- return {
858
- PK: item.PK,
859
- SK: item.SK
860
- };
861
- })
862
- });
863
- try {
864
- await entityBatch.execute();
865
- dataLoaders.clearAll({
866
- model
867
- });
868
- } catch (ex) {
869
- throw new WebinyError(ex.message || "Could not destroy entry records from DynamoDB table.", ex.code || "DELETE_ENTRY_ERROR", {
870
- error: ex,
871
- id
872
- });
873
- }
874
- try {
875
- await elasticsearchEntityBatch.execute();
876
- } catch (ex) {
877
- throw new WebinyError(ex.message || "Could not destroy entry records from DynamoDB Elasticsearch table.", ex.code || "DELETE_ENTRY_ERROR", {
878
- error: ex,
879
- id
880
- });
881
- }
882
- };
883
- const deleteRevision = async (initialModel, params) => {
884
- const {
885
- entry,
886
- latestEntry,
887
- latestStorageEntry: initialLatestStorageEntry
888
- } = params;
889
- const model = getStorageOperationsModel(initialModel);
890
- const partitionKey = createPartitionKey({
891
- id: entry.id,
892
- tenant: model.tenant
893
- });
894
- const {
895
- index
896
- } = configurations.es({
897
- model
898
- });
899
- /**
900
- * We need published entry to delete it if necessary.
901
- */
902
- const [publishedStorageEntry] = await dataLoaders.getPublishedRevisionByEntryId({
903
- model,
904
- ids: [entry.id]
905
- });
906
- /**
907
- * We need to delete all existing records of the given entry revision.
908
- */
909
- const entityBatch = entity.createEntityWriter({
910
- delete: [{
911
- PK: partitionKey,
912
- SK: createRevisionSortKey(entry)
913
- }]
914
- });
915
- const elasticsearchEntityBatch = esEntity.createEntityWriter();
916
-
917
- /**
918
- * If revision we are deleting is the published one as well, we need to delete those records as well.
919
- */
920
- if (publishedStorageEntry?.id === entry.id) {
921
- entityBatch.delete({
922
- PK: partitionKey,
923
- SK: createPublishedSortKey()
924
- });
925
- elasticsearchEntityBatch.delete({
926
- PK: partitionKey,
927
- SK: createPublishedSortKey()
928
- });
929
- }
930
- if (latestEntry && initialLatestStorageEntry) {
931
- const latestStorageEntry = convertToStorageEntry({
932
- storageEntry: initialLatestStorageEntry,
933
- model
934
- });
935
-
936
- /**
937
- * In the end we need to set the new latest entry.
938
- */
939
- const latestStorageEntryLatestKey = createEntryLatestKeys(latestStorageEntry);
940
- entityBatch.put({
941
- ...latestStorageEntryLatestKey,
942
- data: latestStorageEntry
943
- });
944
-
945
- /**
946
- * Also perform an update on the actual revision. This is needed
947
- * because of updates on the entry-level meta fields.
948
- */
949
- const actualRevisionEntryKey = createEntryRevisionKeys(initialLatestStorageEntry);
950
- entityBatch.put({
951
- ...actualRevisionEntryKey,
952
- data: latestStorageEntry
953
- });
954
- const latestTransformer = createTransformer({
955
- valuesModifiers,
956
- model,
957
- entry: latestEntry,
958
- storageEntry: initialLatestStorageEntry,
959
- fieldRegistry,
960
- fieldIndexRegistry,
961
- compressionHandler
962
- });
963
- const esLatestData = await latestTransformer.getElasticsearchLatestEntryData();
964
- const esLatestKeys = createEntryLatestKeys(latestEntry);
965
- elasticsearchEntityBatch.put({
966
- ...esLatestKeys,
967
- index,
968
- data: esLatestData
969
- });
970
- }
971
- try {
972
- await entityBatch.execute();
973
- dataLoaders.clearAll({
974
- model
975
- });
976
- } catch (ex) {
977
- throw new WebinyError(ex.message || "Could not batch write entry records to DynamoDB table.", ex.code || "DELETE_REVISION_ERROR", {
978
- error: ex,
979
- entry,
980
- latestEntry,
981
- initialLatestStorageEntry
982
- });
983
- }
984
- try {
985
- await elasticsearchEntityBatch.execute();
986
- } catch (ex) {
987
- throw new WebinyError(ex.message || "Could not batch write entry records to DynamoDB Elasticsearch table.", ex.code || "DELETE_REVISION_ERROR", {
988
- error: ex,
989
- entry,
990
- latestEntry,
991
- initialLatestStorageEntry
992
- });
993
- }
994
- };
995
- const deleteMultipleEntries = async (initialModel, params) => {
996
- const {
997
- entries
998
- } = params;
999
- const model = getStorageOperationsModel(initialModel);
1000
- /**
1001
- * First we need all the revisions of the entries we want to delete.
1002
- */
1003
- const revisions = await dataLoaders.getAllEntryRevisions({
1004
- model,
1005
- ids: entries
1006
- });
1007
- /**
1008
- * Then we need to construct the queries for all the revisions and entries.
1009
- */
1010
-
1011
- const entityBatch = entity.createEntityWriter();
1012
- const elasticsearchEntityBatch = esEntity.createEntityWriter();
1013
- for (const id of entries) {
1014
- /**
1015
- * Latest item.
1016
- */
1017
- entityBatch.delete({
1018
- PK: createPartitionKey({
1019
- id,
1020
- tenant: model.tenant
1021
- }),
1022
- SK: "L"
1023
- });
1024
- elasticsearchEntityBatch.delete({
1025
- PK: createPartitionKey({
1026
- id,
1027
- tenant: model.tenant
1028
- }),
1029
- SK: "L"
1030
- });
1031
-
1032
- /**
1033
- * Published item.
1034
- */
1035
- entityBatch.delete({
1036
- PK: createPartitionKey({
1037
- id,
1038
- tenant: model.tenant
1039
- }),
1040
- SK: "P"
1041
- });
1042
- elasticsearchEntityBatch.delete({
1043
- PK: createPartitionKey({
1044
- id,
1045
- tenant: model.tenant
1046
- }),
1047
- SK: "P"
1048
- });
1049
- }
1050
- /**
1051
- * Exact revisions of all the entries
1052
- */
1053
- for (const revision of revisions) {
1054
- entityBatch.delete({
1055
- PK: createPartitionKey({
1056
- id: revision.id,
1057
- tenant: model.tenant
1058
- }),
1059
- SK: createRevisionSortKey({
1060
- version: revision.version
1061
- })
1062
- });
1063
- }
1064
- await entityBatch.execute();
1065
- await elasticsearchEntityBatch.execute();
1066
- };
1067
- const list = async (initialModel, params) => {
1068
- const model = getStorageOperationsModel(initialModel);
1069
- const limit = createLimit(params.limit, 50);
1070
- const {
1071
- index
1072
- } = configurations.es({
1073
- model
1074
- });
1075
- const body = createElasticsearchBody({
1076
- model,
1077
- fieldRegistry,
1078
- fieldIndexRegistry,
1079
- bodyModifiers,
1080
- sortModifiers,
1081
- queryModifiers,
1082
- valueSearchRegistry,
1083
- fullTextSearches,
1084
- filterRegistry,
1085
- params: {
1086
- ...params,
1087
- limit,
1088
- after: decodeCursor(params.after)
1089
- },
1090
- plugins
1091
- });
1092
- let response;
1093
- try {
1094
- response = await elasticsearch.search({
1095
- index,
1096
- body
1097
- });
1098
- } catch (error) {
1099
- /**
1100
- * We will silently ignore the `index_not_found_exception` error and return an empty result set.
1101
- * This is because the index might not exist yet, and we don't want to throw an error.
1102
- */
1103
- if (shouldIgnoreEsResponseError(error)) {
717
+ if (latestEntry && initialLatestStorageEntry) {
718
+ const latestStorageEntry = convertToStorageEntry({
719
+ storageEntry: initialLatestStorageEntry,
720
+ model
721
+ });
722
+ const latestStorageEntryLatestKey = createEntryLatestKeys(latestStorageEntry);
723
+ entityBatch.put({
724
+ ...latestStorageEntryLatestKey,
725
+ data: latestStorageEntry
726
+ });
727
+ const actualRevisionEntryKey = createEntryRevisionKeys(initialLatestStorageEntry);
728
+ entityBatch.put({
729
+ ...actualRevisionEntryKey,
730
+ data: latestStorageEntry
731
+ });
732
+ const latestTransformer = createTransformer({
733
+ valuesModifiers,
734
+ model,
735
+ entry: latestEntry,
736
+ storageEntry: initialLatestStorageEntry,
737
+ fieldRegistry,
738
+ fieldIndexRegistry,
739
+ compressionHandler
740
+ });
741
+ const esLatestData = await latestTransformer.getElasticsearchLatestEntryData();
742
+ const esLatestKeys = createEntryLatestKeys(latestEntry);
743
+ elasticsearchEntityBatch.put({
744
+ ...esLatestKeys,
745
+ index,
746
+ data: esLatestData
747
+ });
748
+ }
749
+ try {
750
+ await entityBatch.execute();
751
+ dataLoaders.clearAll({
752
+ model
753
+ });
754
+ } catch (ex) {
755
+ throw new WebinyError(ex.message || "Could not batch write entry records to DynamoDB table.", ex.code || "DELETE_REVISION_ERROR", {
756
+ error: ex,
757
+ entry,
758
+ latestEntry,
759
+ initialLatestStorageEntry
760
+ });
761
+ }
762
+ try {
763
+ await elasticsearchEntityBatch.execute();
764
+ } catch (ex) {
765
+ throw new WebinyError(ex.message || "Could not batch write entry records to DynamoDB Elasticsearch table.", ex.code || "DELETE_REVISION_ERROR", {
766
+ error: ex,
767
+ entry,
768
+ latestEntry,
769
+ initialLatestStorageEntry
770
+ });
771
+ }
772
+ };
773
+ const deleteMultipleEntries = async (initialModel, params)=>{
774
+ const { entries } = params;
775
+ const model = getStorageOperationsModel(initialModel);
776
+ const revisions = await dataLoaders.getAllEntryRevisions({
777
+ model,
778
+ ids: entries
779
+ });
780
+ const entityBatch = entity.createEntityWriter();
781
+ const elasticsearchEntityBatch = esEntity.createEntityWriter();
782
+ for (const id of entries){
783
+ entityBatch.delete({
784
+ PK: createPartitionKey({
785
+ id,
786
+ tenant: model.tenant
787
+ }),
788
+ SK: "L"
789
+ });
790
+ elasticsearchEntityBatch.delete({
791
+ PK: createPartitionKey({
792
+ id,
793
+ tenant: model.tenant
794
+ }),
795
+ SK: "L"
796
+ });
797
+ entityBatch.delete({
798
+ PK: createPartitionKey({
799
+ id,
800
+ tenant: model.tenant
801
+ }),
802
+ SK: "P"
803
+ });
804
+ elasticsearchEntityBatch.delete({
805
+ PK: createPartitionKey({
806
+ id,
807
+ tenant: model.tenant
808
+ }),
809
+ SK: "P"
810
+ });
811
+ }
812
+ for (const revision of revisions)entityBatch.delete({
813
+ PK: createPartitionKey({
814
+ id: revision.id,
815
+ tenant: model.tenant
816
+ }),
817
+ SK: createRevisionSortKey({
818
+ version: revision.version
819
+ })
820
+ });
821
+ await entityBatch.execute();
822
+ await elasticsearchEntityBatch.execute();
823
+ };
824
+ const list = async (initialModel, params)=>{
825
+ const model = getStorageOperationsModel(initialModel);
826
+ const limit = createLimit(params.limit, 50);
827
+ const { index } = configurations.es({
828
+ model
829
+ });
830
+ const body = createElasticsearchBody({
831
+ model,
832
+ fieldRegistry,
833
+ fieldIndexRegistry,
834
+ bodyModifiers,
835
+ sortModifiers,
836
+ queryModifiers,
837
+ valueSearchRegistry,
838
+ fullTextSearches,
839
+ filterRegistry,
840
+ params: {
841
+ ...params,
842
+ limit,
843
+ after: decodeCursor(params.after)
844
+ },
845
+ plugins
846
+ });
847
+ let response;
848
+ try {
849
+ response = await elasticsearch.search({
850
+ index,
851
+ body
852
+ });
853
+ } catch (error) {
854
+ if (shouldIgnoreEsResponseError(error)) return {
855
+ hasMoreItems: false,
856
+ totalCount: 0,
857
+ cursor: null,
858
+ items: []
859
+ };
860
+ throw new WebinyError(error.message, error.code || "OPENSEARCH_ERROR", {
861
+ error,
862
+ index,
863
+ body,
864
+ model
865
+ });
866
+ }
867
+ const { hits, total } = response.body.hits;
868
+ const items = extractEntriesFromIndex({
869
+ fieldRegistry,
870
+ fieldIndexRegistry,
871
+ model,
872
+ entries: hits.map((item)=>item._source)
873
+ }).map((item)=>convertEntryKeysFromStorage({
874
+ model,
875
+ entry: item
876
+ }));
877
+ const hasMoreItems = items.length > limit;
878
+ if (hasMoreItems) items.pop();
879
+ const cursor = items.length > 0 ? encodeCursor(hits[items.length - 1].sort) || null : null;
1104
880
  return {
1105
- hasMoreItems: false,
1106
- totalCount: 0,
1107
- cursor: null,
1108
- items: []
881
+ hasMoreItems,
882
+ totalCount: getTotalCount(total),
883
+ cursor,
884
+ items
1109
885
  };
1110
- }
1111
- throw new WebinyError(error.message, error.code || "OPENSEARCH_ERROR", {
1112
- error,
1113
- index,
1114
- body,
1115
- model
1116
- });
1117
- }
1118
- const {
1119
- hits,
1120
- total
1121
- } = response.body.hits;
1122
- const items = extractEntriesFromIndex({
1123
- fieldRegistry,
1124
- fieldIndexRegistry,
1125
- model,
1126
- entries: hits.map(item => {
1127
- return item._source;
1128
- })
1129
- }).map(item => {
1130
- return convertEntryKeysFromStorage({
1131
- model,
1132
- entry: item
1133
- });
1134
- });
1135
- const hasMoreItems = items.length > limit;
1136
- if (hasMoreItems) {
1137
- /**
1138
- * Remove the last item from results, we don't want to include it.
1139
- */
1140
- items.pop();
1141
- }
1142
- /**
1143
- * Cursor is the `sort` value of the last item in the array.
1144
- * https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html#search-after
1145
- */
1146
- /**
1147
- * TODO expect errors over hit properties is required due to opensearch library narrowing types too much because of the _source: false. At least what Claude says, didnt go into it too much.
1148
- * Properties are there, but types are not correct.
1149
- */
1150
- // @ts-expect-error
1151
- const cursor = items.length > 0 ? encodeCursor(hits[items.length - 1].sort) || null : null;
1152
- return {
1153
- hasMoreItems,
1154
- totalCount: getTotalCount(total),
1155
- cursor,
1156
- items
1157
886
  };
1158
- };
1159
- const get = async (initialModel, params) => {
1160
- const model = getStorageOperationsModel(initialModel);
1161
- const {
1162
- items
1163
- } = await list(model, {
1164
- ...params,
1165
- limit: 1
1166
- });
1167
- return items.shift() || null;
1168
- };
1169
- const publish = async (initialModel, params) => {
1170
- const {
1171
- entry: initialEntry,
1172
- storageEntry: initialStorageEntry
1173
- } = params;
1174
- const model = getStorageOperationsModel(initialModel);
1175
- const transformer = createTransformer({
1176
- valuesModifiers,
1177
- model,
1178
- entry: initialEntry,
1179
- storageEntry: initialStorageEntry,
1180
- fieldRegistry,
1181
- fieldIndexRegistry,
1182
- compressionHandler
1183
- });
1184
- const {
1185
- entry,
1186
- storageEntry
1187
- } = transformer.transformEntryKeys();
1188
- const revisionKeys = createEntryRevisionKeys(entry);
1189
- const latestKeys = createEntryLatestKeys(entry);
1190
- const publishedKeys = createEntryPublishedKeys(entry);
1191
- let latestEsEntry = null;
1192
- try {
1193
- latestEsEntry = await esEntity.getClean(latestKeys);
1194
- } catch (ex) {
1195
- throw new WebinyError(ex.message || "Could not read Elasticsearch latest data.", ex.code || "PUBLISH_LATEST_READ", {
1196
- error: ex,
1197
- latestKeys: latestKeys,
1198
- publishedKeys: publishedKeys
1199
- });
1200
- }
1201
- if (!latestEsEntry) {
1202
- throw new WebinyError(`Could not publish entry. Could not load latest ("L") record (ES table).`, "PUBLISH_ERROR", {
1203
- entry
1204
- });
1205
- }
1206
-
1207
- /**
1208
- * We need the latest entry to check if it needs to be updated as well in the Elasticsearch.
1209
- */
1210
- const [latestStorageEntry] = await dataLoaders.getLatestRevisionByEntryId({
1211
- model,
1212
- ids: [entry.id]
1213
- });
1214
- if (!latestStorageEntry) {
1215
- throw new WebinyError(`Could not publish entry. Could not load latest ("L") record.`, "PUBLISH_ERROR", {
1216
- entry
1217
- });
1218
- }
1219
-
1220
- /**
1221
- * We need currently published entry to check if need to remove it.
1222
- */
1223
- const [publishedStorageEntry] = await dataLoaders.getPublishedRevisionByEntryId({
1224
- model,
1225
- ids: [entry.id]
1226
- });
1227
-
1228
- // 1. Update REV# and P records with new data.
1229
- const entityBatch = entity.createEntityWriter({
1230
- put: [{
1231
- ...revisionKeys,
1232
- data: storageEntry
1233
- }, {
1234
- ...publishedKeys,
1235
- data: storageEntry
1236
- }]
1237
- });
1238
- const elasticsearchEntityWriter = esEntity.createEntityWriter();
1239
- const {
1240
- index: esIndex
1241
- } = configurations.es({
1242
- model
1243
- });
1244
-
1245
- // 2. When it comes to the latest record, we need to perform a couple of different
1246
- // updates, based on whether the entry being published is the latest revision or not.
1247
- const publishedRevisionId = publishedStorageEntry?.id;
1248
- const publishingLatestRevision = latestStorageEntry?.id === entry.id;
1249
- if (publishingLatestRevision) {
1250
- // 2.1 If we're publishing the latest revision, we first need to update the L record.
1251
- entityBatch.put({
1252
- ...latestKeys,
1253
- data: storageEntry
1254
- });
1255
-
1256
- // 2.2 Additionally, if we have a previously published entry, we need to mark it as unpublished.
1257
- // Note that we need to take re-publishing into account (same published revision being
1258
- // published again), in which case the below code does not apply. This is because the
1259
- // required updates were already applied above.
1260
- if (publishedStorageEntry) {
1261
- const isRepublishing = publishedStorageEntry.id === entry.id;
1262
- if (!isRepublishing) {
1263
- /**
1264
- * Update currently published entry (unpublish it)
1265
- */
1266
- const publishedStorageEntryKeys = createEntryRevisionKeys(publishedStorageEntry);
1267
- entityBatch.put({
1268
- ...publishedStorageEntryKeys,
1269
- data: {
1270
- ...publishedStorageEntry,
1271
- status: CONTENT_ENTRY_STATUS.UNPUBLISHED
1272
- }
1273
- });
887
+ const get = async (initialModel, params)=>{
888
+ const model = getStorageOperationsModel(initialModel);
889
+ const { items } = await list(model, {
890
+ ...params,
891
+ limit: 1
892
+ });
893
+ return items.shift() || null;
894
+ };
895
+ const publish = async (initialModel, params)=>{
896
+ const { entry: initialEntry, storageEntry: initialStorageEntry } = params;
897
+ const model = getStorageOperationsModel(initialModel);
898
+ const transformer = createTransformer({
899
+ valuesModifiers,
900
+ model,
901
+ entry: initialEntry,
902
+ storageEntry: initialStorageEntry,
903
+ fieldRegistry,
904
+ fieldIndexRegistry,
905
+ compressionHandler
906
+ });
907
+ const { entry, storageEntry } = transformer.transformEntryKeys();
908
+ const revisionKeys = createEntryRevisionKeys(entry);
909
+ const latestKeys = createEntryLatestKeys(entry);
910
+ const publishedKeys = createEntryPublishedKeys(entry);
911
+ let latestEsEntry = null;
912
+ try {
913
+ latestEsEntry = await esEntity.getClean(latestKeys);
914
+ } catch (ex) {
915
+ throw new WebinyError(ex.message || "Could not read Elasticsearch latest data.", ex.code || "PUBLISH_LATEST_READ", {
916
+ error: ex,
917
+ latestKeys: latestKeys,
918
+ publishedKeys: publishedKeys
919
+ });
1274
920
  }
1275
- }
1276
- } else {
1277
- // 2.3 If the published revision is not the latest one, the situation is a bit
1278
- // more complex. We first need to update the L and REV# records with the new
1279
- // values of *only entry-level* meta fields.
1280
- const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
1281
-
1282
- // 2.4 Update L record. Apart from updating the entry-level meta fields, we also need
1283
- // to change the status from "published" to "unpublished" (if the status is set to "published").
1284
- let latestRevisionStatus = latestStorageEntry.status;
1285
- if (latestRevisionStatus === CONTENT_ENTRY_STATUS.PUBLISHED) {
1286
- latestRevisionStatus = CONTENT_ENTRY_STATUS.UNPUBLISHED;
1287
- }
1288
- const latestStorageEntryFields = {
1289
- ...latestStorageEntry,
1290
- ...updatedEntryLevelMetaFields,
1291
- status: latestRevisionStatus
1292
- };
1293
- const latestStorageEntryLatestKeys = createEntryLatestKeys(latestStorageEntry);
1294
- entityBatch.put({
1295
- ...latestStorageEntryLatestKeys,
1296
- data: latestStorageEntryFields
1297
- });
1298
-
1299
- // 2.5 Update REV# record.
1300
- const latestStorageEntryRevisionKeys = createEntryRevisionKeys(latestStorageEntry);
1301
- entityBatch.put({
1302
- ...latestStorageEntryRevisionKeys,
1303
- data: latestStorageEntryFields
1304
- });
1305
-
1306
- // 2.6 Additionally, if we have a previously published entry, we need to mark it as unpublished.
1307
- // Note that we need to take re-publishing into account (same published revision being
1308
- // published again), in which case the below code does not apply. This is because the
1309
- // required updates were already applied above.
1310
- if (publishedStorageEntry) {
1311
- const isRepublishing = publishedStorageEntry.id === entry.id;
1312
- const publishedRevisionDifferentFromLatest = publishedRevisionId !== latestStorageEntry.id;
1313
- if (!isRepublishing && publishedRevisionDifferentFromLatest) {
1314
- const publishedStorageEntryRevisionKeys = createEntryRevisionKeys(publishedStorageEntry);
1315
- entityBatch.put({
1316
- ...publishedStorageEntryRevisionKeys,
1317
- data: {
1318
- ...publishedStorageEntry,
1319
- status: CONTENT_ENTRY_STATUS.UNPUBLISHED
921
+ if (!latestEsEntry) throw new WebinyError('Could not publish entry. Could not load latest ("L") record (ES table).', "PUBLISH_ERROR", {
922
+ entry
923
+ });
924
+ const [latestStorageEntry] = await dataLoaders.getLatestRevisionByEntryId({
925
+ model,
926
+ ids: [
927
+ entry.id
928
+ ]
929
+ });
930
+ if (!latestStorageEntry) throw new WebinyError('Could not publish entry. Could not load latest ("L") record.', "PUBLISH_ERROR", {
931
+ entry
932
+ });
933
+ const [publishedStorageEntry] = await dataLoaders.getPublishedRevisionByEntryId({
934
+ model,
935
+ ids: [
936
+ entry.id
937
+ ]
938
+ });
939
+ const entityBatch = entity.createEntityWriter({
940
+ put: [
941
+ {
942
+ ...revisionKeys,
943
+ data: storageEntry
944
+ },
945
+ {
946
+ ...publishedKeys,
947
+ data: storageEntry
948
+ }
949
+ ]
950
+ });
951
+ const elasticsearchEntityWriter = esEntity.createEntityWriter();
952
+ const { index: esIndex } = configurations.es({
953
+ model
954
+ });
955
+ const publishedRevisionId = publishedStorageEntry?.id;
956
+ const publishingLatestRevision = latestStorageEntry?.id === entry.id;
957
+ if (publishingLatestRevision) {
958
+ entityBatch.put({
959
+ ...latestKeys,
960
+ data: storageEntry
961
+ });
962
+ if (publishedStorageEntry) {
963
+ const isRepublishing = publishedStorageEntry.id === entry.id;
964
+ if (!isRepublishing) {
965
+ const publishedStorageEntryKeys = createEntryRevisionKeys(publishedStorageEntry);
966
+ entityBatch.put({
967
+ ...publishedStorageEntryKeys,
968
+ data: {
969
+ ...publishedStorageEntry,
970
+ status: CONTENT_ENTRY_STATUS.UNPUBLISHED
971
+ }
972
+ });
973
+ }
974
+ }
975
+ } else {
976
+ const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
977
+ let latestRevisionStatus = latestStorageEntry.status;
978
+ if (latestRevisionStatus === CONTENT_ENTRY_STATUS.PUBLISHED) latestRevisionStatus = CONTENT_ENTRY_STATUS.UNPUBLISHED;
979
+ const latestStorageEntryFields = {
980
+ ...latestStorageEntry,
981
+ ...updatedEntryLevelMetaFields,
982
+ status: latestRevisionStatus
983
+ };
984
+ const latestStorageEntryLatestKeys = createEntryLatestKeys(latestStorageEntry);
985
+ entityBatch.put({
986
+ ...latestStorageEntryLatestKeys,
987
+ data: latestStorageEntryFields
988
+ });
989
+ const latestStorageEntryRevisionKeys = createEntryRevisionKeys(latestStorageEntry);
990
+ entityBatch.put({
991
+ ...latestStorageEntryRevisionKeys,
992
+ data: latestStorageEntryFields
993
+ });
994
+ if (publishedStorageEntry) {
995
+ const isRepublishing = publishedStorageEntry.id === entry.id;
996
+ const publishedRevisionDifferentFromLatest = publishedRevisionId !== latestStorageEntry.id;
997
+ if (!isRepublishing && publishedRevisionDifferentFromLatest) {
998
+ const publishedStorageEntryRevisionKeys = createEntryRevisionKeys(publishedStorageEntry);
999
+ entityBatch.put({
1000
+ ...publishedStorageEntryRevisionKeys,
1001
+ data: {
1002
+ ...publishedStorageEntry,
1003
+ status: CONTENT_ENTRY_STATUS.UNPUBLISHED
1004
+ }
1005
+ });
1006
+ }
1320
1007
  }
1321
- });
1322
1008
  }
1323
- }
1324
- }
1325
-
1326
- // 3. Update records in ES -> DDB table.
1327
-
1328
- /**
1329
- * Update the published revision entry in ES.
1330
- */
1331
- const esPublishedData = await transformer.getElasticsearchPublishedEntryData();
1332
- elasticsearchEntityWriter.put({
1333
- ...publishedKeys,
1334
- index: esIndex,
1335
- data: esPublishedData
1336
- });
1337
-
1338
- /**
1339
- * Need to decompress the data from Elasticsearch DynamoDB table.
1340
- *
1341
- * No need to transform it for the storage because it was fetched
1342
- * directly from the Elasticsearch table, where it sits transformed.
1343
- */
1344
- const latestEsEntryDataDecompressed = await compressionHandler.decompress(latestEsEntry.data);
1345
- if (publishingLatestRevision) {
1346
- const updatedMetaFields = pickEntryMetaFields(entry);
1347
- const latestTransformer = createTransformer({
1348
- valuesModifiers,
1349
- model,
1350
- transformedToIndex: {
1351
- ...latestEsEntryDataDecompressed,
1352
- status: CONTENT_ENTRY_STATUS.PUBLISHED,
1353
- locked: true,
1354
- ...updatedMetaFields
1355
- },
1356
- fieldRegistry,
1357
- fieldIndexRegistry,
1358
- compressionHandler
1359
- });
1360
- const esEntryLatestKeys = createEntryLatestKeys(latestEsEntryDataDecompressed);
1361
- elasticsearchEntityWriter.put({
1362
- index: esIndex,
1363
- data: await latestTransformer.getElasticsearchLatestEntryData(),
1364
- ...esEntryLatestKeys
1365
- });
1366
- } else {
1367
- const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
1368
-
1369
- /**
1370
- * Update the Elasticsearch table to propagate changes to the Elasticsearch.
1371
- */
1372
- const latestEsEntry = await esEntity.getClean(latestKeys);
1373
- if (latestEsEntry) {
1009
+ const esPublishedData = await transformer.getElasticsearchPublishedEntryData();
1010
+ elasticsearchEntityWriter.put({
1011
+ ...publishedKeys,
1012
+ index: esIndex,
1013
+ data: esPublishedData
1014
+ });
1374
1015
  const latestEsEntryDataDecompressed = await compressionHandler.decompress(latestEsEntry.data);
1375
- let latestRevisionStatus = latestEsEntryDataDecompressed.status;
1376
- if (latestRevisionStatus === CONTENT_ENTRY_STATUS.PUBLISHED) {
1377
- latestRevisionStatus = CONTENT_ENTRY_STATUS.UNPUBLISHED;
1016
+ if (publishingLatestRevision) {
1017
+ const updatedMetaFields = pickEntryMetaFields(entry);
1018
+ const latestTransformer = createTransformer({
1019
+ valuesModifiers,
1020
+ model,
1021
+ transformedToIndex: {
1022
+ ...latestEsEntryDataDecompressed,
1023
+ status: CONTENT_ENTRY_STATUS.PUBLISHED,
1024
+ locked: true,
1025
+ ...updatedMetaFields
1026
+ },
1027
+ fieldRegistry,
1028
+ fieldIndexRegistry,
1029
+ compressionHandler
1030
+ });
1031
+ const esEntryLatestKeys = createEntryLatestKeys(latestEsEntryDataDecompressed);
1032
+ elasticsearchEntityWriter.put({
1033
+ index: esIndex,
1034
+ data: await latestTransformer.getElasticsearchLatestEntryData(),
1035
+ ...esEntryLatestKeys
1036
+ });
1037
+ } else {
1038
+ const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
1039
+ const latestEsEntry = await esEntity.getClean(latestKeys);
1040
+ if (latestEsEntry) {
1041
+ const latestEsEntryDataDecompressed = await compressionHandler.decompress(latestEsEntry.data);
1042
+ let latestRevisionStatus = latestEsEntryDataDecompressed.status;
1043
+ if (latestRevisionStatus === CONTENT_ENTRY_STATUS.PUBLISHED) latestRevisionStatus = CONTENT_ENTRY_STATUS.UNPUBLISHED;
1044
+ const updatedLatestEntry = await compressionHandler.compress({
1045
+ ...latestEsEntryDataDecompressed,
1046
+ ...updatedEntryLevelMetaFields,
1047
+ status: latestRevisionStatus
1048
+ });
1049
+ elasticsearchEntityWriter.put({
1050
+ ...latestKeys,
1051
+ index: esIndex,
1052
+ data: updatedLatestEntry
1053
+ });
1054
+ }
1055
+ }
1056
+ try {
1057
+ await entityBatch.execute();
1058
+ dataLoaders.clearAll({
1059
+ model
1060
+ });
1061
+ } catch (ex) {
1062
+ throw new WebinyError(ex.message || "Could not store publish entry records in DynamoDB table.", ex.code || "PUBLISH_ERROR", {
1063
+ error: ex,
1064
+ entry,
1065
+ latestStorageEntry,
1066
+ publishedStorageEntry
1067
+ });
1068
+ }
1069
+ try {
1070
+ await elasticsearchEntityWriter.execute();
1071
+ } catch (ex) {
1072
+ throw new WebinyError(ex.message || "Could not store publish entry records in DynamoDB Elasticsearch table.", ex.code || "PUBLISH_ES_ERROR", {
1073
+ error: ex,
1074
+ entry,
1075
+ latestStorageEntry,
1076
+ publishedStorageEntry
1077
+ });
1378
1078
  }
1379
- const updatedLatestEntry = await compressionHandler.compress({
1380
- ...latestEsEntryDataDecompressed,
1381
- ...updatedEntryLevelMetaFields,
1382
- status: latestRevisionStatus
1079
+ return initialStorageEntry;
1080
+ };
1081
+ const unpublish = async (initialModel, params)=>{
1082
+ const { entry: initialEntry, storageEntry: initialStorageEntry } = params;
1083
+ const model = getStorageOperationsModel(initialModel);
1084
+ const transformer = createTransformer({
1085
+ valuesModifiers,
1086
+ model,
1087
+ entry: initialEntry,
1088
+ storageEntry: initialStorageEntry,
1089
+ fieldRegistry,
1090
+ fieldIndexRegistry,
1091
+ compressionHandler
1383
1092
  });
1384
- elasticsearchEntityWriter.put({
1385
- ...latestKeys,
1386
- index: esIndex,
1387
- data: updatedLatestEntry
1093
+ const { entry, storageEntry } = await transformer.transformEntryKeys();
1094
+ const [latestStorageEntry] = await dataLoaders.getLatestRevisionByEntryId({
1095
+ model,
1096
+ ids: [
1097
+ entry.id
1098
+ ]
1388
1099
  });
1389
- }
1390
- }
1391
-
1392
- /**
1393
- * Finally, execute regular table batch.
1394
- */
1395
- try {
1396
- await entityBatch.execute();
1397
- dataLoaders.clearAll({
1398
- model
1399
- });
1400
- } catch (ex) {
1401
- throw new WebinyError(ex.message || "Could not store publish entry records in DynamoDB table.", ex.code || "PUBLISH_ERROR", {
1402
- error: ex,
1403
- entry,
1404
- latestStorageEntry,
1405
- publishedStorageEntry
1406
- });
1407
- }
1408
- /**
1409
- * And Elasticsearch table batch.
1410
- */
1411
- try {
1412
- await elasticsearchEntityWriter.execute();
1413
- } catch (ex) {
1414
- throw new WebinyError(ex.message || "Could not store publish entry records in DynamoDB Elasticsearch table.", ex.code || "PUBLISH_ES_ERROR", {
1415
- error: ex,
1416
- entry,
1417
- latestStorageEntry,
1418
- publishedStorageEntry
1419
- });
1420
- }
1421
- return initialStorageEntry;
1422
- };
1423
- const unpublish = async (initialModel, params) => {
1424
- const {
1425
- entry: initialEntry,
1426
- storageEntry: initialStorageEntry
1427
- } = params;
1428
- const model = getStorageOperationsModel(initialModel);
1429
- const transformer = createTransformer({
1430
- valuesModifiers,
1431
- model,
1432
- entry: initialEntry,
1433
- storageEntry: initialStorageEntry,
1434
- fieldRegistry,
1435
- fieldIndexRegistry,
1436
- compressionHandler
1437
- });
1438
- const {
1439
- entry,
1440
- storageEntry
1441
- } = await transformer.transformEntryKeys();
1442
-
1443
- /**
1444
- * We need the latest entry to check if it needs to be updated.
1445
- */
1446
- const [latestStorageEntry] = await dataLoaders.getLatestRevisionByEntryId({
1447
- model,
1448
- ids: [entry.id]
1449
- });
1450
- const partitionKey = createPartitionKey({
1451
- id: entry.id,
1452
- tenant: model.tenant
1453
- });
1454
- const entryRevisionKeys = createEntryRevisionKeys(entry);
1455
- const entityBatch = entity.createEntityWriter({
1456
- put: [{
1457
- ...entryRevisionKeys,
1458
- data: storageEntry
1459
- }],
1460
- delete: [{
1461
- PK: partitionKey,
1462
- SK: createPublishedSortKey()
1463
- }]
1464
- });
1465
- const elasticsearchEntityBatch = esEntity.createEntityWriter({
1466
- delete: [{
1467
- PK: partitionKey,
1468
- SK: createPublishedSortKey()
1469
- }]
1470
- });
1471
-
1472
- /**
1473
- * If we are unpublishing the latest revision, let's also update the latest revision entry's status in both DynamoDB tables.
1474
- */
1475
- if (latestStorageEntry?.id === entry.id) {
1476
- const {
1477
- index
1478
- } = configurations.es({
1479
- model
1480
- });
1481
- const entryLatestKeys = createEntryLatestKeys(storageEntry);
1482
- entityBatch.put({
1483
- ...entryLatestKeys,
1484
- data: storageEntry
1485
- });
1486
- const esLatestData = await transformer.getElasticsearchLatestEntryData();
1487
- elasticsearchEntityBatch.put({
1488
- index,
1489
- data: esLatestData,
1490
- ...entryLatestKeys
1491
- });
1492
- }
1493
-
1494
- /**
1495
- * Finally, execute regular table batch.
1496
- */
1497
- try {
1498
- await entityBatch.execute();
1499
- dataLoaders.clearAll({
1500
- model
1501
- });
1502
- } catch (ex) {
1503
- throw new WebinyError(ex.message || "Could not store unpublished entry records in DynamoDB table.", ex.code || "UNPUBLISH_ERROR", {
1504
- entry,
1505
- storageEntry
1506
- });
1507
- }
1508
- /**
1509
- * And Elasticsearch table batch.
1510
- */
1511
- try {
1512
- await elasticsearchEntityBatch.execute();
1513
- } catch (ex) {
1514
- throw new WebinyError(ex.message || "Could not store unpublished entry records in DynamoDB Elasticsearch table.", ex.code || "UNPUBLISH_ERROR", {
1515
- entry,
1516
- storageEntry
1517
- });
1518
- }
1519
- return initialStorageEntry;
1520
- };
1521
- const getLatestRevisionByEntryId = async (initialModel, params) => {
1522
- const model = getStorageOperationsModel(initialModel);
1523
- const [entry] = await dataLoaders.getLatestRevisionByEntryId({
1524
- model,
1525
- ids: [params.id]
1526
- });
1527
- if (!entry) {
1528
- return null;
1529
- }
1530
- return convertEntryKeysFromStorage({
1531
- model,
1532
- entry
1533
- });
1534
- };
1535
- const getPublishedRevisionByEntryId = async (initialModel, params) => {
1536
- const model = getStorageOperationsModel(initialModel);
1537
- const [entry] = await dataLoaders.getPublishedRevisionByEntryId({
1538
- model,
1539
- ids: [params.id]
1540
- });
1541
- if (!entry) {
1542
- return null;
1543
- }
1544
- return convertEntryKeysFromStorage({
1545
- model,
1546
- entry
1547
- });
1548
- };
1549
- const getRevisionById = async (initialModel, params) => {
1550
- const model = getStorageOperationsModel(initialModel);
1551
- const [entry] = await dataLoaders.getRevisionById({
1552
- model,
1553
- ids: [params.id]
1554
- });
1555
- if (!entry) {
1556
- return null;
1557
- }
1558
- return convertEntryKeysFromStorage({
1559
- model,
1560
- entry
1561
- });
1562
- };
1563
- const getRevisions = async (initialModel, params) => {
1564
- const model = getStorageOperationsModel(initialModel);
1565
- const entries = await dataLoaders.getAllEntryRevisions({
1566
- model,
1567
- ids: [params.id]
1568
- });
1569
- return entries.map(entry => {
1570
- return convertEntryKeysFromStorage({
1571
- model,
1572
- entry
1573
- });
1574
- });
1575
- };
1576
- const getByIds = async (initialModel, params) => {
1577
- const model = getStorageOperationsModel(initialModel);
1578
- const entries = await dataLoaders.getRevisionById({
1579
- model,
1580
- ids: params.ids
1581
- });
1582
- return entries.map(entry => {
1583
- return convertEntryKeysFromStorage({
1584
- model,
1585
- entry
1586
- });
1587
- });
1588
- };
1589
- const getLatestByIds = async (initialModel, params) => {
1590
- const model = getStorageOperationsModel(initialModel);
1591
- const entries = await dataLoaders.getLatestRevisionByEntryId({
1592
- model,
1593
- ids: params.ids
1594
- });
1595
- return entries.map(entry => {
1596
- return convertEntryKeysFromStorage({
1597
- model,
1598
- entry
1599
- });
1600
- });
1601
- };
1602
- const getPublishedByIds = async (initialModel, params) => {
1603
- const model = getStorageOperationsModel(initialModel);
1604
- const entries = await dataLoaders.getPublishedRevisionByEntryId({
1605
- model,
1606
- ids: params.ids
1607
- });
1608
- return entries.map(entry => {
1609
- return convertEntryKeysFromStorage({
1610
- model,
1611
- entry
1612
- });
1613
- });
1614
- };
1615
- const getPreviousRevision = async (initialModel, params) => {
1616
- const model = getStorageOperationsModel(initialModel);
1617
- const {
1618
- tenant
1619
- } = model;
1620
- const {
1621
- entryId,
1622
- version
1623
- } = params;
1624
- const partitionKey = createPartitionKey({
1625
- tenant,
1626
- id: entryId
1627
- });
1628
- const options = {
1629
- beginsWith: `REV#`,
1630
- reverse: true
1100
+ const partitionKey = createPartitionKey({
1101
+ id: entry.id,
1102
+ tenant: model.tenant
1103
+ });
1104
+ const entryRevisionKeys = createEntryRevisionKeys(entry);
1105
+ const entityBatch = entity.createEntityWriter({
1106
+ put: [
1107
+ {
1108
+ ...entryRevisionKeys,
1109
+ data: storageEntry
1110
+ }
1111
+ ],
1112
+ delete: [
1113
+ {
1114
+ PK: partitionKey,
1115
+ SK: createPublishedSortKey()
1116
+ }
1117
+ ]
1118
+ });
1119
+ const elasticsearchEntityBatch = esEntity.createEntityWriter({
1120
+ delete: [
1121
+ {
1122
+ PK: partitionKey,
1123
+ SK: createPublishedSortKey()
1124
+ }
1125
+ ]
1126
+ });
1127
+ if (latestStorageEntry?.id === entry.id) {
1128
+ const { index } = configurations.es({
1129
+ model
1130
+ });
1131
+ const entryLatestKeys = createEntryLatestKeys(storageEntry);
1132
+ entityBatch.put({
1133
+ ...entryLatestKeys,
1134
+ data: storageEntry
1135
+ });
1136
+ const esLatestData = await transformer.getElasticsearchLatestEntryData();
1137
+ elasticsearchEntityBatch.put({
1138
+ index,
1139
+ data: esLatestData,
1140
+ ...entryLatestKeys
1141
+ });
1142
+ }
1143
+ try {
1144
+ await entityBatch.execute();
1145
+ dataLoaders.clearAll({
1146
+ model
1147
+ });
1148
+ } catch (ex) {
1149
+ throw new WebinyError(ex.message || "Could not store unpublished entry records in DynamoDB table.", ex.code || "UNPUBLISH_ERROR", {
1150
+ entry,
1151
+ storageEntry
1152
+ });
1153
+ }
1154
+ try {
1155
+ await elasticsearchEntityBatch.execute();
1156
+ } catch (ex) {
1157
+ throw new WebinyError(ex.message || "Could not store unpublished entry records in DynamoDB Elasticsearch table.", ex.code || "UNPUBLISH_ERROR", {
1158
+ entry,
1159
+ storageEntry
1160
+ });
1161
+ }
1162
+ return initialStorageEntry;
1631
1163
  };
1632
- try {
1633
- const unfilteredEntries = (await entity.queryAll({
1634
- partitionKey,
1635
- options
1636
- })).map(item => {
1637
- return item.data;
1638
- });
1639
- const entries = unfilteredEntries.filter(item => {
1640
- return item.version < version;
1641
- });
1642
- const entry = entries[0];
1643
- if (!entry) {
1644
- return null;
1645
- }
1646
- return convertEntryKeysFromStorage({
1647
- entry,
1648
- model
1649
- });
1650
- } catch (ex) {
1651
- throw new WebinyError(ex.message || "Could not get previous version of given entry.", ex.code || "GET_PREVIOUS_VERSION_ERROR", {
1652
- ...params,
1653
- error: ex,
1654
- partitionKey,
1655
- options,
1656
- model
1657
- });
1658
- }
1659
- };
1660
- const getUniqueFieldValues = async (model, params) => {
1661
- const {
1662
- where,
1663
- fieldId
1664
- } = params;
1665
- const {
1666
- index
1667
- } = configurations.es({
1668
- model
1669
- });
1670
- const initialBody = createElasticsearchBody({
1671
- model,
1672
- fieldRegistry,
1673
- fieldIndexRegistry,
1674
- bodyModifiers,
1675
- sortModifiers,
1676
- queryModifiers,
1677
- valueSearchRegistry,
1678
- fullTextSearches,
1679
- filterRegistry,
1680
- params: {
1681
- limit: 1,
1682
- where
1683
- },
1684
- plugins
1685
- });
1686
- const field = model.fields.find(f => f.fieldId === fieldId);
1687
- if (!field) {
1688
- throw new WebinyError(`Could not find field with given "fieldId" value.`, "FIELD_NOT_FOUND", {
1689
- fieldId
1690
- });
1691
- }
1692
- const body = {
1693
- ...initialBody,
1694
- /**
1695
- * We do not need any hits returned, we only need the aggregations.
1696
- */
1697
- size: 0,
1698
- aggregations: {
1699
- getUniqueFieldValues: {
1700
- terms: {
1701
- field: `values.${field.storageId}.keyword`,
1702
- size: 1000000
1703
- }
1164
+ const getLatestRevisionByEntryId = async (initialModel, params)=>{
1165
+ const model = getStorageOperationsModel(initialModel);
1166
+ const [entry] = await dataLoaders.getLatestRevisionByEntryId({
1167
+ model,
1168
+ ids: [
1169
+ params.id
1170
+ ]
1171
+ });
1172
+ if (!entry) return null;
1173
+ return convertEntryKeysFromStorage({
1174
+ model,
1175
+ entry
1176
+ });
1177
+ };
1178
+ const getPublishedRevisionByEntryId = async (initialModel, params)=>{
1179
+ const model = getStorageOperationsModel(initialModel);
1180
+ const [entry] = await dataLoaders.getPublishedRevisionByEntryId({
1181
+ model,
1182
+ ids: [
1183
+ params.id
1184
+ ]
1185
+ });
1186
+ if (!entry) return null;
1187
+ return convertEntryKeysFromStorage({
1188
+ model,
1189
+ entry
1190
+ });
1191
+ };
1192
+ const getRevisionById = async (initialModel, params)=>{
1193
+ const model = getStorageOperationsModel(initialModel);
1194
+ const [entry] = await dataLoaders.getRevisionById({
1195
+ model,
1196
+ ids: [
1197
+ params.id
1198
+ ]
1199
+ });
1200
+ if (!entry) return null;
1201
+ return convertEntryKeysFromStorage({
1202
+ model,
1203
+ entry
1204
+ });
1205
+ };
1206
+ const getRevisions = async (initialModel, params)=>{
1207
+ const model = getStorageOperationsModel(initialModel);
1208
+ const entries = await dataLoaders.getAllEntryRevisions({
1209
+ model,
1210
+ ids: [
1211
+ params.id
1212
+ ]
1213
+ });
1214
+ return entries.map((entry)=>convertEntryKeysFromStorage({
1215
+ model,
1216
+ entry
1217
+ }));
1218
+ };
1219
+ const getByIds = async (initialModel, params)=>{
1220
+ const model = getStorageOperationsModel(initialModel);
1221
+ const entries = await dataLoaders.getRevisionById({
1222
+ model,
1223
+ ids: params.ids
1224
+ });
1225
+ return entries.map((entry)=>convertEntryKeysFromStorage({
1226
+ model,
1227
+ entry
1228
+ }));
1229
+ };
1230
+ const getLatestByIds = async (initialModel, params)=>{
1231
+ const model = getStorageOperationsModel(initialModel);
1232
+ const entries = await dataLoaders.getLatestRevisionByEntryId({
1233
+ model,
1234
+ ids: params.ids
1235
+ });
1236
+ return entries.map((entry)=>convertEntryKeysFromStorage({
1237
+ model,
1238
+ entry
1239
+ }));
1240
+ };
1241
+ const getPublishedByIds = async (initialModel, params)=>{
1242
+ const model = getStorageOperationsModel(initialModel);
1243
+ const entries = await dataLoaders.getPublishedRevisionByEntryId({
1244
+ model,
1245
+ ids: params.ids
1246
+ });
1247
+ return entries.map((entry)=>convertEntryKeysFromStorage({
1248
+ model,
1249
+ entry
1250
+ }));
1251
+ };
1252
+ const getPreviousRevision = async (initialModel, params)=>{
1253
+ const model = getStorageOperationsModel(initialModel);
1254
+ const { tenant } = model;
1255
+ const { entryId, version } = params;
1256
+ const partitionKey = createPartitionKey({
1257
+ tenant,
1258
+ id: entryId
1259
+ });
1260
+ const options = {
1261
+ beginsWith: "REV#",
1262
+ reverse: true
1263
+ };
1264
+ try {
1265
+ const unfilteredEntries = (await entity.queryAll({
1266
+ partitionKey,
1267
+ options
1268
+ })).map((item)=>item.data);
1269
+ const entries = unfilteredEntries.filter((item)=>item.version < version);
1270
+ const entry = entries[0];
1271
+ if (!entry) return null;
1272
+ return convertEntryKeysFromStorage({
1273
+ entry,
1274
+ model
1275
+ });
1276
+ } catch (ex) {
1277
+ throw new WebinyError(ex.message || "Could not get previous version of given entry.", ex.code || "GET_PREVIOUS_VERSION_ERROR", {
1278
+ ...params,
1279
+ error: ex,
1280
+ partitionKey,
1281
+ options,
1282
+ model
1283
+ });
1704
1284
  }
1705
- }
1706
1285
  };
1707
- let response = undefined;
1708
- try {
1709
- response = await elasticsearch.search({
1710
- index,
1711
- body
1712
- });
1713
- } catch (error) {
1714
- if (shouldIgnoreEsResponseError(error)) {
1715
- return [];
1716
- }
1717
- throw new WebinyError(error.message || "Error in the Elasticsearch query.", error.code || "OPENSEARCH_ERROR", {
1718
- error,
1719
- index,
1720
- model,
1721
- body
1722
- });
1723
- }
1724
- const aggregations = response.body.aggregations || {};
1725
- const agg = aggregations["getUniqueFieldValues"];
1726
- const buckets = agg && "buckets" in agg && Array.isArray(agg.buckets) ? agg.buckets : [];
1727
- return buckets.map(bucket => {
1728
- return {
1729
- value: bucket.key,
1730
- count: bucket.doc_count
1731
- };
1732
- });
1733
- };
1734
- return {
1735
- create,
1736
- createRevisionFrom,
1737
- update,
1738
- move,
1739
- delete: deleteEntry,
1740
- moveToBin,
1741
- restoreFromBin,
1742
- deleteRevision,
1743
- deleteMultipleEntries,
1744
- get,
1745
- publish,
1746
- unpublish,
1747
- list,
1748
- getLatestRevisionByEntryId,
1749
- getPublishedRevisionByEntryId,
1750
- getRevisionById,
1751
- getRevisions,
1752
- getByIds,
1753
- getLatestByIds,
1754
- getPublishedByIds,
1755
- getPreviousRevision,
1756
- getUniqueFieldValues,
1757
- dataLoaders
1758
- };
1286
+ const getUniqueFieldValues = async (model, params)=>{
1287
+ const { where, fieldId } = params;
1288
+ const { index } = configurations.es({
1289
+ model
1290
+ });
1291
+ const initialBody = createElasticsearchBody({
1292
+ model,
1293
+ fieldRegistry,
1294
+ fieldIndexRegistry,
1295
+ bodyModifiers,
1296
+ sortModifiers,
1297
+ queryModifiers,
1298
+ valueSearchRegistry,
1299
+ fullTextSearches,
1300
+ filterRegistry,
1301
+ params: {
1302
+ limit: 1,
1303
+ where
1304
+ },
1305
+ plugins
1306
+ });
1307
+ const field = model.fields.find((f)=>f.fieldId === fieldId);
1308
+ if (!field) throw new WebinyError('Could not find field with given "fieldId" value.', "FIELD_NOT_FOUND", {
1309
+ fieldId
1310
+ });
1311
+ const body = {
1312
+ ...initialBody,
1313
+ size: 0,
1314
+ aggregations: {
1315
+ getUniqueFieldValues: {
1316
+ terms: {
1317
+ field: `values.${field.storageId}.keyword`,
1318
+ size: 1000000
1319
+ }
1320
+ }
1321
+ }
1322
+ };
1323
+ let response;
1324
+ try {
1325
+ response = await elasticsearch.search({
1326
+ index,
1327
+ body
1328
+ });
1329
+ } catch (error) {
1330
+ if (shouldIgnoreEsResponseError(error)) return [];
1331
+ throw new WebinyError(error.message || "Error in the Elasticsearch query.", error.code || "OPENSEARCH_ERROR", {
1332
+ error,
1333
+ index,
1334
+ model,
1335
+ body
1336
+ });
1337
+ }
1338
+ const aggregations = response.body.aggregations || {};
1339
+ const agg = aggregations["getUniqueFieldValues"];
1340
+ const buckets = agg && "buckets" in agg && Array.isArray(agg.buckets) ? agg.buckets : [];
1341
+ return buckets.map((bucket)=>({
1342
+ value: bucket.key,
1343
+ count: bucket.doc_count
1344
+ }));
1345
+ };
1346
+ return {
1347
+ create,
1348
+ createRevisionFrom,
1349
+ update,
1350
+ move,
1351
+ delete: deleteEntry,
1352
+ moveToBin,
1353
+ restoreFromBin,
1354
+ deleteRevision,
1355
+ deleteMultipleEntries,
1356
+ get,
1357
+ publish,
1358
+ unpublish,
1359
+ list,
1360
+ getLatestRevisionByEntryId,
1361
+ getPublishedRevisionByEntryId,
1362
+ getRevisionById,
1363
+ getRevisions,
1364
+ getByIds,
1365
+ getLatestByIds,
1366
+ getPublishedByIds,
1367
+ getPreviousRevision,
1368
+ getUniqueFieldValues,
1369
+ dataLoaders
1370
+ };
1759
1371
  };
1372
+ export { createEntriesStorageOperations };
1760
1373
 
1761
1374
  //# sourceMappingURL=index.js.map