@webiny/api-headless-cms-ddb 6.0.0-beta.0 → 6.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/README.md +6 -20
  2. package/definitions/entry.d.ts +4 -5
  3. package/definitions/entry.js +5 -180
  4. package/definitions/entry.js.map +1 -1
  5. package/definitions/group.d.ts +4 -5
  6. package/definitions/group.js +5 -58
  7. package/definitions/group.js.map +1 -1
  8. package/definitions/model.d.ts +4 -5
  9. package/definitions/model.js +5 -102
  10. package/definitions/model.js.map +1 -1
  11. package/definitions/table.d.ts +3 -5
  12. package/definitions/table.js +6 -28
  13. package/definitions/table.js.map +1 -1
  14. package/definitions/types.d.ts +59 -0
  15. package/definitions/types.js +3 -0
  16. package/definitions/types.js.map +1 -0
  17. package/dynamoDb/index.d.ts +1 -1
  18. package/dynamoDb/index.js +6 -14
  19. package/dynamoDb/index.js.map +1 -1
  20. package/dynamoDb/path/locationFolderId.d.ts +1 -1
  21. package/dynamoDb/path/locationFolderId.js +5 -14
  22. package/dynamoDb/path/locationFolderId.js.map +1 -1
  23. package/dynamoDb/path/plainObject.d.ts +1 -1
  24. package/dynamoDb/path/plainObject.js +5 -14
  25. package/dynamoDb/path/plainObject.js.map +1 -1
  26. package/dynamoDb/storage/longText.js +11 -18
  27. package/dynamoDb/storage/longText.js.map +1 -1
  28. package/dynamoDb/storage/richText.js +26 -71
  29. package/dynamoDb/storage/richText.js.map +1 -1
  30. package/dynamoDb/transformValue/datetime.d.ts +1 -1
  31. package/dynamoDb/transformValue/datetime.js +5 -12
  32. package/dynamoDb/transformValue/datetime.js.map +1 -1
  33. package/index.d.ts +2 -2
  34. package/index.js +38 -72
  35. package/index.js.map +1 -1
  36. package/operations/entry/dataLoader/DataLoaderCache.d.ts +1 -3
  37. package/operations/entry/dataLoader/DataLoaderCache.js +2 -9
  38. package/operations/entry/dataLoader/DataLoaderCache.js.map +1 -1
  39. package/operations/entry/dataLoader/constants.js +1 -7
  40. package/operations/entry/dataLoader/constants.js.map +1 -1
  41. package/operations/entry/dataLoader/createBatchScheduleFn.js +4 -10
  42. package/operations/entry/dataLoader/createBatchScheduleFn.js.map +1 -1
  43. package/operations/entry/dataLoader/getAllEntryRevisions.d.ts +3 -3
  44. package/operations/entry/dataLoader/getAllEntryRevisions.js +11 -24
  45. package/operations/entry/dataLoader/getAllEntryRevisions.js.map +1 -1
  46. package/operations/entry/dataLoader/getLatestRevisionByEntryId.d.ts +3 -3
  47. package/operations/entry/dataLoader/getLatestRevisionByEntryId.js +22 -32
  48. package/operations/entry/dataLoader/getLatestRevisionByEntryId.js.map +1 -1
  49. package/operations/entry/dataLoader/getPublishedRevisionByEntryId.d.ts +3 -3
  50. package/operations/entry/dataLoader/getPublishedRevisionByEntryId.js +22 -32
  51. package/operations/entry/dataLoader/getPublishedRevisionByEntryId.js.map +1 -1
  52. package/operations/entry/dataLoader/getRevisionById.d.ts +3 -3
  53. package/operations/entry/dataLoader/getRevisionById.js +24 -34
  54. package/operations/entry/dataLoader/getRevisionById.js.map +1 -1
  55. package/operations/entry/dataLoader/index.d.ts +5 -5
  56. package/operations/entry/dataLoader/index.js +10 -31
  57. package/operations/entry/dataLoader/index.js.map +1 -1
  58. package/operations/entry/dataLoader/types.d.ts +3 -4
  59. package/operations/entry/dataLoader/types.js +1 -5
  60. package/operations/entry/dataLoader/types.js.map +1 -1
  61. package/operations/entry/dataLoaders.d.ts +11 -12
  62. package/operations/entry/dataLoaders.js +15 -25
  63. package/operations/entry/dataLoaders.js.map +1 -1
  64. package/operations/entry/filtering/createExpressions.d.ts +5 -5
  65. package/operations/entry/filtering/createExpressions.js +27 -30
  66. package/operations/entry/filtering/createExpressions.js.map +1 -1
  67. package/operations/entry/filtering/createFields.d.ts +3 -3
  68. package/operations/entry/filtering/createFields.js +20 -22
  69. package/operations/entry/filtering/createFields.js.map +1 -1
  70. package/operations/entry/filtering/extractSort.d.ts +6 -6
  71. package/operations/entry/filtering/extractSort.js +38 -23
  72. package/operations/entry/filtering/extractSort.js.map +1 -1
  73. package/operations/entry/filtering/filter.d.ts +6 -6
  74. package/operations/entry/filtering/filter.js +13 -21
  75. package/operations/entry/filtering/filter.js.map +1 -1
  76. package/operations/entry/filtering/fullTextSearch.d.ts +3 -3
  77. package/operations/entry/filtering/fullTextSearch.js +6 -14
  78. package/operations/entry/filtering/fullTextSearch.js.map +1 -1
  79. package/operations/entry/filtering/getValue.js +1 -8
  80. package/operations/entry/filtering/getValue.js.map +1 -1
  81. package/operations/entry/filtering/index.d.ts +2 -2
  82. package/operations/entry/filtering/index.js +2 -19
  83. package/operations/entry/filtering/index.js.map +1 -1
  84. package/operations/entry/filtering/mapPlugins.d.ts +2 -2
  85. package/operations/entry/filtering/mapPlugins.js +3 -11
  86. package/operations/entry/filtering/mapPlugins.js.map +1 -1
  87. package/operations/entry/filtering/plugins/defaultFilterCreate.d.ts +2 -2
  88. package/operations/entry/filtering/plugins/defaultFilterCreate.js +6 -14
  89. package/operations/entry/filtering/plugins/defaultFilterCreate.js.map +1 -1
  90. package/operations/entry/filtering/plugins/index.d.ts +1 -1
  91. package/operations/entry/filtering/plugins/index.js +6 -12
  92. package/operations/entry/filtering/plugins/index.js.map +1 -1
  93. package/operations/entry/filtering/plugins/objectFilterCreate.d.ts +2 -2
  94. package/operations/entry/filtering/plugins/objectFilterCreate.js +13 -19
  95. package/operations/entry/filtering/plugins/objectFilterCreate.js.map +1 -1
  96. package/operations/entry/filtering/plugins/refFilterCreate.d.ts +3 -2
  97. package/operations/entry/filtering/plugins/refFilterCreate.js +18 -19
  98. package/operations/entry/filtering/plugins/refFilterCreate.js.map +1 -1
  99. package/operations/entry/filtering/plugins/searchableJsonFilterCreate.d.ts +2 -0
  100. package/operations/entry/filtering/plugins/searchableJsonFilterCreate.js +57 -0
  101. package/operations/entry/filtering/plugins/searchableJsonFilterCreate.js.map +1 -0
  102. package/operations/entry/filtering/sort.d.ts +6 -6
  103. package/operations/entry/filtering/sort.js +16 -20
  104. package/operations/entry/filtering/sort.js.map +1 -1
  105. package/operations/entry/filtering/systemFields.d.ts +2 -4
  106. package/operations/entry/filtering/systemFields.js +55 -29
  107. package/operations/entry/filtering/systemFields.js.map +1 -1
  108. package/operations/entry/filtering/transform.d.ts +1 -1
  109. package/operations/entry/filtering/transform.js +1 -8
  110. package/operations/entry/filtering/transform.js.map +1 -1
  111. package/operations/entry/filtering/types.d.ts +3 -3
  112. package/operations/entry/filtering/types.js +1 -5
  113. package/operations/entry/filtering/types.js.map +1 -1
  114. package/operations/entry/filtering/values.d.ts +1 -1
  115. package/operations/entry/filtering/values.js +4 -12
  116. package/operations/entry/filtering/values.js.map +1 -1
  117. package/operations/entry/filtering/where.js +1 -8
  118. package/operations/entry/filtering/where.js.map +1 -1
  119. package/operations/entry/index.d.ts +3 -4
  120. package/operations/entry/index.js +447 -495
  121. package/operations/entry/index.js.map +1 -1
  122. package/operations/entry/keys.d.ts +40 -2
  123. package/operations/entry/keys.js +53 -30
  124. package/operations/entry/keys.js.map +1 -1
  125. package/operations/group/index.d.ts +4 -4
  126. package/operations/group/index.js +35 -64
  127. package/operations/group/index.js.map +1 -1
  128. package/operations/model/index.d.ts +3 -3
  129. package/operations/model/index.js +36 -58
  130. package/operations/model/index.js.map +1 -1
  131. package/package.json +20 -26
  132. package/plugins/CmsEntryFieldFilterPathPlugin.d.ts +2 -2
  133. package/plugins/CmsEntryFieldFilterPathPlugin.js +4 -12
  134. package/plugins/CmsEntryFieldFilterPathPlugin.js.map +1 -1
  135. package/plugins/CmsEntryFieldFilterPlugin.d.ts +10 -10
  136. package/plugins/CmsEntryFieldFilterPlugin.js +2 -8
  137. package/plugins/CmsEntryFieldFilterPlugin.js.map +1 -1
  138. package/plugins/CmsEntryFieldSortingPlugin.d.ts +2 -2
  139. package/plugins/CmsEntryFieldSortingPlugin.js +3 -11
  140. package/plugins/CmsEntryFieldSortingPlugin.js.map +1 -1
  141. package/plugins/CmsFieldFilterValueTransformPlugin.d.ts +2 -2
  142. package/plugins/CmsFieldFilterValueTransformPlugin.js +2 -9
  143. package/plugins/CmsFieldFilterValueTransformPlugin.js.map +1 -1
  144. package/plugins/index.d.ts +4 -4
  145. package/plugins/index.js +4 -49
  146. package/plugins/index.js.map +1 -1
  147. package/types.d.ts +17 -19
  148. package/types.js +1 -8
  149. package/types.js.map +1 -1
  150. package/definitions/system.d.ts +0 -9
  151. package/definitions/system.js +0 -42
  152. package/definitions/system.js.map +0 -1
  153. package/dynamoDb/storage/date.d.ts +0 -3
  154. package/dynamoDb/storage/date.js +0 -84
  155. package/dynamoDb/storage/date.js.map +0 -1
  156. package/operations/system/index.d.ts +0 -7
  157. package/operations/system/index.js +0 -94
  158. package/operations/system/index.js.map +0 -1
