@webiny/api-headless-cms-ddb 0.0.0-unstable.b14eaecf38 → 0.0.0-unstable.b6d7105cee

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 (165) hide show
  1. package/README.md +6 -20
  2. package/definitions/entry.d.ts +4 -5
  3. package/definitions/entry.js +10 -93
  4. package/definitions/entry.js.map +1 -1
  5. package/definitions/group.d.ts +4 -5
  6. package/definitions/group.js +10 -64
  7. package/definitions/group.js.map +1 -1
  8. package/definitions/model.d.ts +4 -5
  9. package/definitions/model.js +10 -108
  10. package/definitions/model.js.map +1 -1
  11. package/definitions/table.d.ts +4 -6
  12. package/definitions/table.js +7 -26
  13. package/definitions/table.js.map +1 -1
  14. package/definitions/types.d.ts +65 -0
  15. package/definitions/types.js +0 -0
  16. package/dynamoDb/index.d.ts +1 -1
  17. package/dynamoDb/index.js +8 -12
  18. package/dynamoDb/index.js.map +1 -1
  19. package/index.d.ts +2 -3
  20. package/index.js +87 -128
  21. package/index.js.map +1 -1
  22. package/operations/entry/dataLoader/DataLoaderCache.d.ts +16 -0
  23. package/operations/entry/dataLoader/DataLoaderCache.js +27 -0
  24. package/operations/entry/dataLoader/DataLoaderCache.js.map +1 -0
  25. package/operations/entry/dataLoader/constants.d.ts +1 -0
  26. package/operations/entry/dataLoader/constants.js +5 -0
  27. package/operations/entry/dataLoader/constants.js.map +1 -0
  28. package/operations/entry/dataLoader/createBatchScheduleFn.d.ts +8 -0
  29. package/operations/entry/dataLoader/createBatchScheduleFn.js +10 -0
  30. package/operations/entry/dataLoader/createBatchScheduleFn.js.map +1 -0
  31. package/operations/entry/dataLoader/getAllEntryRevisions.d.ts +4 -0
  32. package/operations/entry/dataLoader/getAllEntryRevisions.js +24 -0
  33. package/operations/entry/dataLoader/getAllEntryRevisions.js.map +1 -0
  34. package/operations/entry/dataLoader/getLatestRevisionByEntryId.d.ts +4 -0
  35. package/operations/entry/dataLoader/getLatestRevisionByEntryId.js +40 -0
  36. package/operations/entry/dataLoader/getLatestRevisionByEntryId.js.map +1 -0
  37. package/operations/entry/dataLoader/getPublishedRevisionByEntryId.d.ts +4 -0
  38. package/operations/entry/dataLoader/getPublishedRevisionByEntryId.js +40 -0
  39. package/operations/entry/dataLoader/getPublishedRevisionByEntryId.js.map +1 -0
  40. package/operations/entry/dataLoader/getRevisionById.d.ts +4 -0
  41. package/operations/entry/dataLoader/getRevisionById.js +42 -0
  42. package/operations/entry/dataLoader/getRevisionById.js.map +1 -0
  43. package/operations/entry/dataLoader/index.d.ts +8 -0
  44. package/operations/entry/dataLoader/index.js +18 -0
  45. package/operations/entry/dataLoader/index.js.map +1 -0
  46. package/operations/entry/dataLoader/types.d.ts +6 -0
  47. package/operations/entry/dataLoader/types.js +0 -0
  48. package/operations/entry/dataLoaders.d.ts +14 -30
  49. package/operations/entry/dataLoaders.js +84 -272
  50. package/operations/entry/dataLoaders.js.map +1 -1
  51. package/operations/entry/index.d.ts +5 -4
  52. package/operations/entry/index.js +899 -807
  53. package/operations/entry/index.js.map +1 -1
  54. package/operations/entry/keys.d.ts +46 -2
  55. package/operations/entry/keys.js +54 -49
  56. package/operations/entry/keys.js.map +1 -1
  57. package/operations/group/index.d.ts +4 -5
  58. package/operations/group/index.js +117 -158
  59. package/operations/group/index.js.map +1 -1
  60. package/operations/model/index.d.ts +3 -3
  61. package/operations/model/index.js +103 -134
  62. package/operations/model/index.js.map +1 -1
  63. package/package.json +32 -33
  64. package/plugins/index.d.ts +2 -4
  65. package/plugins/index.js +1 -49
  66. package/types.d.ts +25 -41
  67. package/types.js +8 -14
  68. package/types.js.map +1 -1
  69. package/definitions/settings.d.ts +0 -9
  70. package/definitions/settings.js +0 -53
  71. package/definitions/settings.js.map +0 -1
  72. package/definitions/system.d.ts +0 -9
  73. package/definitions/system.js +0 -41
  74. package/definitions/system.js.map +0 -1
  75. package/dynamoDb/path/plainObject.d.ts +0 -2
  76. package/dynamoDb/path/plainObject.js +0 -33
  77. package/dynamoDb/path/plainObject.js.map +0 -1
  78. package/dynamoDb/storage/date.d.ts +0 -3
  79. package/dynamoDb/storage/date.js +0 -91
  80. package/dynamoDb/storage/date.js.map +0 -1
  81. package/dynamoDb/storage/longText.d.ts +0 -10
  82. package/dynamoDb/storage/longText.js +0 -91
  83. package/dynamoDb/storage/longText.js.map +0 -1
  84. package/dynamoDb/storage/richText.d.ts +0 -2
  85. package/dynamoDb/storage/richText.js +0 -95
  86. package/dynamoDb/storage/richText.js.map +0 -1
  87. package/dynamoDb/transformValue/datetime.d.ts +0 -5
  88. package/dynamoDb/transformValue/datetime.js +0 -45
  89. package/dynamoDb/transformValue/datetime.js.map +0 -1
  90. package/operations/entry/filtering/createExpressions.d.ts +0 -26
  91. package/operations/entry/filtering/createExpressions.js +0 -176
  92. package/operations/entry/filtering/createExpressions.js.map +0 -1
  93. package/operations/entry/filtering/createFields.d.ts +0 -14
  94. package/operations/entry/filtering/createFields.js +0 -105
  95. package/operations/entry/filtering/createFields.js.map +0 -1
  96. package/operations/entry/filtering/extractSort.d.ts +0 -17
  97. package/operations/entry/filtering/extractSort.js +0 -67
  98. package/operations/entry/filtering/extractSort.js.map +0 -1
  99. package/operations/entry/filtering/filter.d.ts +0 -15
  100. package/operations/entry/filtering/filter.js +0 -143
  101. package/operations/entry/filtering/filter.js.map +0 -1
  102. package/operations/entry/filtering/fullTextSearch.d.ts +0 -14
  103. package/operations/entry/filtering/fullTextSearch.js +0 -48
  104. package/operations/entry/filtering/fullTextSearch.js.map +0 -1
  105. package/operations/entry/filtering/getValue.d.ts +0 -5
  106. package/operations/entry/filtering/getValue.js +0 -63
  107. package/operations/entry/filtering/getValue.js.map +0 -1
  108. package/operations/entry/filtering/index.d.ts +0 -2
  109. package/operations/entry/filtering/index.js +0 -19
  110. package/operations/entry/filtering/index.js.map +0 -1
  111. package/operations/entry/filtering/mapPlugins.d.ts +0 -8
  112. package/operations/entry/filtering/mapPlugins.js +0 -31
  113. package/operations/entry/filtering/mapPlugins.js.map +0 -1
  114. package/operations/entry/filtering/plugins/defaultFilterCreate.d.ts +0 -2
  115. package/operations/entry/filtering/plugins/defaultFilterCreate.js +0 -41
  116. package/operations/entry/filtering/plugins/defaultFilterCreate.js.map +0 -1
  117. package/operations/entry/filtering/plugins/index.d.ts +0 -1
  118. package/operations/entry/filtering/plugins/index.js +0 -13
  119. package/operations/entry/filtering/plugins/index.js.map +0 -1
  120. package/operations/entry/filtering/plugins/objectFilterCreate.d.ts +0 -2
  121. package/operations/entry/filtering/plugins/objectFilterCreate.js +0 -86
  122. package/operations/entry/filtering/plugins/objectFilterCreate.js.map +0 -1
  123. package/operations/entry/filtering/plugins/refFilterCreate.d.ts +0 -2
  124. package/operations/entry/filtering/plugins/refFilterCreate.js +0 -71
  125. package/operations/entry/filtering/plugins/refFilterCreate.js.map +0 -1
  126. package/operations/entry/filtering/sort.d.ts +0 -12
  127. package/operations/entry/filtering/sort.js +0 -69
  128. package/operations/entry/filtering/sort.js.map +0 -1
  129. package/operations/entry/filtering/systemFields.d.ts +0 -4
  130. package/operations/entry/filtering/systemFields.js +0 -70
  131. package/operations/entry/filtering/systemFields.js.map +0 -1
  132. package/operations/entry/filtering/transform.d.ts +0 -6
  133. package/operations/entry/filtering/transform.js +0 -16
  134. package/operations/entry/filtering/transform.js.map +0 -1
  135. package/operations/entry/filtering/types.d.ts +0 -40
  136. package/operations/entry/filtering/types.js +0 -5
  137. package/operations/entry/filtering/types.js.map +0 -1
  138. package/operations/entry/filtering/values.d.ts +0 -2
  139. package/operations/entry/filtering/values.js +0 -22
  140. package/operations/entry/filtering/values.js.map +0 -1
  141. package/operations/entry/filtering/where.d.ts +0 -5
  142. package/operations/entry/filtering/where.js +0 -32
  143. package/operations/entry/filtering/where.js.map +0 -1
  144. package/operations/entry/systemFields.d.ts +0 -2
  145. package/operations/entry/systemFields.js +0 -72
  146. package/operations/entry/systemFields.js.map +0 -1
  147. package/operations/settings/index.d.ts +0 -7
  148. package/operations/settings/index.js +0 -111
  149. package/operations/settings/index.js.map +0 -1
  150. package/operations/system/index.d.ts +0 -7
  151. package/operations/system/index.js +0 -82
  152. package/operations/system/index.js.map +0 -1
  153. package/plugins/CmsEntryFieldFilterPathPlugin.d.ts +0 -22
  154. package/plugins/CmsEntryFieldFilterPathPlugin.js +0 -41
  155. package/plugins/CmsEntryFieldFilterPathPlugin.js.map +0 -1
  156. package/plugins/CmsEntryFieldFilterPlugin.d.ts +0 -43
  157. package/plugins/CmsEntryFieldFilterPlugin.js +0 -24
  158. package/plugins/CmsEntryFieldFilterPlugin.js.map +0 -1
  159. package/plugins/CmsEntryFieldSortingPlugin.d.ts +0 -42
  160. package/plugins/CmsEntryFieldSortingPlugin.js +0 -28
  161. package/plugins/CmsEntryFieldSortingPlugin.js.map +0 -1
  162. package/plugins/CmsFieldFilterValueTransformPlugin.d.ts +0 -11
  163. package/plugins/CmsFieldFilterValueTransformPlugin.js +0 -24
  164. package/plugins/CmsFieldFilterValueTransformPlugin.js.map +0 -1
  165. package/plugins/index.js.map +0 -1
