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