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