@@ -1,816 +1,908 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.createEntriesStorageOperations = void 0;
8
- var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
9
- var _error = _interopRequireDefault(require("@webiny/error"));
10
- var _dataLoaders = require("./dataLoaders");
11
- var _types = require("@webiny/api-headless-cms/types");
12
- var _keys = require("./keys");
13
- var _batchWrite = require("@webiny/db-dynamodb/utils/batchWrite");
14
- var _query = require("@webiny/db-dynamodb/utils/query");
15
- var _cleanup = require("@webiny/db-dynamodb/utils/cleanup");
16
- var _cursor = require("@webiny/utils/cursor");
17
- var _zeroPad = require("@webiny/utils/zeroPad");
18
- var _apiHeadlessCms = require("@webiny/api-headless-cms");
19
- var _createFields = require("./filtering/createFields");
20
- var _filtering = require("./filtering");
21
- const createType = () => {
22
- return "cms.entry";
23
- };
24
- const createLatestType = () => {
25
- return `${createType()}.l`;
26
- };
27
- const createPublishedType = () => {
28
- return `${createType()}.p`;
29
- };
30
- const convertToStorageEntry = params => {
31
- const {
32
- model,
33
- storageEntry
34
- } = params;
35
- const values = model.convertValueKeyToStorage({
36
- fields: model.fields,
37
- values: storageEntry.values
38
- });
39
- return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
40
- values
41
- });
42
- };
43
- const convertFromStorageEntry = params => {
44
- const {
45
- model,
46
- storageEntry
47
- } = params;
48
- const values = model.convertValueKeyFromStorage({
49
- fields: model.fields,
50
- values: storageEntry.values
51
- });
52
- return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
53
- values
54
- });
55
- };
56
- const createEntriesStorageOperations = params => {
57
- const {
58
- entity,
59
- plugins
60
- } = params;
61
- let storageOperationsCmsModelPlugin;
62
- const getStorageOperationsCmsModelPlugin = () => {
63
- if (storageOperationsCmsModelPlugin) {
64
- return storageOperationsCmsModelPlugin;
65
- }
66
- storageOperationsCmsModelPlugin = plugins.oneByType(_apiHeadlessCms.StorageOperationsCmsModelPlugin.type);
67
- return storageOperationsCmsModelPlugin;
68
- };
69
- const getStorageOperationsModel = model => {
70
- const plugin = getStorageOperationsCmsModelPlugin();
71
- return plugin.getModel(model);
72
- };
73
- const dataLoaders = new _dataLoaders.DataLoadersHandler({
74
- entity
75
- });
76
- const storageTransformPlugins = plugins.byType(_apiHeadlessCms.StorageTransformPlugin.type).reduce((collection, plugin) => {
77
- collection[plugin.fieldType] = plugin;
78
- return collection;
79
- }, {});
80
- const createStorageTransformCallable = model => {
81
- return (field, value) => {
82
- const plugin = storageTransformPlugins[field.type];
83
- if (!plugin) {
84
- return value;
85
- }
86
- return plugin.fromStorage({
87
- model,
88
- field,
89
- value,
90
- getStoragePlugin(fieldType) {
91
- return storageTransformPlugins[fieldType] || storageTransformPlugins["*"];
92
- },
93
- plugins
94
- });
95
- };
96
- };
97
- const create = async (initialModel, params) => {
98
- const {
99
- entry,
100
- storageEntry: initialStorageEntry
101
- } = params;
102
- const model = getStorageOperationsModel(initialModel);
103
- const partitionKey = (0, _keys.createPartitionKey)({
104
- id: entry.id,
105
- locale: model.locale,
106
- tenant: model.tenant
1
+ import error from "@webiny/error";
2
+ import { DataLoadersHandler } from "./dataLoaders.js";
3
+ import { CONTENT_ENTRY_STATUS } from "@webiny/api-headless-cms/types/index.js";
4
+ import { createEntryLatestKeys, createEntryPublishedKeys, createEntryRevisionKeys, createGSIPartitionKey, createPartitionKey, createPublishedSortKey, createRevisionSortKey } from "./keys.js";
5
+ import { decodeCursor, encodeCursor } from "@webiny/utils";
6
+ import { ValueFilterRegistry } from "@webiny/db-utils";
7
+ import { aggregateUniqueFieldValues, createFields, createStorageModelAccessor, createStorageTransformCallable, filter, sort } from "@webiny/api-headless-cms-storage";
8
+ import { isDeletedEntryMetaField, isEntryLevelEntryMetaField, isRestoredEntryMetaField, pickEntryMetaFields } from "@webiny/api-headless-cms/constants.js";
9
+ import { StorageTransformRegistry } from "@webiny/api-headless-cms/exports/api/cms/storage.js";
10
+ const convertToStorageEntry = (params)=>{
11
+ const { model, storageEntry } = params;
12
+ const values = model.convertValueKeyToStorage({
13
+ fields: model.fields,
14
+ values: storageEntry.values
107
15
  });
108
- const isPublished = entry.status === "published";
109
- const locked = isPublished ? true : entry.locked;
110
- const storageEntry = convertToStorageEntry({
111
- model,
112
- storageEntry: initialStorageEntry
113
- });
114
- /**
115
- * We need to:
116
- * - create new main entry item
117
- * - create new or update the latest entry item
118
- */
119
- const items = [entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
120
- locked,
121
- PK: partitionKey,
122
- SK: (0, _keys.createRevisionSortKey)(entry),
123
- TYPE: createType(),
124
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
125
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
126
- })), entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
127
- locked,
128
- PK: partitionKey,
129
- SK: (0, _keys.createLatestSortKey)(),
130
- TYPE: createLatestType(),
131
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
132
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
133
- }))];
134
-
135
- /**
136
- * We need to create published entry if
137
- */
138
- if (isPublished) {
139
- items.push(entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
140
- locked,
141
- PK: partitionKey,
142
- SK: (0, _keys.createPublishedSortKey)(),
143
- TYPE: createLatestType(),
144
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "P"),
145
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
146
- })));
147
- }
148
- try {
149
- await (0, _batchWrite.batchWriteAll)({
150
- table: entity.table,
151
- items
152
- });
153
- dataLoaders.clearAll({
154
- model
155
- });
156
- } catch (ex) {
157
- throw new _error.default(ex.message || "Could not insert data into the DynamoDB.", ex.code || "CREATE_ENTRY_ERROR", {
158
- error: ex,
159
- entry
160
- });
161
- }
162
- return initialStorageEntry;
163
- };
164
- const createRevisionFrom = async (initialModel, params) => {
165
- const {
166
- entry,
167
- storageEntry: initialStorageEntry
168
- } = params;
169
- const model = getStorageOperationsModel(initialModel);
170
- const partitionKey = (0, _keys.createPartitionKey)({
171
- id: entry.id,
172
- locale: model.locale,
173
- tenant: model.tenant
174
- });
175
- const storageEntry = convertToStorageEntry({
176
- storageEntry: initialStorageEntry,
177
- model
178
- });
179
- /**
180
- * We need to:
181
- * - create the main entry item
182
- * - update the last entry item to a current one
183
- */
184
- const items = [entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
185
- PK: partitionKey,
186
- SK: (0, _keys.createRevisionSortKey)(storageEntry),
187
- TYPE: createType(),
188
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
189
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
190
- })), entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
191
- PK: partitionKey,
192
- SK: (0, _keys.createLatestSortKey)(),
193
- TYPE: createLatestType(),
194
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
195
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
196
- }))];
197
- try {
198
- await (0, _batchWrite.batchWriteAll)({
199
- table: entity.table,
200
- items
201
- });
202
- dataLoaders.clearAll({
203
- model
204
- });
205
- } catch (ex) {
206
- throw new _error.default(ex.message || "Could not create revision from given entry.", ex.code || "CREATE_REVISION_ERROR", {
207
- error: ex,
208
- entry,
209
- storageEntry
210
- });
211
- }
212
- /**
213
- * There are no modifications on the entry created so just return the data.
214
- */
215
- return initialStorageEntry;
216
- };
217
- const update = async (initialModel, params) => {
218
- const {
219
- entry,
220
- storageEntry: initialStorageEntry
221
- } = params;
222
- const model = getStorageOperationsModel(initialModel);
223
- const partitionKey = (0, _keys.createPartitionKey)({
224
- id: entry.id,
225
- locale: model.locale,
226
- tenant: model.tenant
227
- });
228
- const isPublished = entry.status === "published";
229
- const locked = isPublished ? true : entry.locked;
230
- const items = [];
231
- const storageEntry = convertToStorageEntry({
232
- model,
233
- storageEntry: initialStorageEntry
234
- });
235
- /**
236
- * We need to:
237
- * - update the current entry
238
- * - update the latest entry if the current entry is the latest one
239
- */
240
- items.push(entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
241
- locked,
242
- PK: partitionKey,
243
- SK: (0, _keys.createRevisionSortKey)(storageEntry),
244
- TYPE: createType(),
245
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
246
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
247
- })));
248
- if (isPublished) {
249
- items.push(entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
250
- locked,
251
- PK: partitionKey,
252
- SK: (0, _keys.createPublishedSortKey)(),
253
- TYPE: createPublishedType(),
254
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "P"),
255
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
256
- })));
257
- }
258
-
259
- /**
260
- * We need the latest entry to update it as well if necessary.
261
- */
262
- const latestStorageEntry = await getLatestRevisionByEntryId(model, entry);
263
- if (latestStorageEntry && latestStorageEntry.id === entry.id) {
264
- items.push(entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
265
- locked,
266
- PK: partitionKey,
267
- SK: (0, _keys.createLatestSortKey)(),
268
- TYPE: createLatestType(),
269
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
270
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
271
- })));
272
- }
273
- try {
274
- await (0, _batchWrite.batchWriteAll)({
275
- table: entity.table,
276
- items
277
- });
278
- dataLoaders.clearAll({
279
- model
280
- });
281
- return initialStorageEntry;
282
- } catch (ex) {
283
- throw new _error.default(ex.message || "Could not update entry.", ex.code || "UPDATE_ERROR", {
284
- error: ex,
285
- entry,
286
- latestStorageEntry
287
- });
288
- }
289
- };
290
- const deleteEntry = async (initialModel, params) => {
291
- const {
292
- entry
293
- } = params;
294
- const model = getStorageOperationsModel(initialModel);
295
- const queryAllParams = {
296
- entity,
297
- partitionKey: (0, _keys.createPartitionKey)({
298
- id: entry.id,
299
- locale: model.locale,
300
- tenant: model.tenant
301
- }),
302
- options: {
303
- gte: " "
304
- }
16
+ return {
17
+ ...storageEntry,
18
+ values
305
19
  };
306
- let records = [];
307
- try {
308
- records = await (0, _query.queryAll)(queryAllParams);
309
- } catch (ex) {
310
- throw new _error.default(ex.message || "Could not load all records.", ex.code || "LOAD_ALL_RECORDS_ERROR", {
311
- error: ex,
312
- entry
313
- });
314
- }
315
- const items = records.map(item => {
316
- return entity.deleteBatch({
317
- PK: item.PK,
318
- SK: item.SK
319
- });
320
- });
321
- try {
322
- await (0, _batchWrite.batchWriteAll)({
323
- table: entity.table,
324
- items
325
- });
326
- dataLoaders.clearAll({
327
- model
328
- });
329
- } catch (ex) {
330
- throw new _error.default(ex.message || "Could not delete the entry.", ex.code || "DELETE_ENTRY_ERROR", {
331
- error: ex,
332
- partitionKey: queryAllParams.partitionKey,
333
- entry
334
- });
335
- }
336
- };
337
- const deleteRevision = async (initialModel, params) => {
338
- const {
339
- entry,
340
- latestEntry,
341
- latestStorageEntry: initialLatestStorageEntry
342
- } = params;
343
- const model = getStorageOperationsModel(initialModel);
344
- const partitionKey = (0, _keys.createPartitionKey)({
345
- id: entry.id,
346
- locale: model.locale,
347
- tenant: model.tenant
348
- });
349
- const items = [entity.deleteBatch({
350
- PK: partitionKey,
351
- SK: (0, _keys.createRevisionSortKey)(entry)
352
- })];
353
- const publishedStorageEntry = await getPublishedRevisionByEntryId(model, entry);
354
-
355
- /**
356
- * If revision we are deleting is the published one as well, we need to delete those records as well.
357
- */
358
- if (publishedStorageEntry && entry.id === publishedStorageEntry.id) {
359
- items.push(entity.deleteBatch({
360
- PK: partitionKey,
361
- SK: (0, _keys.createPublishedSortKey)()
362
- }));
363
- }
364
- if (initialLatestStorageEntry) {
365
- const latestStorageEntry = convertToStorageEntry({
366
- storageEntry: initialLatestStorageEntry,
367
- model
368
- });
369
- items.push(entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, latestStorageEntry), {}, {
370
- PK: partitionKey,
371
- SK: (0, _keys.createLatestSortKey)(),
372
- TYPE: createLatestType(),
373
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
374
- GSI1_SK: (0, _keys.createGSISortKey)(latestStorageEntry)
375
- })));
376
- }
377
- try {
378
- await (0, _batchWrite.batchWriteAll)({
379
- table: entity.table,
380
- items
381
- });
382
- dataLoaders.clearAll({
383
- model
384
- });
385
- } catch (ex) {
386
- throw new _error.default(ex.message, ex.code, {
387
- error: ex,
388
- entry,
389
- latestEntry
390
- });
391
- }
392
- };
393
- const getLatestRevisionByEntryId = async (initialModel, params) => {
394
- const model = getStorageOperationsModel(initialModel);
395
- const items = await dataLoaders.getLatestRevisionByEntryId({
396
- model,
397
- ids: [params.id]
398
- });
399
- const item = items.shift() || null;
400
- if (!item) {
401
- return null;
402
- }
403
- return convertFromStorageEntry({
404
- storageEntry: item,
405
- model
406
- });
407
- };
408
- const getPublishedRevisionByEntryId = async (initialModel, params) => {
409
- const model = getStorageOperationsModel(initialModel);
410
- const items = await dataLoaders.getPublishedRevisionByEntryId({
411
- model,
412
- ids: [params.id]
413
- });
414
- const item = items.shift() || null;
415
- if (!item) {
416
- return null;
417
- }
418
- return convertFromStorageEntry({
419
- storageEntry: item,
420
- model
421
- });
422
- };
423
- const getRevisionById = async (initialModel, params) => {
424
- const model = getStorageOperationsModel(initialModel);
425
- const items = await dataLoaders.getRevisionById({
426
- model,
427
- ids: [params.id]
428
- });
429
- const item = items.shift() || null;
430
- if (!item) {
431
- return null;
432
- }
433
- return convertFromStorageEntry({
434
- storageEntry: item,
435
- model
436
- });
437
- };
438
- const getRevisions = async (initialModel, params) => {
439
- const model = getStorageOperationsModel(initialModel);
440
- const items = await dataLoaders.getAllEntryRevisions({
441
- model,
442
- ids: [params.id]
443
- });
444
- return items.map(item => {
445
- return convertFromStorageEntry({
446
- storageEntry: item,
447
- model
448
- });
449
- });
450
- };
451
- const getByIds = async (initialModel, params) => {
452
- const model = getStorageOperationsModel(initialModel);
453
- const items = await dataLoaders.getRevisionById({
454
- model,
455
- ids: params.ids
456
- });
457
- return items.map(item => {
458
- return convertFromStorageEntry({
459
- storageEntry: item,
460
- model
461
- });
462
- });
463
- };
464
- const getLatestByIds = async (initialModel, params) => {
465
- const model = getStorageOperationsModel(initialModel);
466
- const items = await dataLoaders.getLatestRevisionByEntryId({
467
- model,
468
- ids: params.ids
469
- });
470
- return items.map(item => {
471
- return convertFromStorageEntry({
472
- storageEntry: item,
473
- model
474
- });
475
- });
476
- };
477
- const getPublishedByIds = async (initialModel, params) => {
478
- const model = getStorageOperationsModel(initialModel);
479
- const items = await dataLoaders.getPublishedRevisionByEntryId({
480
- model,
481
- ids: params.ids
20
+ };
21
+ const convertFromStorageEntry = (params)=>{
22
+ const { model, storageEntry } = params;
23
+ const values = model.convertValueKeyFromStorage({
24
+ fields: model.fields,
25
+ values: storageEntry.values
482
26
  });
483
- return items.map(item => {
484
- return convertFromStorageEntry({
485
- storageEntry: item,
486
- model
487
- });
27
+ return {
28
+ ...storageEntry,
29
+ values
30
+ };
31
+ };
32
+ const MAX_LIST_LIMIT = 1000000;
33
+ const createEntriesStorageOperations = (params)=>{
34
+ const { entity, container, plugins } = params;
35
+ const storageTransformRegistry = container.resolve(StorageTransformRegistry);
36
+ const { getModel: getStorageOperationsModel } = createStorageModelAccessor(plugins);
37
+ const dataLoaders = new DataLoadersHandler({
38
+ entity
488
39
  });
489
- };
490
- const getPreviousRevision = async (initialModel, params) => {
491
- const model = getStorageOperationsModel(initialModel);
492
- const {
493
- entryId,
494
- version
495
- } = params;
496
- const queryParams = {
497
- entity,
498
- partitionKey: (0, _keys.createPartitionKey)({
499
- tenant: model.tenant,
500
- locale: model.locale,
501
- id: entryId
502
- }),
503
- options: {
504
- lt: `REV#${(0, _zeroPad.zeroPad)(version)}`,
505
- /**
506
- * We need to have extra checks because DynamoDB will return published or latest record if there is no REV# record.
507
- */
508
- filters: [{
509
- attr: "TYPE",
510
- eq: createType()
511
- }, {
512
- attr: "version",
513
- lt: version
514
- }],
515
- reverse: true
516
- }
40
+ const create = async (initialModel, params)=>{
41
+ const { entry, storageEntry: initialStorageEntry } = params;
42
+ const model = getStorageOperationsModel(initialModel);
43
+ const isPublished = "published" === entry.status;
44
+ const locked = isPublished ? true : entry.locked;
45
+ const storageEntry = convertToStorageEntry({
46
+ model,
47
+ storageEntry: initialStorageEntry
48
+ });
49
+ const storageEntryRevisionKeys = createEntryRevisionKeys(entry);
50
+ const storageEntryLatestKeys = createEntryLatestKeys(entry);
51
+ const entityBatch = entity.createEntityWriter({
52
+ put: [
53
+ {
54
+ ...storageEntryRevisionKeys,
55
+ data: {
56
+ ...storageEntry,
57
+ locked
58
+ }
59
+ },
60
+ {
61
+ ...storageEntryLatestKeys,
62
+ data: {
63
+ ...storageEntry,
64
+ locked
65
+ }
66
+ }
67
+ ]
68
+ });
69
+ if (isPublished) {
70
+ const storageEntryPublishedKeys = createEntryPublishedKeys(storageEntry);
71
+ entityBatch.put({
72
+ ...storageEntryPublishedKeys,
73
+ data: {
74
+ ...storageEntry,
75
+ locked
76
+ }
77
+ });
78
+ }
79
+ try {
80
+ await entityBatch.execute();
81
+ dataLoaders.clearAll({
82
+ tenant: entry.tenant
83
+ });
84
+ } catch (ex) {
85
+ throw new error(ex.message || "Could not insert data into the DynamoDB.", ex.code || "CREATE_ENTRY_ERROR", {
86
+ error: ex,
87
+ entry
88
+ });
89
+ }
90
+ return initialStorageEntry;
517
91
  };
518
- try {
519
- const result = await (0, _query.queryOne)(queryParams);
520
- const storageEntry = (0, _cleanup.cleanupItem)(entity, result);
521
- if (!storageEntry) {
522
- return null;
523
- }
524
- return convertFromStorageEntry({
525
- storageEntry,
526
- model
527
- });
528
- } catch (ex) {
529
- throw new _error.default(ex.message || "Could not get previous version of given entry.", ex.code || "GET_PREVIOUS_VERSION_ERROR", (0, _objectSpread2.default)((0, _objectSpread2.default)({}, params), {}, {
530
- error: ex,
531
- partitionKey: queryParams.partitionKey,
532
- options: queryParams.options,
533
- model
534
- }));
535
- }
536
- };
537
- const list = async (initialModel, params) => {
538
- const model = getStorageOperationsModel(initialModel);
539
- const {
540
- limit: initialLimit = 10,
541
- where: initialWhere,
542
- after,
543
- sort: sortBy,
544
- fields,
545
- search
546
- } = params;
547
- const limit = initialLimit <= 0 || initialLimit >= 10000 ? 10000 : initialLimit;
548
- const type = initialWhere.published ? "P" : "L";
549
- const queryAllParams = {
550
- entity,
551
- partitionKey: (0, _keys.createGSIPartitionKey)(model, type),
552
- options: {
553
- index: "GSI1",
554
- gte: " "
555
- }
92
+ const createRevisionFrom = async (initialModel, params)=>{
93
+ const { entry, storageEntry: initialStorageEntry } = params;
94
+ const model = getStorageOperationsModel(initialModel);
95
+ const storageEntry = convertToStorageEntry({
96
+ storageEntry: initialStorageEntry,
97
+ model
98
+ });
99
+ const entityBatch = entity.createEntityWriter({
100
+ put: [
101
+ {
102
+ ...createEntryRevisionKeys(storageEntry),
103
+ data: {
104
+ ...storageEntry
105
+ }
106
+ },
107
+ {
108
+ ...createEntryLatestKeys(storageEntry),
109
+ data: {
110
+ ...storageEntry
111
+ }
112
+ }
113
+ ]
114
+ });
115
+ const isPublished = "published" === entry.status;
116
+ if (isPublished) {
117
+ entityBatch.put({
118
+ ...createEntryPublishedKeys(storageEntry),
119
+ data: {
120
+ ...storageEntry
121
+ }
122
+ });
123
+ const [publishedRevisionStorageEntry] = await dataLoaders.getPublishedRevisionByEntryId({
124
+ model,
125
+ ids: [
126
+ entry.id
127
+ ]
128
+ });
129
+ if (publishedRevisionStorageEntry) entityBatch.put({
130
+ ...createEntryRevisionKeys(publishedRevisionStorageEntry),
131
+ data: {
132
+ ...publishedRevisionStorageEntry,
133
+ status: CONTENT_ENTRY_STATUS.UNPUBLISHED
134
+ }
135
+ });
136
+ }
137
+ try {
138
+ await entityBatch.execute();
139
+ dataLoaders.clearAll({
140
+ tenant: entry.tenant
141
+ });
142
+ } catch (ex) {
143
+ throw new error(ex.message || "Could not create revision from given entry.", ex.code || "CREATE_REVISION_ERROR", {
144
+ error: ex,
145
+ entry,
146
+ storageEntry
147
+ });
148
+ }
149
+ return initialStorageEntry;
150
+ };
151
+ const update = async (initialModel, params)=>{
152
+ const { entry, storageEntry: initialStorageEntry } = params;
153
+ const model = getStorageOperationsModel(initialModel);
154
+ const isPublished = "published" === entry.status;
155
+ const locked = isPublished ? true : entry.locked;
156
+ const storageEntry = convertToStorageEntry({
157
+ model,
158
+ storageEntry: initialStorageEntry
159
+ });
160
+ const entityBatch = entity.createEntityWriter({
161
+ put: [
162
+ {
163
+ ...createEntryRevisionKeys(storageEntry),
164
+ data: {
165
+ ...storageEntry,
166
+ locked
167
+ }
168
+ }
169
+ ]
170
+ });
171
+ if (isPublished) entityBatch.put({
172
+ ...createEntryPublishedKeys(storageEntry),
173
+ data: {
174
+ ...storageEntry,
175
+ locked
176
+ }
177
+ });
178
+ const latestStorageEntry = await getLatestRevisionByEntryId(model, entry);
179
+ if (latestStorageEntry) {
180
+ const updatingLatestRevision = latestStorageEntry.id === entry.id;
181
+ if (updatingLatestRevision) entityBatch.put({
182
+ ...createEntryLatestKeys(storageEntry),
183
+ data: {
184
+ ...storageEntry,
185
+ locked
186
+ }
187
+ });
188
+ else {
189
+ const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
190
+ entityBatch.put({
191
+ ...createEntryRevisionKeys(latestStorageEntry),
192
+ data: {
193
+ ...latestStorageEntry,
194
+ ...updatedEntryLevelMetaFields
195
+ }
196
+ });
197
+ entityBatch.put({
198
+ ...createEntryLatestKeys(latestStorageEntry),
199
+ data: {
200
+ ...latestStorageEntry,
201
+ ...updatedEntryLevelMetaFields
202
+ }
203
+ });
204
+ }
205
+ }
206
+ try {
207
+ await entityBatch.execute();
208
+ dataLoaders.clearAll({
209
+ tenant: entry.tenant
210
+ });
211
+ return initialStorageEntry;
212
+ } catch (ex) {
213
+ throw new error(ex.message || "Could not update entry.", ex.code || "UPDATE_ERROR", {
214
+ error: ex,
215
+ entry,
216
+ latestStorageEntry
217
+ });
218
+ }
219
+ };
220
+ const move = async (initialModel, id, folderId)=>{
221
+ const model = getStorageOperationsModel(initialModel);
222
+ const partitionKey = createPartitionKey({
223
+ id,
224
+ tenant: model.tenant
225
+ });
226
+ const records = await entity.queryAll({
227
+ partitionKey,
228
+ options: {
229
+ gte: " "
230
+ }
231
+ });
232
+ const entityBatch = entity.createEntityWriter({
233
+ put: records.map((item)=>({
234
+ ...item,
235
+ data: {
236
+ ...item.data,
237
+ location: {
238
+ ...item.data.location,
239
+ folderId
240
+ }
241
+ }
242
+ }))
243
+ });
244
+ try {
245
+ await entityBatch.execute();
246
+ } catch (ex) {
247
+ throw error.from(ex, {
248
+ message: "Could not move records to a new folder.",
249
+ data: {
250
+ id,
251
+ folderId
252
+ }
253
+ });
254
+ }
255
+ };
256
+ const moveToBin = async (initialModel, params)=>{
257
+ const { entry, storageEntry: initialStorageEntry } = params;
258
+ const model = getStorageOperationsModel(initialModel);
259
+ let records = [];
260
+ try {
261
+ records = await entity.queryAll({
262
+ partitionKey: createPartitionKey({
263
+ id: entry.id,
264
+ tenant: model.tenant
265
+ }),
266
+ options: {
267
+ gte: " "
268
+ }
269
+ });
270
+ } catch (ex) {
271
+ throw new error(ex.message || "Could not load all records.", ex.code || "LOAD_ALL_RECORDS_ERROR", {
272
+ error: ex,
273
+ id: entry.id
274
+ });
275
+ }
276
+ if (0 === records.length) return;
277
+ const storageEntry = convertToStorageEntry({
278
+ model,
279
+ storageEntry: initialStorageEntry
280
+ });
281
+ const updatedDeletedMetaFields = pickEntryMetaFields(storageEntry, isDeletedEntryMetaField);
282
+ const entityBatch = entity.createEntityWriter({
283
+ put: records.map((record)=>({
284
+ ...record,
285
+ data: {
286
+ ...record.data,
287
+ ...updatedDeletedMetaFields,
288
+ wbyDeleted: storageEntry.wbyDeleted,
289
+ location: storageEntry.location,
290
+ binOriginalFolderId: storageEntry.binOriginalFolderId
291
+ }
292
+ }))
293
+ });
294
+ try {
295
+ await entityBatch.execute();
296
+ dataLoaders.clearAll({
297
+ tenant: entry.tenant
298
+ });
299
+ } catch (ex) {
300
+ throw new error(ex.message || "Could not move the entry to the bin.", ex.code || "MOVE_ENTRY_TO_BIN_ERROR", {
301
+ error: ex,
302
+ entry,
303
+ storageEntry
304
+ });
305
+ }
306
+ };
307
+ const deleteEntry = async (initialModel, params)=>{
308
+ const { entry } = params;
309
+ const id = entry.id || entry.entryId;
310
+ const model = getStorageOperationsModel(initialModel);
311
+ const partitionKey = createPartitionKey({
312
+ id,
313
+ tenant: model.tenant
314
+ });
315
+ let records = [];
316
+ try {
317
+ records = await entity.queryAll({
318
+ partitionKey,
319
+ options: {
320
+ gte: " "
321
+ }
322
+ });
323
+ } catch (ex) {
324
+ throw new error(ex.message || "Could not load all records.", ex.code || "LOAD_ALL_RECORDS_ERROR", {
325
+ error: ex,
326
+ id
327
+ });
328
+ }
329
+ const entityBatch = entity.createEntityWriter({
330
+ delete: records.map((item)=>({
331
+ PK: item.PK,
332
+ SK: item.SK
333
+ }))
334
+ });
335
+ try {
336
+ await entityBatch.execute();
337
+ dataLoaders.clearAll({
338
+ tenant: entry.tenant
339
+ });
340
+ } catch (ex) {
341
+ throw new error(ex.message || "Could not delete the entry.", ex.code || "DELETE_ENTRY_ERROR", {
342
+ error: ex,
343
+ partitionKey,
344
+ id
345
+ });
346
+ }
347
+ };
348
+ const restoreFromBin = async (initialModel, params)=>{
349
+ const { entry, storageEntry: initialStorageEntry } = params;
350
+ const model = getStorageOperationsModel(initialModel);
351
+ let records = [];
352
+ try {
353
+ records = await entity.queryAll({
354
+ partitionKey: createPartitionKey({
355
+ id: entry.id,
356
+ tenant: model.tenant
357
+ }),
358
+ options: {
359
+ gte: " "
360
+ }
361
+ });
362
+ } catch (ex) {
363
+ throw new error(ex.message || "Could not load all records.", ex.code || "LOAD_ALL_RECORDS_ERROR", {
364
+ error: ex,
365
+ id: entry.id
366
+ });
367
+ }
368
+ if (0 === records.length) return initialStorageEntry;
369
+ const storageEntry = convertToStorageEntry({
370
+ model,
371
+ storageEntry: initialStorageEntry
372
+ });
373
+ const updatedRestoredMetaFields = pickEntryMetaFields(storageEntry, isRestoredEntryMetaField);
374
+ const entityBatch = entity.createEntityWriter({
375
+ put: records.map((record)=>({
376
+ ...record,
377
+ data: {
378
+ ...record.data,
379
+ ...updatedRestoredMetaFields,
380
+ wbyDeleted: storageEntry.wbyDeleted,
381
+ location: storageEntry.location,
382
+ binOriginalFolderId: storageEntry.binOriginalFolderId
383
+ }
384
+ }))
385
+ });
386
+ try {
387
+ await entityBatch.execute();
388
+ dataLoaders.clearAll({
389
+ tenant: entry.tenant
390
+ });
391
+ return initialStorageEntry;
392
+ } catch (ex) {
393
+ throw new error(ex.message || "Could not restore the entry from the bin.", ex.code || "RESTORE_ENTRY_ERROR", {
394
+ error: ex,
395
+ entry,
396
+ storageEntry
397
+ });
398
+ }
399
+ };
400
+ const deleteRevision = async (initialModel, params)=>{
401
+ const { entry, latestEntry, latestStorageEntry: initialLatestStorageEntry } = params;
402
+ const model = getStorageOperationsModel(initialModel);
403
+ const partitionKey = createPartitionKey({
404
+ id: entry.id,
405
+ tenant: model.tenant
406
+ });
407
+ const entityBatch = entity.createEntityWriter({
408
+ delete: [
409
+ {
410
+ PK: partitionKey,
411
+ SK: createRevisionSortKey(entry)
412
+ }
413
+ ]
414
+ });
415
+ const publishedStorageEntry = await getPublishedRevisionByEntryId(model, entry);
416
+ if (publishedStorageEntry && entry.id === publishedStorageEntry.id) entityBatch.delete({
417
+ PK: partitionKey,
418
+ SK: createPublishedSortKey()
419
+ });
420
+ if (initialLatestStorageEntry) {
421
+ const latestStorageEntry = convertToStorageEntry({
422
+ storageEntry: initialLatestStorageEntry,
423
+ model
424
+ });
425
+ entityBatch.put({
426
+ ...createEntryLatestKeys(latestStorageEntry),
427
+ data: {
428
+ ...latestStorageEntry
429
+ }
430
+ });
431
+ entityBatch.put({
432
+ ...createEntryRevisionKeys(latestStorageEntry),
433
+ data: {
434
+ ...latestStorageEntry
435
+ }
436
+ });
437
+ }
438
+ try {
439
+ await entityBatch.execute();
440
+ dataLoaders.clearAll({
441
+ tenant: entry.tenant
442
+ });
443
+ } catch (ex) {
444
+ throw new error(ex.message, ex.code, {
445
+ error: ex,
446
+ entry,
447
+ latestEntry
448
+ });
449
+ }
450
+ };
451
+ const deleteMultipleEntries = async (initialModel, params)=>{
452
+ const { entries } = params;
453
+ const model = getStorageOperationsModel(initialModel);
454
+ const revisions = await dataLoaders.getAllEntryRevisions({
455
+ model,
456
+ ids: entries
457
+ });
458
+ const entityBatch = entity.createEntityWriter();
459
+ for (const id of entries){
460
+ const partitionKey = createPartitionKey({
461
+ id,
462
+ tenant: model.tenant
463
+ });
464
+ entityBatch.delete({
465
+ PK: partitionKey,
466
+ SK: "L"
467
+ });
468
+ entityBatch.delete({
469
+ PK: partitionKey,
470
+ SK: "P"
471
+ });
472
+ }
473
+ for (const revision of revisions)entityBatch.delete({
474
+ PK: createPartitionKey({
475
+ id: revision.id,
476
+ tenant: model.tenant
477
+ }),
478
+ SK: createRevisionSortKey({
479
+ version: revision.version
480
+ })
481
+ });
482
+ await entityBatch.execute();
483
+ };
484
+ const getLatestRevisionByEntryId = async (initialModel, params)=>{
485
+ const model = getStorageOperationsModel(initialModel);
486
+ const items = await dataLoaders.getLatestRevisionByEntryId({
487
+ model,
488
+ ids: [
489
+ params.id
490
+ ]
491
+ });
492
+ const item = items.shift() || null;
493
+ if (!item) return null;
494
+ return convertFromStorageEntry({
495
+ storageEntry: item,
496
+ model
497
+ });
498
+ };
499
+ const getPublishedRevisionByEntryId = async (initialModel, params)=>{
500
+ const model = getStorageOperationsModel(initialModel);
501
+ const items = await dataLoaders.getPublishedRevisionByEntryId({
502
+ model,
503
+ ids: [
504
+ params.id
505
+ ]
506
+ });
507
+ const item = items.shift() || null;
508
+ if (!item) return null;
509
+ return convertFromStorageEntry({
510
+ storageEntry: item,
511
+ model
512
+ });
513
+ };
514
+ const getRevisionById = async (initialModel, params)=>{
515
+ const model = getStorageOperationsModel(initialModel);
516
+ const items = await dataLoaders.getRevisionById({
517
+ model,
518
+ ids: [
519
+ params.id
520
+ ]
521
+ });
522
+ const item = items.shift() || null;
523
+ if (!item) return null;
524
+ return convertFromStorageEntry({
525
+ storageEntry: item,
526
+ model
527
+ });
528
+ };
529
+ const getRevisions = async (initialModel, params)=>{
530
+ const model = getStorageOperationsModel(initialModel);
531
+ const items = await dataLoaders.getAllEntryRevisions({
532
+ model,
533
+ ids: [
534
+ params.id
535
+ ]
536
+ });
537
+ return items.map((item)=>convertFromStorageEntry({
538
+ storageEntry: item,
539
+ model
540
+ }));
541
+ };
542
+ const getByIds = async (initialModel, params)=>{
543
+ const model = getStorageOperationsModel(initialModel);
544
+ const items = await dataLoaders.getRevisionById({
545
+ model,
546
+ ids: params.ids
547
+ });
548
+ return items.map((item)=>convertFromStorageEntry({
549
+ storageEntry: item,
550
+ model
551
+ }));
552
+ };
553
+ const getLatestByIds = async (initialModel, params)=>{
554
+ const model = getStorageOperationsModel(initialModel);
555
+ const items = await dataLoaders.getLatestRevisionByEntryId({
556
+ model,
557
+ ids: params.ids
558
+ });
559
+ return items.map((item)=>convertFromStorageEntry({
560
+ storageEntry: item,
561
+ model
562
+ }));
563
+ };
564
+ const getPublishedByIds = async (initialModel, params)=>{
565
+ const model = getStorageOperationsModel(initialModel);
566
+ const items = await dataLoaders.getPublishedRevisionByEntryId({
567
+ model,
568
+ ids: params.ids
569
+ });
570
+ return items.map((item)=>convertFromStorageEntry({
571
+ storageEntry: item,
572
+ model
573
+ }));
574
+ };
575
+ const getPreviousRevision = async (initialModel, params)=>{
576
+ const model = getStorageOperationsModel(initialModel);
577
+ const { entryId, version } = params;
578
+ const partitionKey = createPartitionKey({
579
+ tenant: model.tenant,
580
+ id: entryId
581
+ });
582
+ const unfilteredRevisions = await entity.queryAll({
583
+ partitionKey,
584
+ options: {
585
+ beginsWith: "REV#",
586
+ reverse: true
587
+ }
588
+ });
589
+ const filteredRevisions = unfilteredRevisions.filter((item)=>item.data.version < version);
590
+ const storageEntry = filteredRevisions[0];
591
+ if (!storageEntry) return null;
592
+ try {
593
+ return convertFromStorageEntry({
594
+ storageEntry: storageEntry.data,
595
+ model
596
+ });
597
+ } catch (ex) {
598
+ throw new error(ex.message || "Could not get previous version of given entry.", ex.code || "GET_PREVIOUS_VERSION_ERROR", {
599
+ ...params,
600
+ error: ex,
601
+ partitionKey,
602
+ model
603
+ });
604
+ }
605
+ };
606
+ const list = async (initialModel, params)=>{
607
+ const model = getStorageOperationsModel(initialModel);
608
+ const { limit: initialLimit = 10, where: initialWhere, after, sort: sortBy, fields, search } = params;
609
+ const limit = initialLimit <= 0 || initialLimit >= MAX_LIST_LIMIT ? MAX_LIST_LIMIT : initialLimit;
610
+ const type = initialWhere.published ? "P" : "L";
611
+ const partitionKey = createGSIPartitionKey(model, type);
612
+ const options = {
613
+ index: "GSI1",
614
+ gte: " "
615
+ };
616
+ let storageEntries = [];
617
+ try {
618
+ storageEntries = await entity.queryAll({
619
+ partitionKey,
620
+ options
621
+ });
622
+ } catch (ex) {
623
+ throw new error(ex.message, "QUERY_ENTRIES_ERROR", {
624
+ error: ex,
625
+ partitionKey,
626
+ options
627
+ });
628
+ }
629
+ if (0 === storageEntries.length) return {
630
+ hasMoreItems: false,
631
+ totalCount: 0,
632
+ cursor: null,
633
+ items: []
634
+ };
635
+ const where = {
636
+ ...initialWhere
637
+ };
638
+ delete where["published"];
639
+ delete where["latest"];
640
+ const modelFields = createFields({
641
+ plugins,
642
+ fields: model.fields
643
+ });
644
+ const fromStorage = createStorageTransformCallable(storageTransformRegistry, model);
645
+ const records = await Promise.all(storageEntries.map(async (storageEntry)=>{
646
+ const entry = convertFromStorageEntry({
647
+ storageEntry: storageEntry.data,
648
+ model
649
+ });
650
+ for (const field of model.fields)entry.values[field.fieldId] = await fromStorage(field, entry.values[field.fieldId]);
651
+ return entry;
652
+ }));
653
+ const valueFilterRegistry = container.resolve(ValueFilterRegistry);
654
+ const filteredItems = filter({
655
+ items: records,
656
+ where,
657
+ plugins,
658
+ fields: modelFields,
659
+ fullTextSearch: {
660
+ term: search,
661
+ fields: fields || []
662
+ },
663
+ valueFilterRegistry
664
+ });
665
+ const totalCount = filteredItems.length;
666
+ const sortedItems = sort({
667
+ model,
668
+ plugins,
669
+ items: filteredItems,
670
+ sort: sortBy,
671
+ fields: modelFields
672
+ });
673
+ const start = parseInt(decodeCursor(after) || "0") || 0;
674
+ const hasMoreItems = totalCount > start + limit;
675
+ const end = limit > totalCount + start + limit ? void 0 : start + limit;
676
+ const slicedItems = sortedItems.slice(start, end);
677
+ const cursor = encodeCursor(`${start + limit}`);
678
+ return {
679
+ hasMoreItems,
680
+ totalCount,
681
+ cursor,
682
+ items: slicedItems
683
+ };
684
+ };
685
+ const get = async (initialModel, params)=>{
686
+ const model = getStorageOperationsModel(initialModel);
687
+ const { items } = await list(model, {
688
+ ...params,
689
+ limit: 1
690
+ });
691
+ return items.shift() || null;
692
+ };
693
+ const publish = async (initialModel, params)=>{
694
+ const { entry, storageEntry: initialStorageEntry } = params;
695
+ const model = getStorageOperationsModel(initialModel);
696
+ const initialLatestStorageEntry = await getLatestRevisionByEntryId(model, entry);
697
+ if (!initialLatestStorageEntry) throw new error('Could not publish entry. Could not load latest ("L") record.', "PUBLISH_ERROR", {
698
+ entry
699
+ });
700
+ const initialPublishedStorageEntry = await getPublishedRevisionByEntryId(model, entry);
701
+ const storageEntry = convertToStorageEntry({
702
+ model,
703
+ storageEntry: initialStorageEntry
704
+ });
705
+ const entityBatch = entity.createEntityWriter({
706
+ put: [
707
+ {
708
+ ...createEntryRevisionKeys(storageEntry),
709
+ data: {
710
+ ...storageEntry
711
+ }
712
+ },
713
+ {
714
+ ...createEntryPublishedKeys(storageEntry),
715
+ data: {
716
+ ...storageEntry
717
+ }
718
+ }
719
+ ]
720
+ });
721
+ const publishedRevisionId = initialPublishedStorageEntry?.id;
722
+ const publishingLatestRevision = entry.id === initialLatestStorageEntry.id;
723
+ if (publishingLatestRevision) {
724
+ entityBatch.put({
725
+ ...createEntryLatestKeys(storageEntry),
726
+ data: {
727
+ ...storageEntry
728
+ }
729
+ });
730
+ if (publishedRevisionId && publishedRevisionId !== entry.id) {
731
+ const publishedStorageEntry = convertToStorageEntry({
732
+ storageEntry: initialPublishedStorageEntry,
733
+ model
734
+ });
735
+ entityBatch.put({
736
+ ...createEntryRevisionKeys(publishedStorageEntry),
737
+ data: {
738
+ ...publishedStorageEntry,
739
+ status: CONTENT_ENTRY_STATUS.UNPUBLISHED
740
+ }
741
+ });
742
+ }
743
+ } else {
744
+ const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
745
+ const latestStorageEntry = convertToStorageEntry({
746
+ storageEntry: initialLatestStorageEntry,
747
+ model
748
+ });
749
+ let latestRevisionStatus = latestStorageEntry.status;
750
+ if (latestRevisionStatus === CONTENT_ENTRY_STATUS.PUBLISHED) latestRevisionStatus = CONTENT_ENTRY_STATUS.UNPUBLISHED;
751
+ const latestStorageEntryFields = {
752
+ ...latestStorageEntry,
753
+ ...updatedEntryLevelMetaFields,
754
+ status: latestRevisionStatus
755
+ };
756
+ entityBatch.put({
757
+ ...createEntryLatestKeys(latestStorageEntryFields),
758
+ data: {
759
+ ...latestStorageEntryFields
760
+ }
761
+ });
762
+ entityBatch.put({
763
+ ...createEntryRevisionKeys(latestStorageEntryFields),
764
+ data: {
765
+ ...latestStorageEntryFields
766
+ }
767
+ });
768
+ const publishedRevisionDifferentFromLatest = publishedRevisionId && publishedRevisionId !== latestStorageEntry.id;
769
+ if (publishedRevisionDifferentFromLatest) {
770
+ const publishedStorageEntry = convertToStorageEntry({
771
+ storageEntry: initialPublishedStorageEntry,
772
+ model
773
+ });
774
+ entityBatch.put({
775
+ ...createEntryRevisionKeys(publishedStorageEntry),
776
+ data: {
777
+ ...publishedStorageEntry,
778
+ status: CONTENT_ENTRY_STATUS.UNPUBLISHED
779
+ }
780
+ });
781
+ }
782
+ }
783
+ try {
784
+ await entityBatch.execute();
785
+ dataLoaders.clearAll({
786
+ tenant: entry.tenant
787
+ });
788
+ return initialStorageEntry;
789
+ } catch (ex) {
790
+ throw new error(ex.message || "Could not execute the publishing batch.", ex.code || "PUBLISH_ERROR", {
791
+ entry,
792
+ latestStorageEntry: initialLatestStorageEntry,
793
+ publishedStorageEntry: initialPublishedStorageEntry
794
+ });
795
+ }
796
+ };
797
+ const unpublish = async (initialModel, params)=>{
798
+ const { entry, storageEntry: initialStorageEntry } = params;
799
+ const model = getStorageOperationsModel(initialModel);
800
+ const partitionKey = createPartitionKey({
801
+ id: entry.id,
802
+ tenant: model.tenant
803
+ });
804
+ const storageEntry = convertToStorageEntry({
805
+ storageEntry: initialStorageEntry,
806
+ model
807
+ });
808
+ const entityBatch = entity.createEntityWriter({
809
+ delete: [
810
+ {
811
+ PK: partitionKey,
812
+ SK: createPublishedSortKey()
813
+ }
814
+ ],
815
+ put: [
816
+ {
817
+ ...createEntryRevisionKeys(storageEntry),
818
+ data: {
819
+ ...storageEntry
820
+ }
821
+ }
822
+ ]
823
+ });
824
+ const initialLatestStorageEntry = await getLatestRevisionByEntryId(model, entry);
825
+ if (initialLatestStorageEntry) {
826
+ const unpublishingLatestRevision = entry.id === initialLatestStorageEntry.id;
827
+ if (unpublishingLatestRevision) entityBatch.put({
828
+ ...createEntryLatestKeys(storageEntry),
829
+ data: {
830
+ ...storageEntry
831
+ }
832
+ });
833
+ else {
834
+ const latestStorageEntry = convertToStorageEntry({
835
+ storageEntry: initialLatestStorageEntry,
836
+ model
837
+ });
838
+ const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
839
+ entityBatch.put({
840
+ ...createEntryRevisionKeys(latestStorageEntry),
841
+ data: {
842
+ ...latestStorageEntry,
843
+ ...updatedEntryLevelMetaFields
844
+ }
845
+ });
846
+ entityBatch.put({
847
+ ...createEntryLatestKeys(latestStorageEntry),
848
+ data: {
849
+ ...latestStorageEntry,
850
+ ...updatedEntryLevelMetaFields
851
+ }
852
+ });
853
+ }
854
+ }
855
+ try {
856
+ await entityBatch.execute();
857
+ dataLoaders.clearAll({
858
+ tenant: entry.tenant
859
+ });
860
+ return initialStorageEntry;
861
+ } catch (ex) {
862
+ throw new error(ex.message || "Could not execute unpublish batch.", ex.code || "UNPUBLISH_ERROR", {
863
+ entry,
864
+ storageEntry
865
+ });
866
+ }
867
+ };
868
+ const getUniqueFieldValues = async (model, params)=>{
869
+ const { where, fieldId } = params;
870
+ const field = model.fields.find((f)=>f.fieldId === fieldId);
871
+ if (!field) throw new error('Could not find field with given "fieldId" value.', "FIELD_NOT_FOUND", {
872
+ fieldId
873
+ });
874
+ const { items } = await list(model, {
875
+ where,
876
+ limit: MAX_LIST_LIMIT
877
+ });
878
+ return aggregateUniqueFieldValues(items, field.fieldId);
556
879
  };
557
- let storageEntries = [];
558
- try {
559
- storageEntries = await (0, _query.queryAll)(queryAllParams);
560
- } catch (ex) {
561
- throw new _error.default(ex.message, "QUERY_ENTRIES_ERROR", {
562
- error: ex,
563
- partitionKey: queryAllParams.partitionKey,
564
- options: queryAllParams.options
565
- });
566
- }
567
- if (storageEntries.length === 0) {
568
- return {
569
- hasMoreItems: false,
570
- totalCount: 0,
571
- cursor: null,
572
- items: []
573
- };
574
- }
575
- const where = (0, _objectSpread2.default)({}, initialWhere);
576
- delete where["published"];
577
- delete where["latest"];
578
- /**
579
- * We need an object containing field, transformers and paths.
580
- * Just build it here and pass on into other methods that require it to avoid mapping multiple times.
581
- */
582
- const modelFields = (0, _createFields.createFields)({
583
- plugins,
584
- fields: model.fields
585
- });
586
- const fromStorage = createStorageTransformCallable(model);
587
- /**
588
- * Let's transform records from storage ones to regular ones, so we do not need to do it later.
589
- *
590
- * This is always being done, but at least its in parallel.
591
- */
592
- const records = await Promise.all(storageEntries.map(async storageEntry => {
593
- const entry = convertFromStorageEntry({
594
- storageEntry,
595
- model
596
- });
597
- for (const field of model.fields) {
598
- entry.values[field.fieldId] = await fromStorage(field, entry.values[field.fieldId]);
599
- }
600
- return entry;
601
- }));
602
- /**
603
- * Filter the read items via the code.
604
- * It will build the filters out of the where input and transform the values it is using.
605
- */
606
- const filteredItems = (0, _filtering.filter)({
607
- items: records,
608
- where,
609
- plugins,
610
- fields: modelFields,
611
- fullTextSearch: {
612
- term: search,
613
- fields: fields || []
614
- }
615
- });
616
- const totalCount = filteredItems.length;
617
-
618
- /**
619
- * Sorting is also done via the code.
620
- * It takes the sort input and sorts by it via the lodash sortBy method.
621
- */
622
- const sortedItems = (0, _filtering.sort)({
623
- model,
624
- plugins,
625
- items: filteredItems,
626
- sort: sortBy,
627
- fields: modelFields
628
- });
629
- const start = parseInt((0, _cursor.decodeCursor)(after) || "0") || 0;
630
- const hasMoreItems = totalCount > start + limit;
631
- const end = limit > totalCount + start + limit ? undefined : start + limit;
632
- const slicedItems = sortedItems.slice(start, end);
633
- /**
634
- * Although we do not need a cursor here, we will use it as such to keep it standardized.
635
- * Number is simply encoded.
636
- */
637
- const cursor = totalCount > start + limit ? (0, _cursor.encodeCursor)(`${start + limit}`) : null;
638
880
  return {
639
- hasMoreItems,
640
- totalCount,
641
- cursor,
642
- items: (0, _cleanup.cleanupItems)(entity, slicedItems)
881
+ create,
882
+ createRevisionFrom,
883
+ update,
884
+ move,
885
+ delete: deleteEntry,
886
+ moveToBin,
887
+ restoreFromBin,
888
+ deleteRevision,
889
+ deleteMultipleEntries,
890
+ getPreviousRevision,
891
+ getPublishedByIds,
892
+ getLatestByIds,
893
+ getByIds,
894
+ getRevisionById,
895
+ getPublishedRevisionByEntryId,
896
+ getLatestRevisionByEntryId,
897
+ get,
898
+ getRevisions,
899
+ publish,
900
+ list,
901
+ unpublish,
902
+ dataLoaders,
903
+ getUniqueFieldValues
643
904
  };
644
- };
645
- const get = async (initialModel, params) => {
646
- const model = getStorageOperationsModel(initialModel);
647
- const {
648
- items
649
- } = await list(model, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, params), {}, {
650
- limit: 1
651
- }));
652
- return items.shift() || null;
653
- };
654
- const publish = async (initialModel, params) => {
655
- const {
656
- entry,
657
- storageEntry: initialStorageEntry
658
- } = params;
659
- const model = getStorageOperationsModel(initialModel);
660
- const partitionKey = (0, _keys.createPartitionKey)({
661
- id: entry.id,
662
- locale: model.locale,
663
- tenant: model.tenant
664
- });
665
-
666
- /**
667
- * We need the latest and published entries to see if something needs to be updated alongside the publishing one.
668
- */
669
- const initialLatestStorageEntry = await getLatestRevisionByEntryId(model, entry);
670
- const initialPublishedStorageEntry = await getPublishedRevisionByEntryId(model, entry);
671
- const storageEntry = convertToStorageEntry({
672
- model,
673
- storageEntry: initialStorageEntry
674
- });
675
- /**
676
- * We need to update:
677
- * - current entry revision sort key
678
- * - published sort key
679
- * - the latest sort key - if entry updated is actually latest
680
- * - previous published entry to unpublished status - if any previously published entry
681
- */
682
- const items = [entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
683
- PK: partitionKey,
684
- SK: (0, _keys.createRevisionSortKey)(entry),
685
- TYPE: createType(),
686
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
687
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
688
- })), entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
689
- PK: partitionKey,
690
- SK: (0, _keys.createPublishedSortKey)(),
691
- TYPE: createPublishedType(),
692
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "P"),
693
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
694
- }))];
695
- if (initialLatestStorageEntry && entry.id === initialLatestStorageEntry.id) {
696
- items.push(entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
697
- PK: partitionKey,
698
- SK: (0, _keys.createLatestSortKey)(),
699
- TYPE: createLatestType(),
700
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
701
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
702
- })));
703
- }
704
- if (initialPublishedStorageEntry && initialPublishedStorageEntry.id !== entry.id) {
705
- const publishedStorageEntry = convertToStorageEntry({
706
- storageEntry: initialPublishedStorageEntry,
707
- model
708
- });
709
- items.push(entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, publishedStorageEntry), {}, {
710
- PK: partitionKey,
711
- SK: (0, _keys.createRevisionSortKey)(publishedStorageEntry),
712
- TYPE: createType(),
713
- status: _types.CONTENT_ENTRY_STATUS.UNPUBLISHED,
714
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
715
- GSI1_SK: (0, _keys.createGSISortKey)(publishedStorageEntry)
716
- })));
717
- }
718
- try {
719
- await (0, _batchWrite.batchWriteAll)({
720
- table: entity.table,
721
- items
722
- });
723
- dataLoaders.clearAll({
724
- model
725
- });
726
- return initialStorageEntry;
727
- } catch (ex) {
728
- throw new _error.default(ex.message || "Could not execute the publishing batch.", ex.code || "PUBLISH_ERROR", {
729
- entry,
730
- latestStorageEntry: initialLatestStorageEntry,
731
- publishedStorageEntry: initialPublishedStorageEntry
732
- });
733
- }
734
- };
735
- const unpublish = async (initialModel, params) => {
736
- const {
737
- entry,
738
- storageEntry: initialStorageEntry
739
- } = params;
740
- const model = getStorageOperationsModel(initialModel);
741
- const partitionKey = (0, _keys.createPartitionKey)({
742
- id: entry.id,
743
- locale: model.locale,
744
- tenant: model.tenant
745
- });
746
- const storageEntry = convertToStorageEntry({
747
- storageEntry: initialStorageEntry,
748
- model
749
- });
750
- /**
751
- * We need to:
752
- * - delete currently published entry
753
- * - update current entry revision with new data
754
- * - update the latest entry status - if entry being unpublished is latest
755
- */
756
- const items = [entity.deleteBatch({
757
- PK: partitionKey,
758
- SK: (0, _keys.createPublishedSortKey)()
759
- }), entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
760
- PK: partitionKey,
761
- SK: (0, _keys.createRevisionSortKey)(entry),
762
- TYPE: createType(),
763
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
764
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
765
- }))];
766
-
767
- /**
768
- * We need the latest entry to see if something needs to be updated alongside the unpublishing one.
769
- */
770
- const latestStorageEntry = await getLatestRevisionByEntryId(model, entry);
771
- if (latestStorageEntry && entry.id === latestStorageEntry.id) {
772
- items.push(entity.putBatch((0, _objectSpread2.default)((0, _objectSpread2.default)({}, storageEntry), {}, {
773
- PK: partitionKey,
774
- SK: (0, _keys.createLatestSortKey)(),
775
- TYPE: createLatestType(),
776
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
777
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
778
- })));
779
- }
780
- try {
781
- await (0, _batchWrite.batchWriteAll)({
782
- table: entity.table,
783
- items
784
- });
785
- dataLoaders.clearAll({
786
- model
787
- });
788
- return initialStorageEntry;
789
- } catch (ex) {
790
- throw new _error.default(ex.message || "Could not execute unpublish batch.", ex.code || "UNPUBLISH_ERROR", {
791
- entry,
792
- storageEntry
793
- });
794
- }
795
- };
796
- return {
797
- create,
798
- createRevisionFrom,
799
- update,
800
- delete: deleteEntry,
801
- deleteRevision,
802
- getPreviousRevision,
803
- getPublishedByIds,
804
- getLatestByIds,
805
- getByIds,
806
- getRevisionById,
807
- getPublishedRevisionByEntryId,
808
- getLatestRevisionByEntryId,
809
- get,
810
- getRevisions,
811
- publish,
812
- list,
813
- unpublish
814
- };
815
905
  };
816
- exports.createEntriesStorageOperations = createEntriesStorageOperations;
906
+ export { createEntriesStorageOperations };
907
+
908
+ //# sourceMappingURL=index.js.map