@@ -1,32 +1,13 @@
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 _error = _interopRequireDefault(require("@webiny/error"));
9
- var _dataLoaders = require("./dataLoaders");
10
- var _types = require("@webiny/api-headless-cms/types");
11
- var _keys = require("./keys");
12
- var _batchWrite = require("@webiny/db-dynamodb/utils/batchWrite");
13
- var _query = require("@webiny/db-dynamodb/utils/query");
14
- var _cleanup = require("@webiny/db-dynamodb/utils/cleanup");
15
- var _cursor = require("@webiny/utils/cursor");
16
- var _zeroPad = require("@webiny/utils/zeroPad");
17
- var _apiHeadlessCms = require("@webiny/api-headless-cms");
18
- var _createFields = require("./filtering/createFields");
19
- var _filtering = require("./filtering");
20
- var _constants = require("@webiny/api-headless-cms/constants");
21
- const createType = () => {
22
- return "cms.entry";
23
- };
24
- const createLatestType = () => {
25
- return `${createType()}.l`;
26
- };
27
- const createPublishedType = () => {
28
- return `${createType()}.p`;
29
- };
1
+ import WebinyError 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 { StorageOperationsCmsModelPlugin, StorageTransformPlugin } from "@webiny/api-headless-cms";
7
+ import { createFields } from "./filtering/createFields.js";
8
+ import { filter, sort } from "./filtering/index.js";
9
+ import { isDeletedEntryMetaField, isEntryLevelEntryMetaField, isRestoredEntryMetaField, pickEntryMetaFields } from "@webiny/api-headless-cms/constants.js";
10
+ import { getBaseFieldType } from "@webiny/api-headless-cms/utils/getBaseFieldType.js";
30
11
  const convertToStorageEntry = params => {
31
12
  const {
32
13
  model,
@@ -55,8 +36,8 @@ const convertFromStorageEntry = params => {
55
36
  values
56
37
  };
57
38
  };
58
- const MAX_LIST_LIMIT = 10000;
59
- const createEntriesStorageOperations = params => {
39
+ const MAX_LIST_LIMIT = 1000000;
40
+ export const createEntriesStorageOperations = params => {
60
41
  const {
61
42
  entity,
62
43
  plugins
@@ -66,23 +47,25 @@ const createEntriesStorageOperations = params => {
66
47
  if (storageOperationsCmsModelPlugin) {
67
48
  return storageOperationsCmsModelPlugin;
68
49
  }
69
- storageOperationsCmsModelPlugin = plugins.oneByType(_apiHeadlessCms.StorageOperationsCmsModelPlugin.type);
50
+ storageOperationsCmsModelPlugin = plugins.oneByType(StorageOperationsCmsModelPlugin.type);
70
51
  return storageOperationsCmsModelPlugin;
71
52
  };
72
53
  const getStorageOperationsModel = model => {
73
54
  const plugin = getStorageOperationsCmsModelPlugin();
74
55
  return plugin.getModel(model);
75
56
  };
76
- const dataLoaders = new _dataLoaders.DataLoadersHandler({
57
+ const dataLoaders = new DataLoadersHandler({
77
58
  entity
78
59
  });
79
- const storageTransformPlugins = plugins.byType(_apiHeadlessCms.StorageTransformPlugin.type).reduce((collection, plugin) => {
80
- collection[plugin.fieldType] = plugin;
81
- return collection;
82
- }, {});
83
60
  const createStorageTransformCallable = model => {
61
+ // Cache StorageTransformPlugin to optimize execution.
62
+ const storageTransformPlugins = plugins.byType(StorageTransformPlugin.type).reduce((collection, plugin) => {
63
+ collection[plugin.fieldType] = plugin;
64
+ return collection;
65
+ }, {});
84
66
  return (field, value) => {
85
- const plugin = storageTransformPlugins[field.type];
67
+ const fieldType = getBaseFieldType(field);
68
+ const plugin = storageTransformPlugins[fieldType];
86
69
  if (!plugin) {
87
70
  return value;
88
71
  }
@@ -103,64 +86,55 @@ const createEntriesStorageOperations = params => {
103
86
  storageEntry: initialStorageEntry
104
87
  } = params;
105
88
  const model = getStorageOperationsModel(initialModel);
106
- const partitionKey = (0, _keys.createPartitionKey)({
107
- id: entry.id,
108
- locale: model.locale,
109
- tenant: model.tenant
110
- });
111
89
  const isPublished = entry.status === "published";
112
90
  const locked = isPublished ? true : entry.locked;
113
91
  const storageEntry = convertToStorageEntry({
114
92
  model,
115
93
  storageEntry: initialStorageEntry
116
94
  });
95
+ const storageEntryRevisionKeys = createEntryRevisionKeys(entry);
96
+ const storageEntryLatestKeys = createEntryLatestKeys(entry);
117
97
  /**
118
98
  * We need to:
119
99
  * - create new main entry item
120
100
  * - create new or update the latest entry item
121
101
  */
122
- const items = [entity.putBatch({
123
- ...storageEntry,
124
- locked,
125
- PK: partitionKey,
126
- SK: (0, _keys.createRevisionSortKey)(entry),
127
- TYPE: createType(),
128
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
129
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
130
- }), entity.putBatch({
131
- ...storageEntry,
132
- locked,
133
- PK: partitionKey,
134
- SK: (0, _keys.createLatestSortKey)(),
135
- TYPE: createLatestType(),
136
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
137
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
138
- })];
102
+ const entityBatch = entity.createEntityWriter({
103
+ put: [{
104
+ ...storageEntryRevisionKeys,
105
+ data: {
106
+ ...storageEntry,
107
+ locked
108
+ }
109
+ }, {
110
+ ...storageEntryLatestKeys,
111
+ data: {
112
+ ...storageEntry,
113
+ locked
114
+ }
115
+ }]
116
+ });
139
117
 
140
118
  /**
141
119
  * We need to create published entry if
142
120
  */
143
121
  if (isPublished) {
144
- items.push(entity.putBatch({
145
- ...storageEntry,
146
- locked,
147
- PK: partitionKey,
148
- SK: (0, _keys.createPublishedSortKey)(),
149
- TYPE: createLatestType(),
150
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "P"),
151
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
152
- }));
122
+ const storageEntryPublishedKeys = createEntryPublishedKeys(storageEntry);
123
+ entityBatch.put({
124
+ ...storageEntryPublishedKeys,
125
+ data: {
126
+ ...storageEntry,
127
+ locked
128
+ }
129
+ });
153
130
  }
154
131
  try {
155
- await (0, _batchWrite.batchWriteAll)({
156
- table: entity.table,
157
- items
158
- });
132
+ await entityBatch.execute();
159
133
  dataLoaders.clearAll({
160
134
  model
161
135
  });
162
136
  } catch (ex) {
163
- throw new _error.default(ex.message || "Could not insert data into the DynamoDB.", ex.code || "CREATE_ENTRY_ERROR", {
137
+ throw new WebinyError(ex.message || "Could not insert data into the DynamoDB.", ex.code || "CREATE_ENTRY_ERROR", {
164
138
  error: ex,
165
139
  entry
166
140
  });
@@ -173,45 +147,63 @@ const createEntriesStorageOperations = params => {
173
147
  storageEntry: initialStorageEntry
174
148
  } = params;
175
149
  const model = getStorageOperationsModel(initialModel);
176
- const partitionKey = (0, _keys.createPartitionKey)({
177
- id: entry.id,
178
- locale: model.locale,
179
- tenant: model.tenant
180
- });
181
150
  const storageEntry = convertToStorageEntry({
182
151
  storageEntry: initialStorageEntry,
183
152
  model
184
153
  });
154
+
185
155
  /**
186
156
  * We need to:
187
157
  * - create the main entry item
188
- * - update the last entry item to a current one
158
+ * - update the latest entry item to the current one
159
+ * - if the entry's status was set to "published":
160
+ * - update the published entry item to the current one
161
+ * - unpublish previously published revision (if any)
189
162
  */
190
- const items = [entity.putBatch({
191
- ...storageEntry,
192
- PK: partitionKey,
193
- SK: (0, _keys.createRevisionSortKey)(storageEntry),
194
- TYPE: createType(),
195
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
196
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
197
- }), entity.putBatch({
198
- ...storageEntry,
199
- PK: partitionKey,
200
- SK: (0, _keys.createLatestSortKey)(),
201
- TYPE: createLatestType(),
202
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
203
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
204
- })];
205
- try {
206
- await (0, _batchWrite.batchWriteAll)({
207
- table: entity.table,
208
- items
163
+ const entityBatch = entity.createEntityWriter({
164
+ put: [{
165
+ ...createEntryRevisionKeys(storageEntry),
166
+ data: {
167
+ ...storageEntry
168
+ }
169
+ }, {
170
+ ...createEntryLatestKeys(storageEntry),
171
+ data: {
172
+ ...storageEntry
173
+ }
174
+ }]
175
+ });
176
+ const isPublished = entry.status === "published";
177
+ if (isPublished) {
178
+ entityBatch.put({
179
+ ...createEntryPublishedKeys(storageEntry),
180
+ data: {
181
+ ...storageEntry
182
+ }
209
183
  });
184
+
185
+ // Unpublish previously published revision (if any).
186
+ const [publishedRevisionStorageEntry] = await dataLoaders.getPublishedRevisionByEntryId({
187
+ model,
188
+ ids: [entry.id]
189
+ });
190
+ if (publishedRevisionStorageEntry) {
191
+ entityBatch.put({
192
+ ...createEntryRevisionKeys(publishedRevisionStorageEntry),
193
+ data: {
194
+ ...publishedRevisionStorageEntry,
195
+ status: CONTENT_ENTRY_STATUS.UNPUBLISHED
196
+ }
197
+ });
198
+ }
199
+ }
200
+ try {
201
+ await entityBatch.execute();
210
202
  dataLoaders.clearAll({
211
203
  model
212
204
  });
213
205
  } catch (ex) {
214
- throw new _error.default(ex.message || "Could not create revision from given entry.", ex.code || "CREATE_REVISION_ERROR", {
206
+ throw new WebinyError(ex.message || "Could not create revision from given entry.", ex.code || "CREATE_REVISION_ERROR", {
215
207
  error: ex,
216
208
  entry,
217
209
  storageEntry
@@ -228,14 +220,8 @@ const createEntriesStorageOperations = params => {
228
220
  storageEntry: initialStorageEntry
229
221
  } = params;
230
222
  const model = getStorageOperationsModel(initialModel);
231
- const partitionKey = (0, _keys.createPartitionKey)({
232
- id: entry.id,
233
- locale: model.locale,
234
- tenant: model.tenant
235
- });
236
223
  const isPublished = entry.status === "published";
237
224
  const locked = isPublished ? true : entry.locked;
238
- const items = [];
239
225
  const storageEntry = convertToStorageEntry({
240
226
  model,
241
227
  storageEntry: initialStorageEntry
@@ -245,25 +231,24 @@ const createEntriesStorageOperations = params => {
245
231
  * - update the current entry
246
232
  * - update the latest entry if the current entry is the latest one
247
233
  */
248
- items.push(entity.putBatch({
249
- ...storageEntry,
250
- locked,
251
- PK: partitionKey,
252
- SK: (0, _keys.createRevisionSortKey)(storageEntry),
253
- TYPE: createType(),
254
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
255
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
256
- }));
234
+
235
+ const entityBatch = entity.createEntityWriter({
236
+ put: [{
237
+ ...createEntryRevisionKeys(storageEntry),
238
+ data: {
239
+ ...storageEntry,
240
+ locked
241
+ }
242
+ }]
243
+ });
257
244
  if (isPublished) {
258
- items.push(entity.putBatch({
259
- ...storageEntry,
260
- locked,
261
- PK: partitionKey,
262
- SK: (0, _keys.createPublishedSortKey)(),
263
- TYPE: createPublishedType(),
264
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "P"),
265
- GSI1_SK: (0, _keys.createGSISortKey)(storageEntry)
266
- }));
245
+ entityBatch.put({
246
+ ...createEntryPublishedKeys(storageEntry),
247
+ data: {
248
+ ...storageEntry,
249
+ locked
250
+ }
251
+ });
267
252
  }
268
253
 
269
254
  /**
@@ -273,58 +258,49 @@ const createEntriesStorageOperations = params => {
273
258
  if (latestStorageEntry) {
274
259
  const updatingLatestRevision = latestStorageEntry.id === entry.id;
275
260
  if (updatingLatestRevision) {
276
- items.push(entity.putBatch({
277
- ...storageEntry,
278
- locked,
279
- PK: partitionKey,
280
- SK: (0, _keys.createLatestSortKey)(),
281
- TYPE: createLatestType(),
282
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
283
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
284
- }));
261
+ entityBatch.put({
262
+ ...createEntryLatestKeys(storageEntry),
263
+ data: {
264
+ ...storageEntry,
265
+ locked
266
+ }
267
+ });
285
268
  } else {
286
269
  /**
287
270
  * If not updating latest revision, we still want to update the latest revision's
288
271
  * entry-level meta fields to match the current revision's entry-level meta fields.
289
272
  */
290
- const updatedEntryLevelMetaFields = (0, _constants.pickEntryMetaFields)(entry, _constants.isEntryLevelEntryMetaField);
273
+ const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
291
274
 
292
275
  /**
293
276
  * First we update the regular DynamoDB table. Two updates are needed:
294
277
  * - one for the actual revision record
295
278
  * - one for the latest record
296
279
  */
297
- items.push(entity.putBatch({
298
- ...latestStorageEntry,
299
- ...updatedEntryLevelMetaFields,
300
- PK: partitionKey,
301
- SK: (0, _keys.createRevisionSortKey)(latestStorageEntry),
302
- TYPE: createType(),
303
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
304
- GSI1_SK: (0, _keys.createGSISortKey)(latestStorageEntry)
305
- }));
306
- items.push(entity.putBatch({
307
- ...latestStorageEntry,
308
- ...updatedEntryLevelMetaFields,
309
- PK: partitionKey,
310
- SK: (0, _keys.createLatestSortKey)(),
311
- TYPE: createLatestType(),
312
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
313
- GSI1_SK: (0, _keys.createGSISortKey)(latestStorageEntry)
314
- }));
280
+ entityBatch.put({
281
+ ...createEntryRevisionKeys(latestStorageEntry),
282
+ data: {
283
+ ...latestStorageEntry,
284
+ ...updatedEntryLevelMetaFields
285
+ }
286
+ });
287
+ entityBatch.put({
288
+ ...createEntryLatestKeys(latestStorageEntry),
289
+ data: {
290
+ ...latestStorageEntry,
291
+ ...updatedEntryLevelMetaFields
292
+ }
293
+ });
315
294
  }
316
295
  }
317
296
  try {
318
- await (0, _batchWrite.batchWriteAll)({
319
- table: entity.table,
320
- items
321
- });
297
+ await entityBatch.execute();
322
298
  dataLoaders.clearAll({
323
299
  model
324
300
  });
325
301
  return initialStorageEntry;
326
302
  } catch (ex) {
327
- throw new _error.default(ex.message || "Could not update entry.", ex.code || "UPDATE_ERROR", {
303
+ throw new WebinyError(ex.message || "Could not update entry.", ex.code || "UPDATE_ERROR", {
328
304
  error: ex,
329
305
  entry,
330
306
  latestStorageEntry
@@ -341,40 +317,41 @@ const createEntriesStorageOperations = params => {
341
317
  /**
342
318
  * First we need to load all the revisions and published / latest entry.
343
319
  */
344
- const queryAllParams = {
345
- entity,
346
- partitionKey: (0, _keys.createPartitionKey)({
347
- id,
348
- locale: model.locale,
349
- tenant: model.tenant
350
- }),
320
+ const partitionKey = createPartitionKey({
321
+ id,
322
+ tenant: model.tenant
323
+ });
324
+ const records = await entity.queryAll({
325
+ partitionKey,
351
326
  options: {
352
327
  gte: " "
353
328
  }
354
- };
355
- const records = await (0, _query.queryAll)(queryAllParams);
329
+ });
356
330
  /**
357
331
  * Then create the batch writes for the DynamoDB, with the updated folderId.
358
332
  */
359
- const items = records.map(item => {
360
- return entity.putBatch({
361
- ...item,
362
- location: {
363
- ...item.location,
364
- folderId
365
- }
366
- });
333
+ const entityBatch = entity.createEntityWriter({
334
+ put: records.map(item => {
335
+ return {
336
+ ...item,
337
+ data: {
338
+ ...item.data,
339
+ location: {
340
+ ...item.data.location,
341
+ folderId
342
+ }
343
+ }
344
+ };
345
+ })
367
346
  });
347
+
368
348
  /**
369
349
  * And finally write it...
370
350
  */
371
351
  try {
372
- await (0, _batchWrite.batchWriteAll)({
373
- table: entity.table,
374
- items
375
- });
352
+ await entityBatch.execute();
376
353
  } catch (ex) {
377
- throw _error.default.from(ex, {
354
+ throw WebinyError.from(ex, {
378
355
  message: "Could not move records to a new folder.",
379
356
  data: {
380
357
  id,
@@ -393,26 +370,27 @@ const createEntriesStorageOperations = params => {
393
370
  /**
394
371
  * First we need to load all the revisions and published / latest entries.
395
372
  */
396
- const queryAllParams = {
397
- entity,
398
- partitionKey: (0, _keys.createPartitionKey)({
399
- id: entry.id,
400
- locale: model.locale,
401
- tenant: model.tenant
402
- }),
403
- options: {
404
- gte: " "
405
- }
406
- };
373
+
407
374
  let records = [];
408
375
  try {
409
- records = await (0, _query.queryAll)(queryAllParams);
376
+ records = await entity.queryAll({
377
+ partitionKey: createPartitionKey({
378
+ id: entry.id,
379
+ tenant: model.tenant
380
+ }),
381
+ options: {
382
+ gte: " "
383
+ }
384
+ });
410
385
  } catch (ex) {
411
- throw new _error.default(ex.message || "Could not load all records.", ex.code || "LOAD_ALL_RECORDS_ERROR", {
386
+ throw new WebinyError(ex.message || "Could not load all records.", ex.code || "LOAD_ALL_RECORDS_ERROR", {
412
387
  error: ex,
413
388
  id: entry.id
414
389
  });
415
390
  }
391
+ if (records.length === 0) {
392
+ return;
393
+ }
416
394
  const storageEntry = convertToStorageEntry({
417
395
  model,
418
396
  storageEntry: initialStorageEntry
@@ -421,30 +399,32 @@ const createEntriesStorageOperations = params => {
421
399
  /**
422
400
  * Let's pick the `deleted` meta fields from the storage entry.
423
401
  */
424
- const updatedDeletedMetaFields = (0, _constants.pickEntryMetaFields)(storageEntry, _constants.isDeletedEntryMetaField);
402
+ const updatedDeletedMetaFields = pickEntryMetaFields(storageEntry, isDeletedEntryMetaField);
425
403
 
426
404
  /**
427
405
  * Then create the batch writes for the DynamoDB, with the updated data.
428
406
  */
429
- const items = records.map(record => {
430
- return entity.putBatch({
431
- ...record,
432
- ...updatedDeletedMetaFields,
433
- wbyDeleted: storageEntry.wbyDeleted,
434
- location: storageEntry.location,
435
- binOriginalFolderId: storageEntry.binOriginalFolderId
436
- });
407
+ const entityBatch = entity.createEntityWriter({
408
+ put: records.map(record => {
409
+ return {
410
+ ...record,
411
+ data: {
412
+ ...record.data,
413
+ ...updatedDeletedMetaFields,
414
+ wbyDeleted: storageEntry.wbyDeleted,
415
+ location: storageEntry.location,
416
+ binOriginalFolderId: storageEntry.binOriginalFolderId
417
+ }
418
+ };
419
+ })
437
420
  });
438
421
  /**
439
422
  * And finally write it...
440
423
  */
441
424
  try {
442
- await (0, _batchWrite.batchWriteAll)({
443
- table: entity.table,
444
- items
445
- });
425
+ await entityBatch.execute();
446
426
  } catch (ex) {
447
- throw new _error.default(ex.message || "Could not move the entry to the bin.", ex.code || "MOVE_ENTRY_TO_BIN_ERROR", {
427
+ throw new WebinyError(ex.message || "Could not move the entry to the bin.", ex.code || "MOVE_ENTRY_TO_BIN_ERROR", {
448
428
  error: ex,
449
429
  entry,
450
430
  storageEntry
@@ -457,44 +437,41 @@ const createEntriesStorageOperations = params => {
457
437
  } = params;
458
438
  const id = entry.id || entry.entryId;
459
439
  const model = getStorageOperationsModel(initialModel);
460
- const queryAllParams = {
461
- entity,
462
- partitionKey: (0, _keys.createPartitionKey)({
463
- id,
464
- locale: model.locale,
465
- tenant: model.tenant
466
- }),
467
- options: {
468
- gte: " "
469
- }
470
- };
440
+ const partitionKey = createPartitionKey({
441
+ id,
442
+ tenant: model.tenant
443
+ });
471
444
  let records = [];
472
445
  try {
473
- records = await (0, _query.queryAll)(queryAllParams);
446
+ records = await entity.queryAll({
447
+ partitionKey,
448
+ options: {
449
+ gte: " "
450
+ }
451
+ });
474
452
  } catch (ex) {
475
- throw new _error.default(ex.message || "Could not load all records.", ex.code || "LOAD_ALL_RECORDS_ERROR", {
453
+ throw new WebinyError(ex.message || "Could not load all records.", ex.code || "LOAD_ALL_RECORDS_ERROR", {
476
454
  error: ex,
477
455
  id
478
456
  });
479
457
  }
480
- const items = records.map(item => {
481
- return entity.deleteBatch({
482
- PK: item.PK,
483
- SK: item.SK
484
- });
458
+ const entityBatch = entity.createEntityWriter({
459
+ delete: records.map(item => {
460
+ return {
461
+ PK: item.PK,
462
+ SK: item.SK
463
+ };
464
+ })
485
465
  });
486
466
  try {
487
- await (0, _batchWrite.batchWriteAll)({
488
- table: entity.table,
489
- items
490
- });
467
+ await entityBatch.execute();
491
468
  dataLoaders.clearAll({
492
469
  model
493
470
  });
494
471
  } catch (ex) {
495
- throw new _error.default(ex.message || "Could not delete the entry.", ex.code || "DELETE_ENTRY_ERROR", {
472
+ throw new WebinyError(ex.message || "Could not delete the entry.", ex.code || "DELETE_ENTRY_ERROR", {
496
473
  error: ex,
497
- partitionKey: queryAllParams.partitionKey,
474
+ partitionKey,
498
475
  id
499
476
  });
500
477
  }
@@ -509,26 +486,26 @@ const createEntriesStorageOperations = params => {
509
486
  /**
510
487
  * First we need to load all the revisions and published / latest entries.
511
488
  */
512
- const queryAllParams = {
513
- entity,
514
- partitionKey: (0, _keys.createPartitionKey)({
515
- id: entry.id,
516
- locale: model.locale,
517
- tenant: model.tenant
518
- }),
519
- options: {
520
- gte: " "
521
- }
522
- };
523
489
  let records = [];
524
490
  try {
525
- records = await (0, _query.queryAll)(queryAllParams);
491
+ records = await entity.queryAll({
492
+ partitionKey: createPartitionKey({
493
+ id: entry.id,
494
+ tenant: model.tenant
495
+ }),
496
+ options: {
497
+ gte: " "
498
+ }
499
+ });
526
500
  } catch (ex) {
527
- throw new _error.default(ex.message || "Could not load all records.", ex.code || "LOAD_ALL_RECORDS_ERROR", {
501
+ throw new WebinyError(ex.message || "Could not load all records.", ex.code || "LOAD_ALL_RECORDS_ERROR", {
528
502
  error: ex,
529
503
  id: entry.id
530
504
  });
531
505
  }
506
+ if (records.length === 0) {
507
+ return initialStorageEntry;
508
+ }
532
509
  const storageEntry = convertToStorageEntry({
533
510
  model,
534
511
  storageEntry: initialStorageEntry
@@ -537,30 +514,33 @@ const createEntriesStorageOperations = params => {
537
514
  /**
538
515
  * Let's pick the `restored` meta fields from the storage entry.
539
516
  */
540
- const updatedRestoredMetaFields = (0, _constants.pickEntryMetaFields)(storageEntry, _constants.isRestoredEntryMetaField);
541
- const items = records.map(record => {
542
- return entity.putBatch({
543
- ...record,
544
- ...updatedRestoredMetaFields,
545
- wbyDeleted: storageEntry.wbyDeleted,
546
- location: storageEntry.location,
547
- binOriginalFolderId: storageEntry.binOriginalFolderId
548
- });
517
+ const updatedRestoredMetaFields = pickEntryMetaFields(storageEntry, isRestoredEntryMetaField);
518
+ const entityBatch = entity.createEntityWriter({
519
+ put: records.map(record => {
520
+ return {
521
+ ...record,
522
+ data: {
523
+ ...record.data,
524
+ ...updatedRestoredMetaFields,
525
+ wbyDeleted: storageEntry.wbyDeleted,
526
+ location: storageEntry.location,
527
+ binOriginalFolderId: storageEntry.binOriginalFolderId
528
+ }
529
+ };
530
+ })
549
531
  });
532
+
550
533
  /**
551
534
  * And finally write it...
552
535
  */
553
536
  try {
554
- await (0, _batchWrite.batchWriteAll)({
555
- table: entity.table,
556
- items
557
- });
537
+ await entityBatch.execute();
558
538
  dataLoaders.clearAll({
559
539
  model
560
540
  });
561
541
  return initialStorageEntry;
562
542
  } catch (ex) {
563
- throw new _error.default(ex.message || "Could not restore the entry from the bin.", ex.code || "RESTORE_ENTRY_ERROR", {
543
+ throw new WebinyError(ex.message || "Could not restore the entry from the bin.", ex.code || "RESTORE_ENTRY_ERROR", {
564
544
  error: ex,
565
545
  entry,
566
546
  storageEntry
@@ -574,61 +554,55 @@ const createEntriesStorageOperations = params => {
574
554
  latestStorageEntry: initialLatestStorageEntry
575
555
  } = params;
576
556
  const model = getStorageOperationsModel(initialModel);
577
- const partitionKey = (0, _keys.createPartitionKey)({
557
+ const partitionKey = createPartitionKey({
578
558
  id: entry.id,
579
- locale: model.locale,
580
559
  tenant: model.tenant
581
560
  });
582
- const items = [entity.deleteBatch({
583
- PK: partitionKey,
584
- SK: (0, _keys.createRevisionSortKey)(entry)
585
- })];
561
+ const entityBatch = entity.createEntityWriter({
562
+ delete: [{
563
+ PK: partitionKey,
564
+ SK: createRevisionSortKey(entry)
565
+ }]
566
+ });
586
567
  const publishedStorageEntry = await getPublishedRevisionByEntryId(model, entry);
587
568
 
588
569
  /**
589
570
  * If revision we are deleting is the published one as well, we need to delete those records as well.
590
571
  */
591
572
  if (publishedStorageEntry && entry.id === publishedStorageEntry.id) {
592
- items.push(entity.deleteBatch({
573
+ entityBatch.delete({
593
574
  PK: partitionKey,
594
- SK: (0, _keys.createPublishedSortKey)()
595
- }));
575
+ SK: createPublishedSortKey()
576
+ });
596
577
  }
597
578
  if (initialLatestStorageEntry) {
598
579
  const latestStorageEntry = convertToStorageEntry({
599
580
  storageEntry: initialLatestStorageEntry,
600
581
  model
601
582
  });
602
- items.push(entity.putBatch({
603
- ...latestStorageEntry,
604
- PK: partitionKey,
605
- SK: (0, _keys.createLatestSortKey)(),
606
- TYPE: createLatestType(),
607
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
608
- GSI1_SK: (0, _keys.createGSISortKey)(latestStorageEntry)
609
- }));
583
+ entityBatch.put({
584
+ ...createEntryLatestKeys(latestStorageEntry),
585
+ data: {
586
+ ...latestStorageEntry
587
+ }
588
+ });
610
589
 
611
590
  // Do an update on the latest revision. We need to update the latest revision's
612
591
  // entry-level meta fields to match the previous revision's entry-level meta fields.
613
- items.push(entity.putBatch({
614
- ...initialLatestStorageEntry,
615
- PK: partitionKey,
616
- SK: (0, _keys.createRevisionSortKey)(initialLatestStorageEntry),
617
- TYPE: createType(),
618
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
619
- GSI1_SK: (0, _keys.createGSISortKey)(initialLatestStorageEntry)
620
- }));
592
+ entityBatch.put({
593
+ ...createEntryRevisionKeys(latestStorageEntry),
594
+ data: {
595
+ ...latestStorageEntry
596
+ }
597
+ });
621
598
  }
622
599
  try {
623
- await (0, _batchWrite.batchWriteAll)({
624
- table: entity.table,
625
- items
626
- });
600
+ await entityBatch.execute();
627
601
  dataLoaders.clearAll({
628
602
  model
629
603
  });
630
604
  } catch (ex) {
631
- throw new _error.default(ex.message, ex.code, {
605
+ throw new WebinyError(ex.message, ex.code, {
632
606
  error: ex,
633
607
  entry,
634
608
  latestEntry
@@ -650,50 +624,37 @@ const createEntriesStorageOperations = params => {
650
624
  /**
651
625
  * Then we need to construct the queries for all the revisions and entries.
652
626
  */
653
- const items = [];
627
+
628
+ const entityBatch = entity.createEntityWriter();
654
629
  for (const id of entries) {
655
- /**
656
- * Latest item.
657
- */
658
- items.push(entity.deleteBatch({
659
- PK: (0, _keys.createPartitionKey)({
660
- id,
661
- locale: model.locale,
662
- tenant: model.tenant
663
- }),
630
+ const partitionKey = createPartitionKey({
631
+ id,
632
+ tenant: model.tenant
633
+ });
634
+ entityBatch.delete({
635
+ PK: partitionKey,
664
636
  SK: "L"
665
- }));
666
- /**
667
- * Published item.
668
- */
669
- items.push(entity.deleteBatch({
670
- PK: (0, _keys.createPartitionKey)({
671
- id,
672
- locale: model.locale,
673
- tenant: model.tenant
674
- }),
637
+ });
638
+ entityBatch.delete({
639
+ PK: partitionKey,
675
640
  SK: "P"
676
- }));
641
+ });
677
642
  }
678
643
  /**
679
644
  * Exact revisions of all the entries
680
645
  */
681
646
  for (const revision of revisions) {
682
- items.push(entity.deleteBatch({
683
- PK: (0, _keys.createPartitionKey)({
647
+ entityBatch.delete({
648
+ PK: createPartitionKey({
684
649
  id: revision.id,
685
- locale: model.locale,
686
650
  tenant: model.tenant
687
651
  }),
688
- SK: (0, _keys.createRevisionSortKey)({
652
+ SK: createRevisionSortKey({
689
653
  version: revision.version
690
654
  })
691
- }));
655
+ });
692
656
  }
693
- await (0, _batchWrite.batchWriteAll)({
694
- table: entity.table,
695
- items
696
- });
657
+ await entityBatch.execute();
697
658
  };
698
659
  const getLatestRevisionByEntryId = async (initialModel, params) => {
699
660
  const model = getStorageOperationsModel(initialModel);
@@ -798,44 +759,34 @@ const createEntriesStorageOperations = params => {
798
759
  entryId,
799
760
  version
800
761
  } = params;
801
- const queryParams = {
802
- entity,
803
- partitionKey: (0, _keys.createPartitionKey)({
804
- tenant: model.tenant,
805
- locale: model.locale,
806
- id: entryId
807
- }),
762
+ const partitionKey = createPartitionKey({
763
+ tenant: model.tenant,
764
+ id: entryId
765
+ });
766
+ const unfilteredRevisions = await entity.queryAll({
767
+ partitionKey,
808
768
  options: {
809
- lt: `REV#${(0, _zeroPad.zeroPad)(version)}`,
810
- /**
811
- * We need to have extra checks because DynamoDB will return published or latest record if there is no REV# record.
812
- */
813
- filters: [{
814
- attr: "TYPE",
815
- eq: createType()
816
- }, {
817
- attr: "version",
818
- lt: version
819
- }],
769
+ beginsWith: `REV#`,
820
770
  reverse: true
821
771
  }
822
- };
772
+ });
773
+ const filteredRevisions = unfilteredRevisions.filter(item => {
774
+ return item.data.version < version;
775
+ });
776
+ const storageEntry = filteredRevisions[0];
777
+ if (!storageEntry) {
778
+ return null;
779
+ }
823
780
  try {
824
- const result = await (0, _query.queryOne)(queryParams);
825
- const storageEntry = (0, _cleanup.cleanupItem)(entity, result);
826
- if (!storageEntry) {
827
- return null;
828
- }
829
781
  return convertFromStorageEntry({
830
- storageEntry,
782
+ storageEntry: storageEntry.data,
831
783
  model
832
784
  });
833
785
  } catch (ex) {
834
- throw new _error.default(ex.message || "Could not get previous version of given entry.", ex.code || "GET_PREVIOUS_VERSION_ERROR", {
786
+ throw new WebinyError(ex.message || "Could not get previous version of given entry.", ex.code || "GET_PREVIOUS_VERSION_ERROR", {
835
787
  ...params,
836
788
  error: ex,
837
- partitionKey: queryParams.partitionKey,
838
- options: queryParams.options,
789
+ partitionKey,
839
790
  model
840
791
  });
841
792
  }
@@ -852,22 +803,22 @@ const createEntriesStorageOperations = params => {
852
803
  } = params;
853
804
  const limit = initialLimit <= 0 || initialLimit >= MAX_LIST_LIMIT ? MAX_LIST_LIMIT : initialLimit;
854
805
  const type = initialWhere.published ? "P" : "L";
855
- const queryAllParams = {
856
- entity,
857
- partitionKey: (0, _keys.createGSIPartitionKey)(model, type),
858
- options: {
859
- index: "GSI1",
860
- gte: " "
861
- }
806
+ const partitionKey = createGSIPartitionKey(model, type);
807
+ const options = {
808
+ index: "GSI1",
809
+ gte: " "
862
810
  };
863
811
  let storageEntries = [];
864
812
  try {
865
- storageEntries = await (0, _query.queryAll)(queryAllParams);
813
+ storageEntries = await entity.queryAll({
814
+ partitionKey,
815
+ options
816
+ });
866
817
  } catch (ex) {
867
- throw new _error.default(ex.message, "QUERY_ENTRIES_ERROR", {
818
+ throw new WebinyError(ex.message, "QUERY_ENTRIES_ERROR", {
868
819
  error: ex,
869
- partitionKey: queryAllParams.partitionKey,
870
- options: queryAllParams.options
820
+ partitionKey,
821
+ options
871
822
  });
872
823
  }
873
824
  if (storageEntries.length === 0) {
@@ -887,7 +838,7 @@ const createEntriesStorageOperations = params => {
887
838
  * We need an object containing field, transformers and paths.
888
839
  * Just build it here and pass on into other methods that require it to avoid mapping multiple times.
889
840
  */
890
- const modelFields = (0, _createFields.createFields)({
841
+ const modelFields = createFields({
891
842
  plugins,
892
843
  fields: model.fields
893
844
  });
@@ -899,7 +850,7 @@ const createEntriesStorageOperations = params => {
899
850
  */
900
851
  const records = await Promise.all(storageEntries.map(async storageEntry => {
901
852
  const entry = convertFromStorageEntry({
902
- storageEntry,
853
+ storageEntry: storageEntry.data,
903
854
  model
904
855
  });
905
856
  for (const field of model.fields) {
@@ -911,7 +862,7 @@ const createEntriesStorageOperations = params => {
911
862
  * Filter the read items via the code.
912
863
  * It will build the filters out of the where input and transform the values it is using.
913
864
  */
914
- const filteredItems = (0, _filtering.filter)({
865
+ const filteredItems = filter({
915
866
  items: records,
916
867
  where,
917
868
  plugins,
@@ -927,14 +878,14 @@ const createEntriesStorageOperations = params => {
927
878
  * Sorting is also done via the code.
928
879
  * It takes the sort input and sorts by it via the lodash sortBy method.
929
880
  */
930
- const sortedItems = (0, _filtering.sort)({
881
+ const sortedItems = sort({
931
882
  model,
932
883
  plugins,
933
884
  items: filteredItems,
934
885
  sort: sortBy,
935
886
  fields: modelFields
936
887
  });
937
- const start = parseInt((0, _cursor.decodeCursor)(after) || "0") || 0;
888
+ const start = parseInt(decodeCursor(after) || "0") || 0;
938
889
  const hasMoreItems = totalCount > start + limit;
939
890
  const end = limit > totalCount + start + limit ? undefined : start + limit;
940
891
  const slicedItems = sortedItems.slice(start, end);
@@ -942,12 +893,12 @@ const createEntriesStorageOperations = params => {
942
893
  * Although we do not need a cursor here, we will use it as such to keep it standardized.
943
894
  * Number is simply encoded.
944
895
  */
945
- const cursor = totalCount > start + limit ? (0, _cursor.encodeCursor)(`${start + limit}`) : null;
896
+ const cursor = encodeCursor(`${start + limit}`);
946
897
  return {
947
898
  hasMoreItems,
948
899
  totalCount,
949
900
  cursor,
950
- items: (0, _cleanup.cleanupItems)(entity, slicedItems)
901
+ items: slicedItems
951
902
  };
952
903
  };
953
904
  const get = async (initialModel, params) => {
@@ -966,114 +917,125 @@ const createEntriesStorageOperations = params => {
966
917
  storageEntry: initialStorageEntry
967
918
  } = params;
968
919
  const model = getStorageOperationsModel(initialModel);
969
- const partitionKey = (0, _keys.createPartitionKey)({
970
- id: entry.id,
971
- locale: model.locale,
972
- tenant: model.tenant
973
- });
974
920
 
975
921
  /**
976
922
  * We need the latest and published entries to see if something needs to be updated alongside the publishing one.
977
923
  */
978
924
  const initialLatestStorageEntry = await getLatestRevisionByEntryId(model, entry);
925
+ if (!initialLatestStorageEntry) {
926
+ throw new WebinyError(`Could not publish entry. Could not load latest ("L") record.`, "PUBLISH_ERROR", {
927
+ entry
928
+ });
929
+ }
979
930
  const initialPublishedStorageEntry = await getPublishedRevisionByEntryId(model, entry);
980
931
  const storageEntry = convertToStorageEntry({
981
932
  model,
982
933
  storageEntry: initialStorageEntry
983
934
  });
984
- /**
985
- * We need to update:
986
- * - current entry revision sort key
987
- * - published sort key
988
- * - the latest sort key - if entry updated is actually latest
989
- * - previous published entry to unpublished status - if any previously published entry
990
- */
991
- const items = [entity.putBatch({
992
- ...storageEntry,
993
- PK: partitionKey,
994
- SK: (0, _keys.createRevisionSortKey)(entry),
995
- TYPE: createType(),
996
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
997
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
998
- }), entity.putBatch({
999
- ...storageEntry,
1000
- PK: partitionKey,
1001
- SK: (0, _keys.createPublishedSortKey)(),
1002
- TYPE: createPublishedType(),
1003
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "P"),
1004
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
1005
- })];
1006
- if (initialLatestStorageEntry) {
1007
- const publishingLatestRevision = entry.id === initialLatestStorageEntry.id;
1008
- if (publishingLatestRevision) {
1009
- // We want to update current latest record because of the status (`status: 'published'`) update.
1010
- items.push(entity.putBatch({
1011
- ...storageEntry,
1012
- PK: partitionKey,
1013
- SK: (0, _keys.createLatestSortKey)(),
1014
- TYPE: createLatestType(),
1015
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
1016
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
1017
- }));
1018
- } else {
1019
- const latestStorageEntry = convertToStorageEntry({
1020
- storageEntry: initialLatestStorageEntry,
1021
- model
1022
- });
1023
935
 
1024
- // If the published revision is not the latest one, we still need to
1025
- // update the latest record with the new values of entry-level meta fields.
1026
- const updatedEntryLevelMetaFields = (0, _constants.pickEntryMetaFields)(entry, _constants.isEntryLevelEntryMetaField);
936
+ // 1. Update REV# and P records with new data.
937
+ const entityBatch = entity.createEntityWriter({
938
+ put: [{
939
+ ...createEntryRevisionKeys(storageEntry),
940
+ data: {
941
+ ...storageEntry
942
+ }
943
+ }, {
944
+ ...createEntryPublishedKeys(storageEntry),
945
+ data: {
946
+ ...storageEntry
947
+ }
948
+ }]
949
+ });
1027
950
 
1028
- // 1. Update actual revision record.
1029
- items.push(entity.putBatch({
1030
- ...latestStorageEntry,
1031
- ...updatedEntryLevelMetaFields,
1032
- PK: partitionKey,
1033
- SK: (0, _keys.createRevisionSortKey)(latestStorageEntry),
1034
- TYPE: createType(),
1035
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
1036
- GSI1_SK: (0, _keys.createGSISortKey)(latestStorageEntry)
1037
- }));
951
+ // 2. When it comes to the latest record, we need to perform a couple of different
952
+ // updates, based on whether the entry being published is the latest revision or not.
953
+ const publishedRevisionId = initialPublishedStorageEntry?.id;
954
+ const publishingLatestRevision = entry.id === initialLatestStorageEntry.id;
955
+ if (publishingLatestRevision) {
956
+ // 2.1 If we're publishing the latest revision, we first need to update the L record.
957
+ entityBatch.put({
958
+ ...createEntryLatestKeys(storageEntry),
959
+ data: {
960
+ ...storageEntry
961
+ }
962
+ });
1038
963
 
1039
- // 2. Update latest record.
1040
- items.push(entity.putBatch({
1041
- ...latestStorageEntry,
1042
- ...updatedEntryLevelMetaFields,
1043
- PK: partitionKey,
1044
- SK: (0, _keys.createLatestSortKey)(),
1045
- TYPE: createLatestType(),
1046
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
1047
- GSI1_SK: (0, _keys.createGSISortKey)(latestStorageEntry)
1048
- }));
964
+ // 2.2 Additionally, if we have a previously published entry, we need to mark it as unpublished.
965
+ if (publishedRevisionId && publishedRevisionId !== entry.id) {
966
+ const publishedStorageEntry = convertToStorageEntry({
967
+ storageEntry: initialPublishedStorageEntry,
968
+ model
969
+ });
970
+ entityBatch.put({
971
+ ...createEntryRevisionKeys(publishedStorageEntry),
972
+ data: {
973
+ ...publishedStorageEntry,
974
+ status: CONTENT_ENTRY_STATUS.UNPUBLISHED
975
+ }
976
+ });
1049
977
  }
1050
- }
1051
- if (initialPublishedStorageEntry && initialPublishedStorageEntry.id !== entry.id) {
1052
- const publishedStorageEntry = convertToStorageEntry({
1053
- storageEntry: initialPublishedStorageEntry,
978
+ } else {
979
+ // 2.3 If the published revision is not the latest one, the situation is a bit
980
+ // more complex. We first need to update the L and REV# records with the new
981
+ // values of *only entry-level* meta fields.
982
+ const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
983
+ const latestStorageEntry = convertToStorageEntry({
984
+ storageEntry: initialLatestStorageEntry,
1054
985
  model
1055
986
  });
1056
- items.push(entity.putBatch({
1057
- ...publishedStorageEntry,
1058
- PK: partitionKey,
1059
- SK: (0, _keys.createRevisionSortKey)(publishedStorageEntry),
1060
- TYPE: createType(),
1061
- status: _types.CONTENT_ENTRY_STATUS.UNPUBLISHED,
1062
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
1063
- GSI1_SK: (0, _keys.createGSISortKey)(publishedStorageEntry)
1064
- }));
987
+
988
+ // 2.3.1 Update L record. Apart from updating the entry-level meta fields, we also need
989
+ // to change the status from "published" to "unpublished" (if the status is set to "published").
990
+ let latestRevisionStatus = latestStorageEntry.status;
991
+ if (latestRevisionStatus === CONTENT_ENTRY_STATUS.PUBLISHED) {
992
+ latestRevisionStatus = CONTENT_ENTRY_STATUS.UNPUBLISHED;
993
+ }
994
+ const latestStorageEntryFields = {
995
+ ...latestStorageEntry,
996
+ ...updatedEntryLevelMetaFields,
997
+ status: latestRevisionStatus
998
+ };
999
+ entityBatch.put({
1000
+ ...createEntryLatestKeys(latestStorageEntryFields),
1001
+ data: {
1002
+ ...latestStorageEntryFields
1003
+ }
1004
+ });
1005
+
1006
+ // 2.3.2 Update REV# record.
1007
+ entityBatch.put({
1008
+ ...createEntryRevisionKeys(latestStorageEntryFields),
1009
+ data: {
1010
+ ...latestStorageEntryFields
1011
+ }
1012
+ });
1013
+
1014
+ // 2.3.3 Finally, if we got a published entry, but it wasn't the latest one, we need to take
1015
+ // an extra step and mark it as unpublished.
1016
+ const publishedRevisionDifferentFromLatest = publishedRevisionId && publishedRevisionId !== latestStorageEntry.id;
1017
+ if (publishedRevisionDifferentFromLatest) {
1018
+ const publishedStorageEntry = convertToStorageEntry({
1019
+ storageEntry: initialPublishedStorageEntry,
1020
+ model
1021
+ });
1022
+ entityBatch.put({
1023
+ ...createEntryRevisionKeys(publishedStorageEntry),
1024
+ data: {
1025
+ ...publishedStorageEntry,
1026
+ status: CONTENT_ENTRY_STATUS.UNPUBLISHED
1027
+ }
1028
+ });
1029
+ }
1065
1030
  }
1066
1031
  try {
1067
- await (0, _batchWrite.batchWriteAll)({
1068
- table: entity.table,
1069
- items
1070
- });
1032
+ await entityBatch.execute();
1071
1033
  dataLoaders.clearAll({
1072
1034
  model
1073
1035
  });
1074
1036
  return initialStorageEntry;
1075
1037
  } catch (ex) {
1076
- throw new _error.default(ex.message || "Could not execute the publishing batch.", ex.code || "PUBLISH_ERROR", {
1038
+ throw new WebinyError(ex.message || "Could not execute the publishing batch.", ex.code || "PUBLISH_ERROR", {
1077
1039
  entry,
1078
1040
  latestStorageEntry: initialLatestStorageEntry,
1079
1041
  publishedStorageEntry: initialPublishedStorageEntry
@@ -1086,9 +1048,8 @@ const createEntriesStorageOperations = params => {
1086
1048
  storageEntry: initialStorageEntry
1087
1049
  } = params;
1088
1050
  const model = getStorageOperationsModel(initialModel);
1089
- const partitionKey = (0, _keys.createPartitionKey)({
1051
+ const partitionKey = createPartitionKey({
1090
1052
  id: entry.id,
1091
- locale: model.locale,
1092
1053
  tenant: model.tenant
1093
1054
  });
1094
1055
  const storageEntry = convertToStorageEntry({
@@ -1101,17 +1062,18 @@ const createEntriesStorageOperations = params => {
1101
1062
  * - update current entry revision with new data
1102
1063
  * - update the latest entry status - if entry being unpublished is latest
1103
1064
  */
1104
- const items = [entity.deleteBatch({
1105
- PK: partitionKey,
1106
- SK: (0, _keys.createPublishedSortKey)()
1107
- }), entity.putBatch({
1108
- ...storageEntry,
1109
- PK: partitionKey,
1110
- SK: (0, _keys.createRevisionSortKey)(entry),
1111
- TYPE: createType(),
1112
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
1113
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
1114
- })];
1065
+ const entityBatch = entity.createEntityWriter({
1066
+ delete: [{
1067
+ PK: partitionKey,
1068
+ SK: createPublishedSortKey()
1069
+ }],
1070
+ put: [{
1071
+ ...createEntryRevisionKeys(storageEntry),
1072
+ data: {
1073
+ ...storageEntry
1074
+ }
1075
+ }]
1076
+ });
1115
1077
 
1116
1078
  /**
1117
1079
  * We need the latest entry to see if something needs to be updated alongside the unpublishing one.
@@ -1120,14 +1082,12 @@ const createEntriesStorageOperations = params => {
1120
1082
  if (initialLatestStorageEntry) {
1121
1083
  const unpublishingLatestRevision = entry.id === initialLatestStorageEntry.id;
1122
1084
  if (unpublishingLatestRevision) {
1123
- items.push(entity.putBatch({
1124
- ...storageEntry,
1125
- PK: partitionKey,
1126
- SK: (0, _keys.createLatestSortKey)(),
1127
- TYPE: createLatestType(),
1128
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
1129
- GSI1_SK: (0, _keys.createGSISortKey)(entry)
1130
- }));
1085
+ entityBatch.put({
1086
+ ...createEntryLatestKeys(storageEntry),
1087
+ data: {
1088
+ ...storageEntry
1089
+ }
1090
+ });
1131
1091
  } else {
1132
1092
  const latestStorageEntry = convertToStorageEntry({
1133
1093
  storageEntry: initialLatestStorageEntry,
@@ -1136,42 +1096,35 @@ const createEntriesStorageOperations = params => {
1136
1096
 
1137
1097
  // If the unpublished revision is not the latest one, we still need to
1138
1098
  // update the latest record with the new values of entry-level meta fields.
1139
- const updatedEntryLevelMetaFields = (0, _constants.pickEntryMetaFields)(entry, _constants.isEntryLevelEntryMetaField);
1099
+ const updatedEntryLevelMetaFields = pickEntryMetaFields(entry, isEntryLevelEntryMetaField);
1140
1100
 
1141
1101
  // 1. Update actual revision record.
1142
- items.push(entity.putBatch({
1143
- ...latestStorageEntry,
1144
- ...updatedEntryLevelMetaFields,
1145
- PK: partitionKey,
1146
- SK: (0, _keys.createRevisionSortKey)(latestStorageEntry),
1147
- TYPE: createType(),
1148
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "A"),
1149
- GSI1_SK: (0, _keys.createGSISortKey)(latestStorageEntry)
1150
- }));
1102
+ entityBatch.put({
1103
+ ...createEntryRevisionKeys(latestStorageEntry),
1104
+ data: {
1105
+ ...latestStorageEntry,
1106
+ ...updatedEntryLevelMetaFields
1107
+ }
1108
+ });
1151
1109
 
1152
1110
  // 2. Update latest record.
1153
- items.push(entity.putBatch({
1154
- ...latestStorageEntry,
1155
- ...updatedEntryLevelMetaFields,
1156
- PK: partitionKey,
1157
- SK: (0, _keys.createLatestSortKey)(),
1158
- TYPE: createLatestType(),
1159
- GSI1_PK: (0, _keys.createGSIPartitionKey)(model, "L"),
1160
- GSI1_SK: (0, _keys.createGSISortKey)(latestStorageEntry)
1161
- }));
1111
+ entityBatch.put({
1112
+ ...createEntryLatestKeys(latestStorageEntry),
1113
+ data: {
1114
+ ...latestStorageEntry,
1115
+ ...updatedEntryLevelMetaFields
1116
+ }
1117
+ });
1162
1118
  }
1163
1119
  }
1164
1120
  try {
1165
- await (0, _batchWrite.batchWriteAll)({
1166
- table: entity.table,
1167
- items
1168
- });
1121
+ await entityBatch.execute();
1169
1122
  dataLoaders.clearAll({
1170
1123
  model
1171
1124
  });
1172
1125
  return initialStorageEntry;
1173
1126
  } catch (ex) {
1174
- throw new _error.default(ex.message || "Could not execute unpublish batch.", ex.code || "UNPUBLISH_ERROR", {
1127
+ throw new WebinyError(ex.message || "Could not execute unpublish batch.", ex.code || "UNPUBLISH_ERROR", {
1175
1128
  entry,
1176
1129
  storageEntry
1177
1130
  });
@@ -1184,7 +1137,7 @@ const createEntriesStorageOperations = params => {
1184
1137
  } = params;
1185
1138
  const field = model.fields.find(f => f.fieldId === fieldId);
1186
1139
  if (!field) {
1187
- throw new _error.default(`Could not find field with given "fieldId" value.`, "FIELD_NOT_FOUND", {
1140
+ throw new WebinyError(`Could not find field with given "fieldId" value.`, "FIELD_NOT_FOUND", {
1188
1141
  fieldId
1189
1142
  });
1190
1143
  }
@@ -1239,6 +1192,5 @@ const createEntriesStorageOperations = params => {
1239
1192
  getUniqueFieldValues
1240
1193
  };
1241
1194
  };
1242
- exports.createEntriesStorageOperations = createEntriesStorageOperations;
1243
1195
 
1244
1196
  //# sourceMappingURL=index.js.map