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