@webiny/api-headless-cms 0.0.0-unstable.bca7b3e350 → 0.0.0-unstable.c59b9cc5b9
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/context.js +47 -43
- package/context.js.map +1 -1
- package/crud/contentEntry/markLockedFields.d.ts +1 -1
- package/crud/contentEntry/markLockedFields.js +3 -0
- package/crud/contentEntry/markLockedFields.js.map +1 -1
- package/crud/contentEntry/referenceFieldsMapping.js +34 -5
- package/crud/contentEntry/referenceFieldsMapping.js.map +1 -1
- package/crud/contentEntry.crud.d.ts +8 -5
- package/crud/contentEntry.crud.js +1023 -840
- package/crud/contentEntry.crud.js.map +1 -1
- package/crud/contentModel/beforeCreate.js +39 -76
- package/crud/contentModel/beforeCreate.js.map +1 -1
- package/crud/contentModel/beforeDelete.d.ts +1 -1
- package/crud/contentModel/beforeDelete.js +1 -5
- package/crud/contentModel/beforeDelete.js.map +1 -1
- package/crud/contentModel/beforeUpdate.js +31 -3
- package/crud/contentModel/beforeUpdate.js.map +1 -1
- package/crud/contentModel/compatibility/modelApiName.d.ts +3 -0
- package/crud/contentModel/compatibility/modelApiName.js +24 -0
- package/crud/contentModel/compatibility/modelApiName.js.map +1 -0
- package/crud/contentModel/defaultFields.d.ts +5 -0
- package/crud/contentModel/defaultFields.js +58 -0
- package/crud/contentModel/defaultFields.js.map +1 -0
- package/crud/contentModel/fields/descriptionField.d.ts +2 -0
- package/crud/contentModel/fields/descriptionField.js +42 -0
- package/crud/contentModel/fields/descriptionField.js.map +1 -0
- package/crud/contentModel/fields/imageField.d.ts +2 -0
- package/crud/contentModel/fields/imageField.js +46 -0
- package/crud/contentModel/fields/imageField.js.map +1 -0
- package/crud/contentModel/fields/titleField.d.ts +2 -0
- package/crud/contentModel/fields/titleField.js +58 -0
- package/crud/contentModel/fields/titleField.js.map +1 -0
- package/crud/contentModel/validate/endingAllowed.d.ts +6 -0
- package/crud/contentModel/validate/endingAllowed.js +26 -0
- package/crud/contentModel/validate/endingAllowed.js.map +1 -0
- package/crud/contentModel/validate/isModelEndingAllowed.d.ts +6 -0
- package/crud/contentModel/validate/isModelEndingAllowed.js +24 -0
- package/crud/contentModel/validate/isModelEndingAllowed.js.map +1 -0
- package/crud/contentModel/validate/modelId.d.ts +11 -0
- package/crud/contentModel/validate/modelId.js +36 -0
- package/crud/contentModel/validate/modelId.js.map +1 -0
- package/crud/contentModel/validate/pluralApiName.d.ts +7 -0
- package/crud/contentModel/validate/pluralApiName.js +24 -0
- package/crud/contentModel/validate/pluralApiName.js.map +1 -0
- package/crud/contentModel/validate/singularApiName.d.ts +7 -0
- package/crud/contentModel/validate/singularApiName.js +24 -0
- package/crud/contentModel/validate/singularApiName.js.map +1 -0
- package/crud/contentModel/validateModel.d.ts +1 -0
- package/crud/contentModel/validateModel.js.map +1 -1
- package/crud/contentModel/validateModelFields.d.ts +2 -1
- package/crud/contentModel/validateModelFields.js +19 -57
- package/crud/contentModel/validateModelFields.js.map +1 -1
- package/crud/contentModel/validation.d.ts +136 -62
- package/crud/contentModel/validation.js +61 -13
- package/crud/contentModel/validation.js.map +1 -1
- package/crud/contentModel.crud.js +346 -285
- package/crud/contentModel.crud.js.map +1 -1
- package/crud/contentModelGroup.crud.js +170 -148
- package/crud/contentModelGroup.crud.js.map +1 -1
- package/crud/settings.crud.d.ts +1 -1
- package/crud/settings.crud.js +5 -10
- package/crud/settings.crud.js.map +1 -1
- package/crud/system.crud.js +0 -60
- package/crud/system.crud.js.map +1 -1
- package/graphql/checkEndpointAccess.d.ts +2 -0
- package/graphql/checkEndpointAccess.js +18 -0
- package/graphql/checkEndpointAccess.js.map +1 -0
- package/graphql/createExecutableSchema.d.ts +2 -3
- package/graphql/createExecutableSchema.js.map +1 -1
- package/graphql/createRequestBody.d.ts +2 -0
- package/graphql/createRequestBody.js +14 -0
- package/graphql/createRequestBody.js.map +1 -0
- package/graphql/formatErrorPayload.d.ts +1 -0
- package/graphql/formatErrorPayload.js +25 -0
- package/graphql/formatErrorPayload.js.map +1 -0
- package/graphql/generateSchema.js.map +1 -1
- package/graphql/getSchema.d.ts +17 -0
- package/graphql/getSchema.js +102 -0
- package/graphql/getSchema.js.map +1 -0
- package/graphql/graphQLHandlerFactory.js +6 -145
- package/graphql/graphQLHandlerFactory.js.map +1 -1
- package/graphql/handleRequest.d.ts +11 -0
- package/graphql/handleRequest.js +81 -0
- package/graphql/handleRequest.js.map +1 -0
- package/graphql/schema/baseContentSchema.js +1 -7
- package/graphql/schema/baseContentSchema.js.map +1 -1
- package/graphql/schema/baseSchema.js +15 -0
- package/graphql/schema/baseSchema.js.map +1 -1
- package/graphql/schema/contentEntries.js +90 -53
- package/graphql/schema/contentEntries.js.map +1 -1
- package/graphql/schema/contentModelGroups.js +7 -7
- package/graphql/schema/contentModelGroups.js.map +1 -1
- package/graphql/schema/contentModels.js +23 -4
- package/graphql/schema/contentModels.js.map +1 -1
- package/graphql/schema/createFieldResolvers.d.ts +1 -1
- package/graphql/schema/createFieldResolvers.js +6 -12
- package/graphql/schema/createFieldResolvers.js.map +1 -1
- package/graphql/schema/createFieldTypePluginRecords.d.ts +3 -0
- package/graphql/schema/createFieldTypePluginRecords.js +13 -0
- package/graphql/schema/createFieldTypePluginRecords.js.map +1 -0
- package/graphql/schema/createManageResolvers.d.ts +1 -1
- package/graphql/schema/createManageResolvers.js +37 -17
- package/graphql/schema/createManageResolvers.js.map +1 -1
- package/graphql/schema/createManageSDL.d.ts +1 -0
- package/graphql/schema/createManageSDL.js +76 -62
- package/graphql/schema/createManageSDL.js.map +1 -1
- package/graphql/schema/createPreviewResolvers.js +3 -7
- package/graphql/schema/createPreviewResolvers.js.map +1 -1
- package/graphql/schema/createReadResolvers.js +4 -8
- package/graphql/schema/createReadResolvers.js.map +1 -1
- package/graphql/schema/createReadSDL.d.ts +1 -0
- package/graphql/schema/createReadSDL.js +40 -35
- package/graphql/schema/createReadSDL.js.map +1 -1
- package/graphql/schema/resolvers/commonFieldResolvers.d.ts +3 -2
- package/graphql/schema/resolvers/commonFieldResolvers.js +2 -1
- package/graphql/schema/resolvers/commonFieldResolvers.js.map +1 -1
- package/graphql/schema/resolvers/manage/resolveDelete.d.ts +2 -1
- package/graphql/schema/resolvers/manage/resolveDelete.js +13 -3
- package/graphql/schema/resolvers/manage/resolveDelete.js.map +1 -1
- package/graphql/schema/resolvers/manage/resolveDeleteMultiple.d.ts +7 -0
- package/graphql/schema/resolvers/manage/resolveDeleteMultiple.js +20 -0
- package/graphql/schema/resolvers/manage/resolveDeleteMultiple.js.map +1 -0
- package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.d.ts +4 -0
- package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.js +18 -0
- package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.js.map +1 -0
- package/graphql/schema/schemaPlugins.js +7 -16
- package/graphql/schema/schemaPlugins.js.map +1 -1
- package/graphql/system.js +0 -16
- package/graphql/system.js.map +1 -1
- package/graphqlFields/dynamicZone/dynamicZoneField.d.ts +1 -1
- package/graphqlFields/dynamicZone/dynamicZoneField.js +54 -19
- package/graphqlFields/dynamicZone/dynamicZoneField.js.map +1 -1
- package/graphqlFields/object.js +21 -2
- package/graphqlFields/object.js.map +1 -1
- package/graphqlFields/ref.js +42 -14
- package/graphqlFields/ref.js.map +1 -1
- package/index.d.ts +3 -1
- package/index.js +25 -2
- package/index.js.map +1 -1
- package/package.json +35 -36
- package/plugins/CmsModelPlugin.d.ts +21 -3
- package/plugins/CmsModelPlugin.js +28 -2
- package/plugins/CmsModelPlugin.js.map +1 -1
- package/plugins/StorageOperationsCmsModelPlugin.d.ts +23 -0
- package/plugins/StorageOperationsCmsModelPlugin.js +42 -0
- package/plugins/StorageOperationsCmsModelPlugin.js.map +1 -0
- package/plugins/index.d.ts +1 -0
- package/plugins/index.js +11 -0
- package/plugins/index.js.map +1 -1
- package/types.d.ts +200 -97
- package/types.js +12 -1
- package/types.js.map +1 -1
- package/utils/converters/valueKeyStorageConverter.d.ts +1 -5
- package/utils/converters/valueKeyStorageConverter.js +26 -20
- package/utils/converters/valueKeyStorageConverter.js.map +1 -1
- package/utils/createTypeFromFields.d.ts +1 -0
- package/utils/createTypeFromFields.js +7 -5
- package/utils/createTypeFromFields.js.map +1 -1
- package/utils/createTypeName.d.ts +0 -2
- package/utils/createTypeName.js +2 -10
- package/utils/createTypeName.js.map +1 -1
- package/utils/getBaseFieldType.d.ts +1 -3
- package/utils/getBaseFieldType.js.map +1 -1
- package/utils/getEntryDescription.d.ts +2 -0
- package/utils/getEntryDescription.js +17 -0
- package/utils/getEntryDescription.js.map +1 -0
- package/utils/getEntryImage.d.ts +2 -0
- package/utils/getEntryImage.js +17 -0
- package/utils/getEntryImage.js.map +1 -0
- package/utils/getEntryTitle.d.ts +1 -1
- package/utils/getEntryTitle.js.map +1 -1
- package/utils/incrementEntryIdVersion.d.ts +5 -0
- package/utils/incrementEntryIdVersion.js +29 -0
- package/utils/incrementEntryIdVersion.js.map +1 -0
- package/utils/ownership.d.ts +3 -3
- package/utils/ownership.js.map +1 -1
- package/utils/renderFields.d.ts +4 -2
- package/utils/renderFields.js +10 -2
- package/utils/renderFields.js.map +1 -1
- package/utils/renderGetFilterFields.d.ts +2 -2
- package/utils/renderGetFilterFields.js +7 -20
- package/utils/renderGetFilterFields.js.map +1 -1
- package/utils/renderInputFields.d.ts +4 -2
- package/utils/renderInputFields.js +17 -5
- package/utils/renderInputFields.js.map +1 -1
- package/utils/renderListFilterFields.d.ts +2 -1
- package/utils/renderListFilterFields.js +9 -20
- package/utils/renderListFilterFields.js.map +1 -1
- package/utils/renderSortEnum.d.ts +2 -1
- package/utils/renderSortEnum.js +2 -1
- package/utils/renderSortEnum.js.map +1 -1
- package/crud/contentModel/createFieldModels.d.ts +0 -2
- package/crud/contentModel/createFieldModels.js +0 -26
- package/crud/contentModel/createFieldModels.js.map +0 -1
- package/crud/contentModel/fieldIdValidation.d.ts +0 -1
- package/crud/contentModel/fieldIdValidation.js +0 -25
- package/crud/contentModel/fieldIdValidation.js.map +0 -1
- package/crud/contentModel/idValidation.d.ts +0 -1
- package/crud/contentModel/idValidation.js +0 -22
- package/crud/contentModel/idValidation.js.map +0 -1
- package/crud/contentModel/models.d.ts +0 -4
- package/crud/contentModel/models.js +0 -192
- package/crud/contentModel/models.js.map +0 -1
- package/crud/contentModel/systemFields.d.ts +0 -1
- package/crud/contentModel/systemFields.js +0 -8
- package/crud/contentModel/systemFields.js.map +0 -1
- package/upgrades/5.33.0/index.d.ts +0 -3
- package/upgrades/5.33.0/index.js +0 -159
- package/upgrades/5.33.0/index.js.map +0 -1
- package/upgrades/index.d.ts +0 -1
- package/upgrades/index.js +0 -9
- package/upgrades/index.js.map +0 -1
- package/utils/pluralizedTypeName.d.ts +0 -1
- package/utils/pluralizedTypeName.js +0 -20
- package/utils/pluralizedTypeName.js.map +0 -1
|
@@ -6,33 +6,28 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.createContentEntryCrud = exports.STATUS_UNPUBLISHED = exports.STATUS_PUBLISHED = exports.STATUS_DRAFT = void 0;
|
|
8
8
|
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
9
|
-
var
|
|
9
|
+
var _merge = _interopRequireDefault(require("lodash/merge"));
|
|
10
|
+
var _utils = require("@webiny/utils");
|
|
11
|
+
var _error = _interopRequireDefault(require("@webiny/error"));
|
|
10
12
|
var _handlerGraphql = require("@webiny/handler-graphql");
|
|
13
|
+
var _types = require("../types");
|
|
11
14
|
var _entryDataValidation = require("./contentEntry/entryDataValidation");
|
|
12
|
-
var _error = _interopRequireDefault(require("@webiny/error"));
|
|
13
15
|
var _pubsub = require("@webiny/pubsub");
|
|
14
16
|
var _beforeCreate = require("./contentEntry/beforeCreate");
|
|
15
17
|
var _beforeUpdate = require("./contentEntry/beforeUpdate");
|
|
16
|
-
var _utils = require("@webiny/utils");
|
|
17
18
|
var _afterDelete = require("./contentEntry/afterDelete");
|
|
18
19
|
var _referenceFieldsMapping = require("./contentEntry/referenceFieldsMapping");
|
|
19
|
-
var _merge = _interopRequireDefault(require("lodash/merge"));
|
|
20
20
|
var _permissions = require("../utils/permissions");
|
|
21
21
|
var _access = require("../utils/access");
|
|
22
22
|
var _ownership = require("../utils/ownership");
|
|
23
23
|
var _entryStorage = require("../utils/entryStorage");
|
|
24
|
-
var _valueKeyStorageConverter = require("../utils/converters/valueKeyStorageConverter");
|
|
25
24
|
var _searchableFields = require("./contentEntry/searchableFields");
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
*/
|
|
29
|
-
// @ts-ignore
|
|
30
|
-
|
|
31
|
-
const STATUS_DRAFT = "draft";
|
|
25
|
+
var _filterAsync = require("../utils/filterAsync");
|
|
26
|
+
const STATUS_DRAFT = _types.CONTENT_ENTRY_STATUS.DRAFT;
|
|
32
27
|
exports.STATUS_DRAFT = STATUS_DRAFT;
|
|
33
|
-
const STATUS_PUBLISHED =
|
|
28
|
+
const STATUS_PUBLISHED = _types.CONTENT_ENTRY_STATUS.PUBLISHED;
|
|
34
29
|
exports.STATUS_PUBLISHED = STATUS_PUBLISHED;
|
|
35
|
-
const STATUS_UNPUBLISHED =
|
|
30
|
+
const STATUS_UNPUBLISHED = _types.CONTENT_ENTRY_STATUS.UNPUBLISHED;
|
|
36
31
|
exports.STATUS_UNPUBLISHED = STATUS_UNPUBLISHED;
|
|
37
32
|
/**
|
|
38
33
|
* Used for some fields to convert their values.
|
|
@@ -131,19 +126,13 @@ const mapAndCleanUpdatedInputData = (model, input) => {
|
|
|
131
126
|
*/
|
|
132
127
|
const createEntryMeta = (input, original) => {
|
|
133
128
|
const meta = (0, _merge.default)(original || {}, input || {});
|
|
134
|
-
|
|
135
|
-
if (meta[key] !== undefined || meta[key] !== null) {
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
delete meta[key];
|
|
139
|
-
}
|
|
140
|
-
return meta;
|
|
129
|
+
return (0, _utils.removeUndefinedValues)((0, _utils.removeNullValues)(meta));
|
|
141
130
|
};
|
|
142
131
|
const createEntryId = input => {
|
|
143
|
-
let entryId = (0,
|
|
132
|
+
let entryId = (0, _utils.mdbid)();
|
|
144
133
|
if (input.id) {
|
|
145
134
|
if (input.id.match(/^([a-zA-Z0-9])([a-zA-Z0-9\-]+)([a-zA-Z0-9])$/) === null) {
|
|
146
|
-
throw new _error.default("The provided ID is not valid. It must be a string which can A-Z, a-z, 0-9, - and it cannot start or end with a -.", "INVALID_ID", {
|
|
135
|
+
throw new _error.default("The provided ID is not valid. It must be a string which can be A-Z, a-z, 0-9, - and it cannot start or end with a -.", "INVALID_ID", {
|
|
147
136
|
id: input.id
|
|
148
137
|
});
|
|
149
138
|
}
|
|
@@ -151,7 +140,7 @@ const createEntryId = input => {
|
|
|
151
140
|
}
|
|
152
141
|
const version = 1;
|
|
153
142
|
return {
|
|
154
|
-
entryId
|
|
143
|
+
entryId,
|
|
155
144
|
version,
|
|
156
145
|
id: (0, _utils.createIdentifier)({
|
|
157
146
|
id: entryId,
|
|
@@ -187,11 +176,17 @@ const createContentEntryCrud = params => {
|
|
|
187
176
|
storageOperations,
|
|
188
177
|
context,
|
|
189
178
|
getIdentity,
|
|
190
|
-
getTenant
|
|
179
|
+
getTenant,
|
|
180
|
+
getLocale
|
|
191
181
|
} = params;
|
|
192
|
-
const {
|
|
193
|
-
|
|
194
|
-
|
|
182
|
+
const getCreatedBy = () => {
|
|
183
|
+
const identity = getIdentity();
|
|
184
|
+
return {
|
|
185
|
+
id: identity.id,
|
|
186
|
+
displayName: identity.displayName,
|
|
187
|
+
type: identity.type
|
|
188
|
+
};
|
|
189
|
+
};
|
|
195
190
|
|
|
196
191
|
/**
|
|
197
192
|
* Create
|
|
@@ -242,15 +237,27 @@ const createContentEntryCrud = params => {
|
|
|
242
237
|
const onEntryAfterDelete = (0, _pubsub.createTopic)("cms.onEntryAfterDelete");
|
|
243
238
|
const onEntryDeleteError = (0, _pubsub.createTopic)("cms.onEntryDeleteError");
|
|
244
239
|
|
|
245
|
-
|
|
240
|
+
/**
|
|
241
|
+
* Delete revision
|
|
242
|
+
*/
|
|
246
243
|
const onEntryRevisionBeforeDelete = (0, _pubsub.createTopic)("cms.onEntryRevisionBeforeDelete");
|
|
247
244
|
const onEntryRevisionAfterDelete = (0, _pubsub.createTopic)("cms.onEntryRevisionAfterDelete");
|
|
248
245
|
const onEntryRevisionDeleteError = (0, _pubsub.createTopic)("cms.onEntryRevisionDeleteError");
|
|
246
|
+
/**
|
|
247
|
+
* Delete multiple entries
|
|
248
|
+
*/
|
|
249
|
+
const onEntryBeforeDeleteMultiple = (0, _pubsub.createTopic)("cms.onEntryBeforeDeleteMultiple");
|
|
250
|
+
const onEntryAfterDeleteMultiple = (0, _pubsub.createTopic)("cms.onEntryAfterDeleteMultiple");
|
|
251
|
+
const onEntryDeleteMultipleError = (0, _pubsub.createTopic)("cms.onEntryDeleteMultipleError");
|
|
249
252
|
|
|
250
|
-
|
|
253
|
+
/**
|
|
254
|
+
* Get entry
|
|
255
|
+
*/
|
|
251
256
|
const onEntryBeforeGet = (0, _pubsub.createTopic)("cms.onEntryBeforeGet");
|
|
252
257
|
|
|
253
|
-
|
|
258
|
+
/**
|
|
259
|
+
* List entries
|
|
260
|
+
*/
|
|
254
261
|
const onEntryBeforeList = (0, _pubsub.createTopic)("cms.onEntryBeforeList");
|
|
255
262
|
|
|
256
263
|
/**
|
|
@@ -275,189 +282,1000 @@ const createContentEntryCrud = params => {
|
|
|
275
282
|
/**
|
|
276
283
|
* A helper to delete the entire entry.
|
|
277
284
|
*/
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
entry
|
|
282
|
-
} = params;
|
|
283
|
-
try {
|
|
284
|
-
await onEntryBeforeDelete.publish({
|
|
285
|
-
entry,
|
|
286
|
-
model
|
|
287
|
-
});
|
|
288
|
-
await storageOperations.entries.delete(model, {
|
|
289
|
-
entry
|
|
290
|
-
});
|
|
291
|
-
await onEntryAfterDelete.publish({
|
|
292
|
-
entry,
|
|
293
|
-
model
|
|
294
|
-
});
|
|
295
|
-
} catch (ex) {
|
|
296
|
-
await onEntryDeleteError.publish({
|
|
297
|
-
entry,
|
|
285
|
+
const deleteEntryHelper = async params => {
|
|
286
|
+
return context.benchmark.measure("headlessCms.crud.entries.deleteEntry", async () => {
|
|
287
|
+
const {
|
|
298
288
|
model,
|
|
299
|
-
error: ex
|
|
300
|
-
});
|
|
301
|
-
throw new _error.default(ex.message || "Could not delete entry.", ex.code || "DELETE_ERROR", {
|
|
302
289
|
entry
|
|
303
|
-
}
|
|
304
|
-
|
|
290
|
+
} = params;
|
|
291
|
+
try {
|
|
292
|
+
await onEntryBeforeDelete.publish({
|
|
293
|
+
entry,
|
|
294
|
+
model
|
|
295
|
+
});
|
|
296
|
+
await storageOperations.entries.delete(model, {
|
|
297
|
+
entry
|
|
298
|
+
});
|
|
299
|
+
await onEntryAfterDelete.publish({
|
|
300
|
+
entry,
|
|
301
|
+
model
|
|
302
|
+
});
|
|
303
|
+
} catch (ex) {
|
|
304
|
+
await onEntryDeleteError.publish({
|
|
305
|
+
entry,
|
|
306
|
+
model,
|
|
307
|
+
error: ex
|
|
308
|
+
});
|
|
309
|
+
throw new _error.default(ex.message || "Could not delete entry.", ex.code || "DELETE_ERROR", {
|
|
310
|
+
entry
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
});
|
|
305
314
|
};
|
|
306
315
|
/**
|
|
307
316
|
* A helper to get entries by revision IDs
|
|
308
317
|
*/
|
|
309
|
-
const getEntriesByIds = async (
|
|
318
|
+
const getEntriesByIds = async (model, ids) => {
|
|
319
|
+
return context.benchmark.measure("headlessCms.crud.entries.getEntriesByIds", async () => {
|
|
320
|
+
const permission = await checkEntryPermissions({
|
|
321
|
+
rwd: "r"
|
|
322
|
+
});
|
|
323
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
324
|
+
const entries = await storageOperations.entries.getByIds(model, {
|
|
325
|
+
ids
|
|
326
|
+
});
|
|
327
|
+
return entries.filter(entry => (0, _ownership.validateOwnership)(context, permission, entry));
|
|
328
|
+
});
|
|
329
|
+
};
|
|
330
|
+
const getEntryById = async (model, id) => {
|
|
331
|
+
const where = {
|
|
332
|
+
id
|
|
333
|
+
};
|
|
334
|
+
await onEntryBeforeGet.publish({
|
|
335
|
+
where,
|
|
336
|
+
model
|
|
337
|
+
});
|
|
338
|
+
const [entry] = await getEntriesByIds(model, [id]);
|
|
339
|
+
if (!entry) {
|
|
340
|
+
throw new _handlerGraphql.NotFoundError(`Entry by ID "${id}" not found.`);
|
|
341
|
+
}
|
|
342
|
+
return entry;
|
|
343
|
+
};
|
|
344
|
+
const getPublishedEntriesByIds = async (model, ids) => {
|
|
310
345
|
const permission = await checkEntryPermissions({
|
|
311
346
|
rwd: "r"
|
|
312
347
|
});
|
|
313
|
-
await (0, _access.checkModelAccess)(context,
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
348
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
349
|
+
const entries = await storageOperations.entries.getPublishedByIds(model, {
|
|
350
|
+
ids
|
|
351
|
+
});
|
|
352
|
+
return entries.filter(entry => (0, _ownership.validateOwnership)(context, permission, entry));
|
|
353
|
+
};
|
|
354
|
+
const getLatestEntriesByIds = async (model, ids) => {
|
|
355
|
+
const permission = await checkEntryPermissions({
|
|
356
|
+
rwd: "r"
|
|
317
357
|
});
|
|
318
|
-
|
|
358
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
359
|
+
const entries = await storageOperations.entries.getLatestByIds(model, {
|
|
319
360
|
ids
|
|
320
361
|
});
|
|
321
362
|
return entries.filter(entry => (0, _ownership.validateOwnership)(context, permission, entry));
|
|
322
363
|
};
|
|
323
|
-
|
|
364
|
+
const getEntry = async (model, params) => {
|
|
365
|
+
await checkEntryPermissions({
|
|
366
|
+
rwd: "r"
|
|
367
|
+
});
|
|
368
|
+
const {
|
|
369
|
+
where,
|
|
370
|
+
sort
|
|
371
|
+
} = params;
|
|
372
|
+
await onEntryBeforeGet.publish({
|
|
373
|
+
where,
|
|
374
|
+
model
|
|
375
|
+
});
|
|
376
|
+
const [items] = await listEntries(model, {
|
|
377
|
+
where,
|
|
378
|
+
sort,
|
|
379
|
+
limit: 1
|
|
380
|
+
});
|
|
381
|
+
const item = items.shift();
|
|
382
|
+
if (!item) {
|
|
383
|
+
throw new _handlerGraphql.NotFoundError(`Entry not found!`);
|
|
384
|
+
}
|
|
385
|
+
return item;
|
|
386
|
+
};
|
|
387
|
+
const getEntryRevisions = async (model, entryId) => {
|
|
388
|
+
return storageOperations.entries.getRevisions(model, {
|
|
389
|
+
id: entryId
|
|
390
|
+
});
|
|
391
|
+
};
|
|
392
|
+
const listEntries = async (model, params) => {
|
|
393
|
+
const permission = await checkEntryPermissions({
|
|
394
|
+
rwd: "r"
|
|
395
|
+
});
|
|
396
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
397
|
+
const {
|
|
398
|
+
where: initialWhere,
|
|
399
|
+
limit: initialLimit
|
|
400
|
+
} = params;
|
|
401
|
+
const limit = initialLimit && initialLimit > 0 ? initialLimit : 50;
|
|
402
|
+
const where = (0, _objectSpread2.default)({}, initialWhere);
|
|
324
403
|
/**
|
|
325
|
-
*
|
|
404
|
+
* Possibly only get records which are owned by current user.
|
|
405
|
+
* Or if searching for the owner set that value - in the case that user can see other entries than their own.
|
|
326
406
|
*/
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
onBeforeEntryUpdate: onEntryBeforeUpdate,
|
|
332
|
-
onAfterEntryUpdate: onEntryAfterUpdate,
|
|
333
|
-
onBeforeEntryDelete: onEntryBeforeDelete,
|
|
334
|
-
onAfterEntryDelete: onEntryAfterDelete,
|
|
335
|
-
onBeforeEntryDeleteRevision: onEntryRevisionBeforeDelete,
|
|
336
|
-
onAfterEntryDeleteRevision: onEntryRevisionAfterDelete,
|
|
337
|
-
onBeforeEntryPublish: onEntryBeforePublish,
|
|
338
|
-
onAfterEntryPublish: onEntryAfterPublish,
|
|
339
|
-
onBeforeEntryUnpublish: onEntryBeforeUnpublish,
|
|
340
|
-
onAfterEntryUnpublish: onEntryAfterUnpublish,
|
|
341
|
-
onBeforeEntryGet: onEntryBeforeGet,
|
|
342
|
-
onBeforeEntryList: onEntryBeforeList,
|
|
407
|
+
const ownedBy = permission.own ? getIdentity().id : where.ownedBy;
|
|
408
|
+
if (ownedBy !== undefined) {
|
|
409
|
+
where.ownedBy = ownedBy;
|
|
410
|
+
}
|
|
343
411
|
/**
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
* Create
|
|
412
|
+
* Where must contain either latest or published keys.
|
|
413
|
+
* We cannot list entries without one of those
|
|
347
414
|
*/
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
415
|
+
if (where.latest && where.published) {
|
|
416
|
+
throw new _error.default("Cannot list entries that are both published and latest.", "LIST_ENTRIES_ERROR", {
|
|
417
|
+
where
|
|
418
|
+
});
|
|
419
|
+
} else if (!where.latest && !where.published) {
|
|
420
|
+
throw new _error.default("Cannot list entries if we do not have latest or published defined.", "LIST_ENTRIES_ERROR", {
|
|
421
|
+
where
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
const fields = (0, _searchableFields.getSearchableFields)({
|
|
425
|
+
fields: model.fields,
|
|
426
|
+
plugins: context.plugins,
|
|
427
|
+
input: params.fields || []
|
|
428
|
+
});
|
|
429
|
+
try {
|
|
430
|
+
await onEntryBeforeList.publish({
|
|
431
|
+
where,
|
|
432
|
+
model
|
|
433
|
+
});
|
|
434
|
+
const {
|
|
435
|
+
hasMoreItems,
|
|
436
|
+
totalCount,
|
|
437
|
+
cursor,
|
|
438
|
+
items
|
|
439
|
+
} = await storageOperations.entries.list(model, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, params), {}, {
|
|
440
|
+
limit,
|
|
441
|
+
where,
|
|
442
|
+
fields
|
|
443
|
+
}));
|
|
444
|
+
const meta = {
|
|
445
|
+
hasMoreItems,
|
|
446
|
+
totalCount,
|
|
447
|
+
/**
|
|
448
|
+
* Cursor should be null if there are no more items to load.
|
|
449
|
+
* Just make sure of that, disregarding what is returned from the storageOperations.entries.list method.
|
|
450
|
+
*/
|
|
451
|
+
cursor: hasMoreItems ? cursor : null
|
|
452
|
+
};
|
|
453
|
+
return [items, meta];
|
|
454
|
+
} catch (ex) {
|
|
455
|
+
throw new _error.default("Error while fetching entries from storage.", "LIST_ENTRIES_ERROR", {
|
|
456
|
+
params,
|
|
457
|
+
error: {
|
|
458
|
+
message: ex.message,
|
|
459
|
+
code: ex.code,
|
|
460
|
+
data: ex.data
|
|
461
|
+
},
|
|
462
|
+
model,
|
|
463
|
+
fields
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
const createEntry = async (model, inputData) => {
|
|
468
|
+
await checkEntryPermissions({
|
|
469
|
+
rwd: "w"
|
|
470
|
+
});
|
|
471
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
472
|
+
|
|
351
473
|
/**
|
|
352
|
-
*
|
|
474
|
+
* Make sure we only work with fields that are defined in the model.
|
|
353
475
|
*/
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
476
|
+
const initialInput = mapAndCleanCreateInputData(model, inputData);
|
|
477
|
+
await (0, _entryDataValidation.validateModelEntryData)({
|
|
478
|
+
context,
|
|
479
|
+
model,
|
|
480
|
+
data: initialInput
|
|
481
|
+
});
|
|
482
|
+
const input = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
483
|
+
context,
|
|
484
|
+
model,
|
|
485
|
+
input: initialInput,
|
|
486
|
+
validateEntries: true
|
|
487
|
+
});
|
|
488
|
+
const locale = getLocale();
|
|
489
|
+
const owner = getCreatedBy();
|
|
490
|
+
const {
|
|
491
|
+
id,
|
|
492
|
+
entryId,
|
|
493
|
+
version
|
|
494
|
+
} = createEntryId(inputData);
|
|
357
495
|
/**
|
|
358
|
-
*
|
|
496
|
+
* There is a possibility that user sends an ID in the input, so we will use that one.
|
|
497
|
+
* There is no check if the ID is unique or not, that is up to the user.
|
|
359
498
|
*/
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
499
|
+
const entry = {
|
|
500
|
+
webinyVersion: context.WEBINY_VERSION,
|
|
501
|
+
tenant: getTenant().id,
|
|
502
|
+
entryId,
|
|
503
|
+
id,
|
|
504
|
+
modelId: model.modelId,
|
|
505
|
+
locale: locale.code,
|
|
506
|
+
createdOn: new Date().toISOString(),
|
|
507
|
+
savedOn: new Date().toISOString(),
|
|
508
|
+
createdBy: owner,
|
|
509
|
+
ownedBy: owner,
|
|
510
|
+
modifiedBy: null,
|
|
511
|
+
version,
|
|
512
|
+
locked: false,
|
|
513
|
+
status: STATUS_DRAFT,
|
|
514
|
+
values: input
|
|
515
|
+
};
|
|
516
|
+
let storageEntry = null;
|
|
517
|
+
try {
|
|
518
|
+
await onEntryBeforeCreate.publish({
|
|
519
|
+
entry,
|
|
520
|
+
input,
|
|
521
|
+
model
|
|
522
|
+
});
|
|
523
|
+
storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
524
|
+
const result = await storageOperations.entries.create(model, {
|
|
525
|
+
entry,
|
|
526
|
+
storageEntry
|
|
527
|
+
});
|
|
528
|
+
await onEntryAfterCreate.publish({
|
|
529
|
+
entry,
|
|
530
|
+
storageEntry: result,
|
|
531
|
+
model,
|
|
532
|
+
input
|
|
533
|
+
});
|
|
534
|
+
return result;
|
|
535
|
+
} catch (ex) {
|
|
536
|
+
await onEntryCreateError.publish({
|
|
537
|
+
error: ex,
|
|
538
|
+
entry,
|
|
539
|
+
model,
|
|
540
|
+
input
|
|
541
|
+
});
|
|
542
|
+
throw new _error.default(ex.message || "Could not create content entry.", ex.code || "CREATE_ENTRY_ERROR", ex.data || {
|
|
543
|
+
error: ex,
|
|
544
|
+
input,
|
|
545
|
+
entry,
|
|
546
|
+
storageEntry
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
const createEntryRevisionFrom = async (model, sourceId, inputData) => {
|
|
551
|
+
const permission = await checkEntryPermissions({
|
|
552
|
+
rwd: "w"
|
|
553
|
+
});
|
|
554
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
555
|
+
|
|
363
556
|
/**
|
|
364
|
-
*
|
|
557
|
+
* Make sure we only work with fields that are defined in the model.
|
|
365
558
|
*/
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
onEntryDeleteError,
|
|
559
|
+
const input = mapAndCleanUpdatedInputData(model, inputData);
|
|
560
|
+
|
|
369
561
|
/**
|
|
370
|
-
*
|
|
562
|
+
* Entries are identified by a common parent ID + Revision number.
|
|
371
563
|
*/
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
564
|
+
const {
|
|
565
|
+
id: uniqueId
|
|
566
|
+
} = (0, _utils.parseIdentifier)(sourceId);
|
|
567
|
+
const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
|
|
568
|
+
id: sourceId
|
|
569
|
+
});
|
|
570
|
+
const latestStorageEntry = await storageOperations.entries.getLatestRevisionByEntryId(model, {
|
|
571
|
+
id: uniqueId
|
|
572
|
+
});
|
|
573
|
+
if (!originalStorageEntry) {
|
|
574
|
+
throw new _handlerGraphql.NotFoundError(`Entry "${sourceId}" of model "${model.modelId}" was not found.`);
|
|
575
|
+
}
|
|
576
|
+
|
|
375
577
|
/**
|
|
376
|
-
*
|
|
578
|
+
* We need to convert data from DB to its original form before using it further.
|
|
377
579
|
*/
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
580
|
+
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
581
|
+
const initialValues = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry.values), input);
|
|
582
|
+
await (0, _entryDataValidation.validateModelEntryData)({
|
|
583
|
+
context,
|
|
584
|
+
model,
|
|
585
|
+
data: initialValues,
|
|
586
|
+
entry: originalEntry
|
|
587
|
+
});
|
|
588
|
+
const values = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
589
|
+
context,
|
|
590
|
+
model,
|
|
591
|
+
input: initialValues,
|
|
592
|
+
validateEntries: false
|
|
593
|
+
});
|
|
594
|
+
(0, _ownership.checkOwnership)(context, permission, originalEntry);
|
|
595
|
+
const identity = getIdentity();
|
|
596
|
+
const latestId = latestStorageEntry ? latestStorageEntry.id : sourceId;
|
|
597
|
+
const {
|
|
598
|
+
id,
|
|
599
|
+
version: nextVersion
|
|
600
|
+
} = increaseEntryIdVersion(latestId);
|
|
601
|
+
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
602
|
+
id,
|
|
603
|
+
version: nextVersion,
|
|
604
|
+
savedOn: new Date().toISOString(),
|
|
605
|
+
createdOn: new Date().toISOString(),
|
|
606
|
+
createdBy: {
|
|
607
|
+
id: identity.id,
|
|
608
|
+
displayName: identity.displayName,
|
|
609
|
+
type: identity.type
|
|
610
|
+
},
|
|
611
|
+
modifiedBy: null,
|
|
612
|
+
locked: false,
|
|
613
|
+
publishedOn: undefined,
|
|
614
|
+
status: STATUS_DRAFT,
|
|
615
|
+
values
|
|
616
|
+
});
|
|
617
|
+
let storageEntry = null;
|
|
618
|
+
try {
|
|
619
|
+
await onEntryBeforeCreateRevision.publish({
|
|
620
|
+
input,
|
|
621
|
+
entry,
|
|
622
|
+
original: originalEntry,
|
|
623
|
+
model
|
|
624
|
+
});
|
|
625
|
+
storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
626
|
+
const result = await storageOperations.entries.createRevisionFrom(model, {
|
|
627
|
+
entry,
|
|
628
|
+
storageEntry
|
|
629
|
+
});
|
|
630
|
+
await onEntryRevisionAfterCreate.publish({
|
|
631
|
+
input,
|
|
632
|
+
entry,
|
|
633
|
+
model,
|
|
634
|
+
original: originalEntry,
|
|
635
|
+
storageEntry: result
|
|
636
|
+
});
|
|
637
|
+
return result;
|
|
638
|
+
} catch (ex) {
|
|
639
|
+
await onEntryCreateRevisionError.publish({
|
|
640
|
+
entry,
|
|
641
|
+
original: originalEntry,
|
|
642
|
+
model,
|
|
643
|
+
input,
|
|
644
|
+
error: ex
|
|
645
|
+
});
|
|
646
|
+
throw new _error.default(ex.message || "Could not create entry from existing one.", ex.code || "CREATE_FROM_REVISION_ERROR", {
|
|
647
|
+
error: ex,
|
|
648
|
+
entry,
|
|
649
|
+
storageEntry,
|
|
650
|
+
originalEntry,
|
|
651
|
+
originalStorageEntry
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
const updateEntry = async (model, id, inputData, metaInput) => {
|
|
656
|
+
const permission = await checkEntryPermissions({
|
|
657
|
+
rwd: "w"
|
|
658
|
+
});
|
|
659
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
660
|
+
|
|
381
661
|
/**
|
|
382
|
-
*
|
|
662
|
+
* Make sure we only work with fields that are defined in the model.
|
|
383
663
|
*/
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
onEntryRepublishError,
|
|
664
|
+
const input = mapAndCleanUpdatedInputData(model, inputData);
|
|
665
|
+
|
|
387
666
|
/**
|
|
388
|
-
*
|
|
667
|
+
* The entry we are going to update.
|
|
389
668
|
*/
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
669
|
+
const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
|
|
670
|
+
id
|
|
671
|
+
});
|
|
672
|
+
if (!originalStorageEntry) {
|
|
673
|
+
throw new _handlerGraphql.NotFoundError(`Entry "${id}" of model "${model.modelId}" was not found.`);
|
|
674
|
+
}
|
|
675
|
+
if (originalStorageEntry.locked) {
|
|
676
|
+
throw new _error.default(`Cannot update entry because it's locked.`, "CONTENT_ENTRY_UPDATE_ERROR");
|
|
677
|
+
}
|
|
678
|
+
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
679
|
+
await (0, _entryDataValidation.validateModelEntryData)({
|
|
680
|
+
context,
|
|
681
|
+
model,
|
|
682
|
+
data: input,
|
|
683
|
+
entry: originalEntry
|
|
684
|
+
});
|
|
685
|
+
(0, _ownership.checkOwnership)(context, permission, originalEntry);
|
|
686
|
+
const initialValues = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry.values), input);
|
|
687
|
+
const values = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
688
|
+
context,
|
|
689
|
+
model,
|
|
690
|
+
input: initialValues,
|
|
691
|
+
validateEntries: false
|
|
692
|
+
});
|
|
395
693
|
/**
|
|
396
|
-
*
|
|
694
|
+
* If users wants to remove a key from meta values, they need to send meta key with the null value.
|
|
397
695
|
*/
|
|
398
|
-
|
|
696
|
+
const meta = createEntryMeta(metaInput, originalEntry.meta);
|
|
399
697
|
/**
|
|
400
|
-
*
|
|
698
|
+
* We always send the full entry to the hooks and storage operations update.
|
|
401
699
|
*/
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
700
|
+
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
701
|
+
savedOn: new Date().toISOString(),
|
|
702
|
+
modifiedBy: getCreatedBy(),
|
|
703
|
+
values,
|
|
704
|
+
meta,
|
|
705
|
+
status: transformEntryStatus(originalEntry.status)
|
|
706
|
+
});
|
|
707
|
+
let storageEntry = null;
|
|
708
|
+
try {
|
|
709
|
+
await onEntryBeforeUpdate.publish({
|
|
710
|
+
entry,
|
|
711
|
+
model,
|
|
712
|
+
input,
|
|
713
|
+
original: originalEntry
|
|
409
714
|
});
|
|
410
|
-
await
|
|
411
|
-
|
|
412
|
-
|
|
715
|
+
storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
716
|
+
const result = await storageOperations.entries.update(model, {
|
|
717
|
+
entry,
|
|
718
|
+
storageEntry
|
|
413
719
|
});
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
720
|
+
await onEntryAfterUpdate.publish({
|
|
721
|
+
entry,
|
|
722
|
+
storageEntry: result,
|
|
723
|
+
model,
|
|
724
|
+
input,
|
|
725
|
+
original: originalEntry
|
|
726
|
+
});
|
|
727
|
+
return result;
|
|
728
|
+
} catch (ex) {
|
|
729
|
+
await onEntryUpdateError.publish({
|
|
730
|
+
entry,
|
|
731
|
+
model,
|
|
732
|
+
input,
|
|
733
|
+
error: ex
|
|
734
|
+
});
|
|
735
|
+
throw new _error.default(ex.message || "Could not update existing entry.", ex.code || "UPDATE_ERROR", {
|
|
736
|
+
error: ex,
|
|
737
|
+
entry,
|
|
738
|
+
storageEntry,
|
|
739
|
+
originalEntry,
|
|
740
|
+
input
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
const republishEntry = async (model, id) => {
|
|
745
|
+
await checkEntryPermissions({
|
|
746
|
+
rwd: "w"
|
|
747
|
+
});
|
|
748
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
749
|
+
/**
|
|
750
|
+
* Fetch the entry from the storage.
|
|
751
|
+
*/
|
|
752
|
+
const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
|
|
753
|
+
id
|
|
754
|
+
});
|
|
755
|
+
if (!originalStorageEntry) {
|
|
756
|
+
throw new _handlerGraphql.NotFoundError(`Entry "${id}" was not found!`);
|
|
757
|
+
}
|
|
758
|
+
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
759
|
+
/**
|
|
760
|
+
* We can only process published entries.
|
|
761
|
+
*/
|
|
762
|
+
if (originalEntry.status !== "published") {
|
|
763
|
+
throw new _error.default("Entry with given ID is not published!", "NOT_PUBLISHED_ERROR", {
|
|
764
|
+
id,
|
|
765
|
+
original: originalEntry
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
const values = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
769
|
+
context,
|
|
770
|
+
model,
|
|
771
|
+
input: originalEntry.values,
|
|
772
|
+
validateEntries: false
|
|
773
|
+
});
|
|
774
|
+
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
775
|
+
savedOn: new Date().toISOString(),
|
|
776
|
+
webinyVersion: context.WEBINY_VERSION,
|
|
777
|
+
values
|
|
778
|
+
});
|
|
779
|
+
const storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
780
|
+
/**
|
|
781
|
+
* First we need to update existing entry.
|
|
782
|
+
*/
|
|
783
|
+
try {
|
|
784
|
+
await storageOperations.entries.update(model, {
|
|
785
|
+
entry,
|
|
786
|
+
storageEntry
|
|
426
787
|
});
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
788
|
+
} catch (ex) {
|
|
789
|
+
throw new _error.default("Could not update existing entry with new data while re-publishing.", "REPUBLISH_UPDATE_ERROR", {
|
|
790
|
+
entry
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Then we move onto publishing it again.
|
|
795
|
+
*/
|
|
796
|
+
try {
|
|
797
|
+
await onEntryBeforeRepublish.publish({
|
|
798
|
+
entry,
|
|
799
|
+
model
|
|
800
|
+
});
|
|
801
|
+
const result = await storageOperations.entries.publish(model, {
|
|
802
|
+
entry,
|
|
803
|
+
storageEntry
|
|
804
|
+
});
|
|
805
|
+
await onEntryAfterRepublish.publish({
|
|
806
|
+
entry,
|
|
807
|
+
model,
|
|
808
|
+
storageEntry
|
|
809
|
+
});
|
|
810
|
+
return result;
|
|
811
|
+
} catch (ex) {
|
|
812
|
+
await onEntryRepublishError.publish({
|
|
813
|
+
entry,
|
|
814
|
+
model,
|
|
815
|
+
error: ex
|
|
816
|
+
});
|
|
817
|
+
throw new _error.default("Could not publish existing entry while re-publishing.", "REPUBLISH_PUBLISH_ERROR", {
|
|
818
|
+
entry
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
};
|
|
822
|
+
const deleteEntryRevision = async (model, revisionId) => {
|
|
823
|
+
const permission = await checkEntryPermissions({
|
|
824
|
+
rwd: "d"
|
|
825
|
+
});
|
|
826
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
827
|
+
const {
|
|
828
|
+
id: entryId,
|
|
829
|
+
version
|
|
830
|
+
} = (0, _utils.parseIdentifier)(revisionId);
|
|
831
|
+
const storageEntryToDelete = await storageOperations.entries.getRevisionById(model, {
|
|
832
|
+
id: revisionId
|
|
833
|
+
});
|
|
834
|
+
const latestStorageEntry = await storageOperations.entries.getLatestRevisionByEntryId(model, {
|
|
835
|
+
id: entryId
|
|
836
|
+
});
|
|
837
|
+
const previousStorageEntry = await storageOperations.entries.getPreviousRevision(model, {
|
|
838
|
+
entryId,
|
|
839
|
+
version: version
|
|
840
|
+
});
|
|
841
|
+
if (!storageEntryToDelete) {
|
|
842
|
+
throw new _handlerGraphql.NotFoundError(`Entry "${revisionId}" was not found!`);
|
|
843
|
+
}
|
|
844
|
+
(0, _ownership.checkOwnership)(context, permission, storageEntryToDelete);
|
|
845
|
+
const latestEntryRevisionId = latestStorageEntry ? latestStorageEntry.id : null;
|
|
846
|
+
const entryToDelete = await (0, _entryStorage.entryFromStorageTransform)(context, model, storageEntryToDelete);
|
|
847
|
+
/**
|
|
848
|
+
* If targeted record is the latest entry record and there is no previous one, we need to run full delete with hooks.
|
|
849
|
+
* At this point deleteRevision hooks are not fired.
|
|
850
|
+
*/
|
|
851
|
+
if (entryToDelete.id === latestEntryRevisionId && !previousStorageEntry) {
|
|
852
|
+
return await deleteEntryHelper({
|
|
853
|
+
model,
|
|
854
|
+
entry: entryToDelete
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* If targeted record is latest entry revision, set the previous one as the new latest
|
|
859
|
+
*/
|
|
860
|
+
let entryToSetAsLatest = null;
|
|
861
|
+
let storageEntryToSetAsLatest = null;
|
|
862
|
+
if (entryToDelete.id === latestEntryRevisionId && previousStorageEntry) {
|
|
863
|
+
entryToSetAsLatest = await (0, _entryStorage.entryFromStorageTransform)(context, model, previousStorageEntry);
|
|
864
|
+
storageEntryToSetAsLatest = previousStorageEntry;
|
|
865
|
+
}
|
|
866
|
+
try {
|
|
867
|
+
await onEntryRevisionBeforeDelete.publish({
|
|
868
|
+
entry: entryToDelete,
|
|
869
|
+
model
|
|
870
|
+
});
|
|
871
|
+
await storageOperations.entries.deleteRevision(model, {
|
|
872
|
+
entry: entryToDelete,
|
|
873
|
+
storageEntry: storageEntryToDelete,
|
|
874
|
+
latestEntry: entryToSetAsLatest,
|
|
875
|
+
latestStorageEntry: storageEntryToSetAsLatest
|
|
876
|
+
});
|
|
877
|
+
await onEntryRevisionAfterDelete.publish({
|
|
878
|
+
entry: entryToDelete,
|
|
879
|
+
model
|
|
880
|
+
});
|
|
881
|
+
} catch (ex) {
|
|
882
|
+
await onEntryRevisionDeleteError.publish({
|
|
883
|
+
entry: entryToDelete,
|
|
884
|
+
model,
|
|
885
|
+
error: ex
|
|
886
|
+
});
|
|
887
|
+
throw new _error.default(ex.message, ex.code || "DELETE_REVISION_ERROR", {
|
|
888
|
+
error: ex,
|
|
889
|
+
entry: entryToDelete,
|
|
890
|
+
storageEntry: storageEntryToDelete,
|
|
891
|
+
latestEntry: entryToSetAsLatest,
|
|
892
|
+
latestStorageEntry: storageEntryToSetAsLatest
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
const deleteMultipleEntries = async (model, params) => {
|
|
897
|
+
const {
|
|
898
|
+
entries: input
|
|
899
|
+
} = params;
|
|
900
|
+
const maxDeletableEntries = 50;
|
|
901
|
+
const entryIdList = new Set();
|
|
902
|
+
for (const id of input) {
|
|
903
|
+
const {
|
|
904
|
+
id: entryId
|
|
905
|
+
} = (0, _utils.parseIdentifier)(id);
|
|
906
|
+
entryIdList.add(entryId);
|
|
907
|
+
}
|
|
908
|
+
const ids = Array.from(entryIdList);
|
|
909
|
+
if (ids.length > maxDeletableEntries) {
|
|
910
|
+
throw new _error.default("Cannot delete more than 50 entries at once.", "DELETE_ENTRIES_MAX", {
|
|
911
|
+
entries: ids
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
const permission = await checkEntryPermissions({
|
|
915
|
+
rwd: "d"
|
|
916
|
+
});
|
|
917
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
918
|
+
const {
|
|
919
|
+
items: entries
|
|
920
|
+
} = await storageOperations.entries.list(model, {
|
|
921
|
+
where: {
|
|
922
|
+
latest: true,
|
|
923
|
+
entryId_in: ids
|
|
924
|
+
},
|
|
925
|
+
limit: maxDeletableEntries + 1
|
|
926
|
+
});
|
|
927
|
+
/**
|
|
928
|
+
* We do not want to allow deleting entries that user does not own or cannot access.
|
|
929
|
+
*/
|
|
930
|
+
const items = (await (0, _filterAsync.filterAsync)(entries, async entry => {
|
|
931
|
+
return (0, _ownership.validateOwnership)(context, permission, entry);
|
|
932
|
+
})).map(entry => entry.id);
|
|
933
|
+
try {
|
|
934
|
+
await onEntryBeforeDeleteMultiple.publish({
|
|
935
|
+
entries,
|
|
936
|
+
ids,
|
|
937
|
+
model
|
|
938
|
+
});
|
|
939
|
+
await storageOperations.entries.deleteMultipleEntries(model, {
|
|
940
|
+
entries: items
|
|
941
|
+
});
|
|
942
|
+
await onEntryAfterDeleteMultiple.publish({
|
|
943
|
+
entries,
|
|
944
|
+
ids,
|
|
945
|
+
model
|
|
946
|
+
});
|
|
947
|
+
return items.map(id => {
|
|
948
|
+
return {
|
|
949
|
+
id
|
|
950
|
+
};
|
|
951
|
+
});
|
|
952
|
+
} catch (ex) {
|
|
953
|
+
await onEntryDeleteMultipleError.publish({
|
|
954
|
+
entries,
|
|
955
|
+
ids,
|
|
956
|
+
model,
|
|
957
|
+
error: ex
|
|
958
|
+
});
|
|
959
|
+
throw new _error.default(ex.message, ex.code || "DELETE_ENTRIES_MULTIPLE_ERROR", {
|
|
960
|
+
error: ex,
|
|
961
|
+
entries
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
};
|
|
965
|
+
const deleteEntry = async (model, id, options) => {
|
|
966
|
+
const permission = await checkEntryPermissions({
|
|
967
|
+
rwd: "d"
|
|
968
|
+
});
|
|
969
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
970
|
+
const {
|
|
971
|
+
force
|
|
972
|
+
} = options || {};
|
|
973
|
+
const storageEntry = await storageOperations.entries.getLatestRevisionByEntryId(model, {
|
|
974
|
+
id
|
|
975
|
+
});
|
|
976
|
+
/**
|
|
977
|
+
* If there is no entry, and we do not force the deletion, just throw an error.
|
|
978
|
+
*/
|
|
979
|
+
if (!storageEntry && !force) {
|
|
980
|
+
throw new _handlerGraphql.NotFoundError(`Entry "${id}" was not found!`);
|
|
981
|
+
}
|
|
982
|
+
/**
|
|
983
|
+
* In the case we are forcing the deletion, we do not need the storageEntry to exist as it might be an error when loading single database record.
|
|
984
|
+
*
|
|
985
|
+
* This happens, sometimes, in the Elasticsearch system as the entry might get deleted from the DynamoDB but not from the Elasticsearch.
|
|
986
|
+
* This is due to high load on the Elasticsearch at the time of the deletion.
|
|
987
|
+
*/
|
|
988
|
+
//
|
|
989
|
+
else if (!storageEntry && force) {
|
|
990
|
+
const {
|
|
991
|
+
id: entryId
|
|
992
|
+
} = (0, _utils.parseIdentifier)(id);
|
|
993
|
+
return await deleteEntryHelper({
|
|
994
|
+
model,
|
|
995
|
+
entry: {
|
|
996
|
+
id,
|
|
997
|
+
entryId
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
(0, _ownership.checkOwnership)(context, permission, storageEntry);
|
|
1002
|
+
const entry = await (0, _entryStorage.entryFromStorageTransform)(context, model, storageEntry);
|
|
1003
|
+
return await deleteEntryHelper({
|
|
1004
|
+
model,
|
|
1005
|
+
entry
|
|
1006
|
+
});
|
|
1007
|
+
};
|
|
1008
|
+
const publishEntry = async (model, id) => {
|
|
1009
|
+
const permission = await checkEntryPermissions({
|
|
1010
|
+
pw: "p"
|
|
1011
|
+
});
|
|
1012
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
1013
|
+
const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
|
|
1014
|
+
id
|
|
1015
|
+
});
|
|
1016
|
+
if (!originalStorageEntry) {
|
|
1017
|
+
throw new _handlerGraphql.NotFoundError(`Entry "${id}" in the model "${model.modelId}" was not found.`);
|
|
1018
|
+
}
|
|
1019
|
+
(0, _ownership.checkOwnership)(context, permission, originalStorageEntry);
|
|
1020
|
+
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
1021
|
+
const currentDate = new Date().toISOString();
|
|
1022
|
+
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
1023
|
+
status: STATUS_PUBLISHED,
|
|
1024
|
+
locked: true,
|
|
1025
|
+
savedOn: currentDate,
|
|
1026
|
+
publishedOn: currentDate
|
|
1027
|
+
});
|
|
1028
|
+
let storageEntry = null;
|
|
1029
|
+
try {
|
|
1030
|
+
await onEntryBeforePublish.publish({
|
|
1031
|
+
entry,
|
|
1032
|
+
model
|
|
1033
|
+
});
|
|
1034
|
+
storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
1035
|
+
const result = await storageOperations.entries.publish(model, {
|
|
1036
|
+
entry,
|
|
1037
|
+
storageEntry
|
|
1038
|
+
});
|
|
1039
|
+
await onEntryAfterPublish.publish({
|
|
1040
|
+
entry,
|
|
1041
|
+
storageEntry: result,
|
|
1042
|
+
model
|
|
1043
|
+
});
|
|
1044
|
+
return result;
|
|
1045
|
+
} catch (ex) {
|
|
1046
|
+
await onEntryPublishError.publish({
|
|
1047
|
+
entry,
|
|
1048
|
+
model,
|
|
1049
|
+
error: ex
|
|
1050
|
+
});
|
|
1051
|
+
throw new _error.default(ex.message || "Could not publish entry.", ex.code || "PUBLISH_ERROR", {
|
|
1052
|
+
error: ex,
|
|
1053
|
+
entry,
|
|
1054
|
+
storageEntry,
|
|
1055
|
+
originalEntry,
|
|
1056
|
+
originalStorageEntry
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
const unpublishEntry = async (model, id) => {
|
|
1061
|
+
const permission = await checkEntryPermissions({
|
|
1062
|
+
pw: "u"
|
|
1063
|
+
});
|
|
1064
|
+
const {
|
|
1065
|
+
id: entryId
|
|
1066
|
+
} = (0, _utils.parseIdentifier)(id);
|
|
1067
|
+
const originalStorageEntry = await storageOperations.entries.getPublishedRevisionByEntryId(model, {
|
|
1068
|
+
id: entryId
|
|
1069
|
+
});
|
|
1070
|
+
if (!originalStorageEntry) {
|
|
1071
|
+
throw new _handlerGraphql.NotFoundError(`Entry "${id}" of model "${model.modelId}" was not found.`);
|
|
1072
|
+
}
|
|
1073
|
+
if (originalStorageEntry.id !== id) {
|
|
1074
|
+
throw new _error.default(`Entry is not published.`, "UNPUBLISH_ERROR", {
|
|
1075
|
+
entry: originalStorageEntry
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
(0, _ownership.checkOwnership)(context, permission, originalStorageEntry);
|
|
1079
|
+
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
1080
|
+
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
1081
|
+
status: STATUS_UNPUBLISHED
|
|
1082
|
+
});
|
|
1083
|
+
let storageEntry = null;
|
|
1084
|
+
try {
|
|
1085
|
+
await onEntryBeforeUnpublish.publish({
|
|
1086
|
+
entry,
|
|
1087
|
+
model
|
|
1088
|
+
});
|
|
1089
|
+
storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
1090
|
+
const result = await storageOperations.entries.unpublish(model, {
|
|
1091
|
+
entry,
|
|
1092
|
+
storageEntry
|
|
1093
|
+
});
|
|
1094
|
+
await onEntryAfterUnpublish.publish({
|
|
1095
|
+
entry,
|
|
1096
|
+
storageEntry: result,
|
|
1097
|
+
model
|
|
1098
|
+
});
|
|
1099
|
+
return result;
|
|
1100
|
+
} catch (ex) {
|
|
1101
|
+
await onEntryUnpublishError.publish({
|
|
1102
|
+
entry,
|
|
1103
|
+
model,
|
|
1104
|
+
error: ex
|
|
1105
|
+
});
|
|
1106
|
+
throw new _error.default(ex.message || "Could not unpublish entry.", ex.code || "UNPUBLISH_ERROR", {
|
|
1107
|
+
originalEntry,
|
|
1108
|
+
originalStorageEntry,
|
|
1109
|
+
entry,
|
|
1110
|
+
storageEntry
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
};
|
|
1114
|
+
const getUniqueFieldValues = async (model, params) => {
|
|
1115
|
+
const permission = await checkEntryPermissions({
|
|
1116
|
+
rwd: "r"
|
|
1117
|
+
});
|
|
1118
|
+
await (0, _access.checkModelAccess)(context, model);
|
|
1119
|
+
const {
|
|
1120
|
+
where: initialWhere,
|
|
1121
|
+
fieldId
|
|
1122
|
+
} = params;
|
|
1123
|
+
const where = (0, _objectSpread2.default)({}, initialWhere);
|
|
1124
|
+
/**
|
|
1125
|
+
* Possibly only get records which are owned by current user.
|
|
1126
|
+
* Or if searching for the owner set that value - in the case that user can see other entries than their own.
|
|
1127
|
+
*/
|
|
1128
|
+
const ownedBy = permission.own ? getIdentity().id : where.ownedBy;
|
|
1129
|
+
if (ownedBy !== undefined) {
|
|
1130
|
+
where.ownedBy = ownedBy;
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Where must contain either latest or published keys.
|
|
1134
|
+
* We cannot list entries without one of those
|
|
1135
|
+
*/
|
|
1136
|
+
if (where.latest && where.published) {
|
|
1137
|
+
throw new _error.default("Cannot list entries that are both published and latest.", "LIST_ENTRIES_ERROR", {
|
|
1138
|
+
where
|
|
1139
|
+
});
|
|
1140
|
+
} else if (!where.latest && !where.published) {
|
|
1141
|
+
throw new _error.default("Cannot list entries if we do not have latest or published defined.", "LIST_ENTRIES_ERROR", {
|
|
1142
|
+
where
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
/**
|
|
1146
|
+
* We need to verify that the field in question is searchable.
|
|
1147
|
+
*/
|
|
1148
|
+
const fields = (0, _searchableFields.getSearchableFields)({
|
|
1149
|
+
fields: model.fields,
|
|
1150
|
+
plugins: context.plugins,
|
|
1151
|
+
input: []
|
|
1152
|
+
});
|
|
1153
|
+
if (fields.includes(fieldId) === false) {
|
|
1154
|
+
throw new _error.default("Cannot list unique entry field values if the field is not searchable.", "LIST_UNIQUE_ENTRY_VALUES_ERROR", {
|
|
1155
|
+
fieldId
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
try {
|
|
1159
|
+
return await storageOperations.entries.getUniqueFieldValues(model, {
|
|
1160
|
+
where,
|
|
1161
|
+
fieldId
|
|
1162
|
+
});
|
|
1163
|
+
} catch (ex) {
|
|
1164
|
+
throw new _error.default("Error while fetching unique entry values from storage.", "LIST_UNIQUE_ENTRY_VALUES_ERROR", {
|
|
1165
|
+
error: {
|
|
1166
|
+
message: ex.message,
|
|
1167
|
+
code: ex.code,
|
|
1168
|
+
data: ex.data
|
|
1169
|
+
},
|
|
1170
|
+
model,
|
|
1171
|
+
where,
|
|
1172
|
+
fieldId
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
};
|
|
1176
|
+
return {
|
|
1177
|
+
/**
|
|
1178
|
+
* Deprecated - will be removed in 5.35.0
|
|
1179
|
+
*/
|
|
1180
|
+
onBeforeEntryCreate: onEntryBeforeCreate,
|
|
1181
|
+
onAfterEntryCreate: onEntryAfterCreate,
|
|
1182
|
+
onBeforeEntryCreateRevision: onEntryBeforeCreateRevision,
|
|
1183
|
+
onAfterEntryCreateRevision: onEntryRevisionAfterCreate,
|
|
1184
|
+
onBeforeEntryUpdate: onEntryBeforeUpdate,
|
|
1185
|
+
onAfterEntryUpdate: onEntryAfterUpdate,
|
|
1186
|
+
onBeforeEntryDelete: onEntryBeforeDelete,
|
|
1187
|
+
onAfterEntryDelete: onEntryAfterDelete,
|
|
1188
|
+
onBeforeEntryDeleteRevision: onEntryRevisionBeforeDelete,
|
|
1189
|
+
onAfterEntryDeleteRevision: onEntryRevisionAfterDelete,
|
|
1190
|
+
onBeforeEntryPublish: onEntryBeforePublish,
|
|
1191
|
+
onAfterEntryPublish: onEntryAfterPublish,
|
|
1192
|
+
onBeforeEntryUnpublish: onEntryBeforeUnpublish,
|
|
1193
|
+
onAfterEntryUnpublish: onEntryAfterUnpublish,
|
|
1194
|
+
onBeforeEntryGet: onEntryBeforeGet,
|
|
1195
|
+
onBeforeEntryList: onEntryBeforeList,
|
|
1196
|
+
/**
|
|
1197
|
+
* Released in 5.34.0
|
|
1198
|
+
*
|
|
1199
|
+
* Create
|
|
1200
|
+
*/
|
|
1201
|
+
onEntryBeforeCreate,
|
|
1202
|
+
onEntryAfterCreate,
|
|
1203
|
+
onEntryCreateError,
|
|
1204
|
+
/**
|
|
1205
|
+
* Create revision
|
|
1206
|
+
*/
|
|
1207
|
+
onEntryRevisionBeforeCreate: onEntryBeforeCreateRevision,
|
|
1208
|
+
onEntryRevisionAfterCreate,
|
|
1209
|
+
onEntryRevisionCreateError: onEntryCreateRevisionError,
|
|
1210
|
+
/**
|
|
1211
|
+
* Update
|
|
1212
|
+
*/
|
|
1213
|
+
onEntryBeforeUpdate,
|
|
1214
|
+
onEntryAfterUpdate,
|
|
1215
|
+
onEntryUpdateError,
|
|
1216
|
+
/**
|
|
1217
|
+
* Delete whole entry
|
|
1218
|
+
*/
|
|
1219
|
+
onEntryBeforeDelete,
|
|
1220
|
+
onEntryAfterDelete,
|
|
1221
|
+
onEntryDeleteError,
|
|
1222
|
+
/**
|
|
1223
|
+
* Delete entry revision
|
|
1224
|
+
*/
|
|
1225
|
+
onEntryRevisionBeforeDelete,
|
|
1226
|
+
onEntryRevisionAfterDelete,
|
|
1227
|
+
onEntryRevisionDeleteError,
|
|
1228
|
+
/**
|
|
1229
|
+
* Publish
|
|
1230
|
+
*/
|
|
1231
|
+
onEntryBeforePublish,
|
|
1232
|
+
onEntryAfterPublish,
|
|
1233
|
+
onEntryPublishError,
|
|
1234
|
+
/**
|
|
1235
|
+
* Republish
|
|
1236
|
+
*/
|
|
1237
|
+
onEntryBeforeRepublish,
|
|
1238
|
+
onEntryAfterRepublish,
|
|
1239
|
+
onEntryRepublishError,
|
|
1240
|
+
/**
|
|
1241
|
+
* Unpublish
|
|
1242
|
+
*/
|
|
1243
|
+
onEntryBeforeUnpublish,
|
|
1244
|
+
onEntryAfterUnpublish,
|
|
1245
|
+
onEntryUnpublishError,
|
|
1246
|
+
onEntryBeforeGet,
|
|
1247
|
+
onEntryBeforeList,
|
|
1248
|
+
/**
|
|
1249
|
+
* Get entries by exact revision IDs from the database.
|
|
1250
|
+
*/
|
|
1251
|
+
getEntriesByIds,
|
|
1252
|
+
/**
|
|
1253
|
+
* Get a single entry by revision ID from the database.
|
|
1254
|
+
*/
|
|
1255
|
+
async getEntryById(model, id) {
|
|
1256
|
+
return context.benchmark.measure("headlessCms.crud.entries.getEntryById", async () => {
|
|
1257
|
+
return getEntryById(model, id);
|
|
431
1258
|
});
|
|
432
|
-
|
|
433
|
-
|
|
1259
|
+
},
|
|
1260
|
+
/**
|
|
1261
|
+
* Get published revisions by entry IDs.
|
|
1262
|
+
*/
|
|
1263
|
+
async getPublishedEntriesByIds(model, ids) {
|
|
1264
|
+
return context.benchmark.measure("headlessCms.crud.entries.getPublishedEntriesByIds", async () => {
|
|
1265
|
+
return getPublishedEntriesByIds(model, ids);
|
|
434
1266
|
});
|
|
435
|
-
return entries.filter(entry => (0, _ownership.validateOwnership)(context, permission, entry));
|
|
436
1267
|
},
|
|
437
1268
|
/**
|
|
438
1269
|
* Get the latest revisions by entry IDs.
|
|
439
1270
|
*/
|
|
440
|
-
async getLatestEntriesByIds(
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
});
|
|
444
|
-
await (0, _access.checkModelAccess)(context, initialModel);
|
|
445
|
-
const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
|
|
446
|
-
model: initialModel,
|
|
447
|
-
plugins
|
|
1271
|
+
async getLatestEntriesByIds(model, ids) {
|
|
1272
|
+
return context.benchmark.measure("headlessCms.crud.entries.getLatestEntriesByIds", async () => {
|
|
1273
|
+
return getLatestEntriesByIds(model, ids);
|
|
448
1274
|
});
|
|
449
|
-
const entries = await storageOperations.entries.getLatestByIds(model, {
|
|
450
|
-
ids
|
|
451
|
-
});
|
|
452
|
-
return entries.filter(entry => (0, _ownership.validateOwnership)(context, permission, entry));
|
|
453
1275
|
},
|
|
454
|
-
async getEntryRevisions(
|
|
455
|
-
|
|
456
|
-
model
|
|
457
|
-
plugins
|
|
458
|
-
});
|
|
459
|
-
return storageOperations.entries.getRevisions(model, {
|
|
460
|
-
id: entryId
|
|
1276
|
+
async getEntryRevisions(model, entryId) {
|
|
1277
|
+
return context.benchmark.measure("headlessCms.crud.entries.getEntryRevisions", async () => {
|
|
1278
|
+
return getEntryRevisions(model, entryId);
|
|
461
1279
|
});
|
|
462
1280
|
},
|
|
463
1281
|
/**
|
|
@@ -465,118 +1283,20 @@ const createContentEntryCrud = params => {
|
|
|
465
1283
|
*
|
|
466
1284
|
* @internal
|
|
467
1285
|
*/
|
|
468
|
-
async getEntry(
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
});
|
|
472
|
-
const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
|
|
473
|
-
model: initialModel,
|
|
474
|
-
plugins
|
|
475
|
-
});
|
|
476
|
-
const {
|
|
477
|
-
where,
|
|
478
|
-
sort
|
|
479
|
-
} = params;
|
|
480
|
-
await onEntryBeforeGet.publish({
|
|
481
|
-
where,
|
|
482
|
-
model
|
|
483
|
-
});
|
|
484
|
-
const [items] = await this.listEntries(model, {
|
|
485
|
-
where,
|
|
486
|
-
sort,
|
|
487
|
-
limit: 1
|
|
1286
|
+
async getEntry(model, params) {
|
|
1287
|
+
return context.benchmark.measure("headlessCms.crud.entries.getEntry", async () => {
|
|
1288
|
+
return getEntry(model, params);
|
|
488
1289
|
});
|
|
489
|
-
if (items.length === 0) {
|
|
490
|
-
throw new _handlerGraphql.NotFoundError(`Entry not found!`);
|
|
491
|
-
}
|
|
492
|
-
return items[0];
|
|
493
1290
|
},
|
|
494
1291
|
/**
|
|
495
1292
|
* @description Should not be used directly. Internal use only!
|
|
496
1293
|
*
|
|
497
1294
|
* @internal
|
|
498
1295
|
*/
|
|
499
|
-
async listEntries(
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
});
|
|
503
|
-
await (0, _access.checkModelAccess)(context, initialModel);
|
|
504
|
-
const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
|
|
505
|
-
model: initialModel,
|
|
506
|
-
plugins
|
|
507
|
-
});
|
|
508
|
-
const {
|
|
509
|
-
where: initialWhere,
|
|
510
|
-
limit: initialLimit
|
|
511
|
-
} = params;
|
|
512
|
-
const limit = initialLimit && initialLimit > 0 ? initialLimit : 50;
|
|
513
|
-
/**
|
|
514
|
-
* We always assign tenant and locale because we do not allow one model to have content through multiple tenants.
|
|
515
|
-
*/
|
|
516
|
-
const where = (0, _objectSpread2.default)({}, initialWhere);
|
|
517
|
-
/**
|
|
518
|
-
* Possibly only get records which are owned by current user.
|
|
519
|
-
* Or if searching for the owner set that value - in the case that user can see other entries than their own.
|
|
520
|
-
*/
|
|
521
|
-
const ownedBy = permission.own ? getIdentity().id : where.ownedBy;
|
|
522
|
-
if (ownedBy !== undefined) {
|
|
523
|
-
where.ownedBy = ownedBy;
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* Where must contain either latest or published keys.
|
|
527
|
-
* We cannot list entries without one of those
|
|
528
|
-
*/
|
|
529
|
-
if (where.latest && where.published) {
|
|
530
|
-
throw new _error.default("Cannot list entries that are both published and latest.", "LIST_ENTRIES_ERROR", {
|
|
531
|
-
where
|
|
532
|
-
});
|
|
533
|
-
} else if (!where.latest && !where.published) {
|
|
534
|
-
throw new _error.default("Cannot list entries if we do not have latest or published defined.", "LIST_ENTRIES_ERROR", {
|
|
535
|
-
where
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
|
-
const fields = (0, _searchableFields.getSearchableFields)({
|
|
539
|
-
fields: model.fields,
|
|
540
|
-
plugins: context.plugins,
|
|
541
|
-
input: params.fields || []
|
|
1296
|
+
async listEntries(model, params) {
|
|
1297
|
+
return context.benchmark.measure("headlessCms.crud.entries.listEntries", async () => {
|
|
1298
|
+
return listEntries(model, params);
|
|
542
1299
|
});
|
|
543
|
-
try {
|
|
544
|
-
await onEntryBeforeList.publish({
|
|
545
|
-
where,
|
|
546
|
-
model
|
|
547
|
-
});
|
|
548
|
-
const {
|
|
549
|
-
hasMoreItems,
|
|
550
|
-
totalCount,
|
|
551
|
-
cursor,
|
|
552
|
-
items
|
|
553
|
-
} = await storageOperations.entries.list(model, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, params), {}, {
|
|
554
|
-
limit,
|
|
555
|
-
where,
|
|
556
|
-
fields
|
|
557
|
-
}));
|
|
558
|
-
const meta = {
|
|
559
|
-
hasMoreItems,
|
|
560
|
-
totalCount,
|
|
561
|
-
/**
|
|
562
|
-
* Cursor should be null if there are no more items to load.
|
|
563
|
-
* Just make sure of that, disregarding what is returned from the storageOperations.entries.list method.
|
|
564
|
-
*/
|
|
565
|
-
cursor: hasMoreItems ? cursor : null
|
|
566
|
-
};
|
|
567
|
-
return [items, meta];
|
|
568
|
-
} catch (ex) {
|
|
569
|
-
throw new _error.default("Error while fetching entries from storage.", "LIST_ENTRIES_ERROR", {
|
|
570
|
-
params,
|
|
571
|
-
error: {
|
|
572
|
-
message: ex.message,
|
|
573
|
-
code: ex.code,
|
|
574
|
-
data: ex.data
|
|
575
|
-
},
|
|
576
|
-
model,
|
|
577
|
-
fields
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
1300
|
},
|
|
581
1301
|
async listLatestEntries(model, params) {
|
|
582
1302
|
const where = (params === null || params === void 0 ? void 0 : params.where) || {};
|
|
@@ -598,596 +1318,59 @@ const createContentEntryCrud = params => {
|
|
|
598
1318
|
})
|
|
599
1319
|
}));
|
|
600
1320
|
},
|
|
601
|
-
async createEntry(
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
});
|
|
605
|
-
await (0, _access.checkModelAccess)(context, initialModel);
|
|
606
|
-
const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
|
|
607
|
-
model: initialModel,
|
|
608
|
-
plugins
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
/**
|
|
612
|
-
* Make sure we only work with fields that are defined in the model.
|
|
613
|
-
*/
|
|
614
|
-
const initialInput = mapAndCleanCreateInputData(model, inputData);
|
|
615
|
-
await (0, _entryDataValidation.validateModelEntryData)({
|
|
616
|
-
context,
|
|
617
|
-
model,
|
|
618
|
-
data: initialInput
|
|
619
|
-
});
|
|
620
|
-
const input = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
621
|
-
context,
|
|
622
|
-
model,
|
|
623
|
-
input: initialInput,
|
|
624
|
-
validateEntries: true
|
|
1321
|
+
async createEntry(model, input) {
|
|
1322
|
+
return context.benchmark.measure("headlessCms.crud.entries.createEntry", async () => {
|
|
1323
|
+
return createEntry(model, input);
|
|
625
1324
|
});
|
|
626
|
-
const identity = context.security.getIdentity();
|
|
627
|
-
const locale = this.getLocale();
|
|
628
|
-
const owner = {
|
|
629
|
-
id: identity.id,
|
|
630
|
-
displayName: identity.displayName,
|
|
631
|
-
type: identity.type
|
|
632
|
-
};
|
|
633
|
-
/**
|
|
634
|
-
* There is a possibility that user sends an ID in the input, so we will use that one.
|
|
635
|
-
* There is no check if the ID is unique or not, that is up to the user.
|
|
636
|
-
*/
|
|
637
|
-
const {
|
|
638
|
-
id,
|
|
639
|
-
entryId,
|
|
640
|
-
version
|
|
641
|
-
} = createEntryId(inputData);
|
|
642
|
-
const entry = {
|
|
643
|
-
webinyVersion: context.WEBINY_VERSION,
|
|
644
|
-
tenant: getTenant().id,
|
|
645
|
-
entryId,
|
|
646
|
-
id,
|
|
647
|
-
modelId: model.modelId,
|
|
648
|
-
locale: locale.code,
|
|
649
|
-
createdOn: new Date().toISOString(),
|
|
650
|
-
savedOn: new Date().toISOString(),
|
|
651
|
-
createdBy: owner,
|
|
652
|
-
ownedBy: owner,
|
|
653
|
-
version,
|
|
654
|
-
locked: false,
|
|
655
|
-
status: STATUS_DRAFT,
|
|
656
|
-
values: input
|
|
657
|
-
};
|
|
658
|
-
let storageEntry = null;
|
|
659
|
-
try {
|
|
660
|
-
await onEntryBeforeCreate.publish({
|
|
661
|
-
entry,
|
|
662
|
-
input,
|
|
663
|
-
model
|
|
664
|
-
});
|
|
665
|
-
storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
666
|
-
const result = await storageOperations.entries.create(model, {
|
|
667
|
-
entry,
|
|
668
|
-
storageEntry
|
|
669
|
-
});
|
|
670
|
-
await onEntryAfterCreate.publish({
|
|
671
|
-
entry,
|
|
672
|
-
storageEntry: result,
|
|
673
|
-
model,
|
|
674
|
-
input
|
|
675
|
-
});
|
|
676
|
-
return result;
|
|
677
|
-
} catch (ex) {
|
|
678
|
-
await onEntryCreateError.publish({
|
|
679
|
-
error: ex,
|
|
680
|
-
entry,
|
|
681
|
-
model,
|
|
682
|
-
input
|
|
683
|
-
});
|
|
684
|
-
throw new _error.default(ex.message || "Could not create content entry.", ex.code || "CREATE_ENTRY_ERROR", ex.data || {
|
|
685
|
-
error: ex,
|
|
686
|
-
input,
|
|
687
|
-
entry,
|
|
688
|
-
storageEntry
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
1325
|
},
|
|
692
|
-
async createEntryRevisionFrom(
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
});
|
|
696
|
-
await (0, _access.checkModelAccess)(context, initialModel);
|
|
697
|
-
const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
|
|
698
|
-
model: initialModel,
|
|
699
|
-
plugins
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
/**
|
|
703
|
-
* Make sure we only work with fields that are defined in the model.
|
|
704
|
-
*/
|
|
705
|
-
const input = mapAndCleanUpdatedInputData(model, inputData);
|
|
706
|
-
|
|
707
|
-
/**
|
|
708
|
-
* Entries are identified by a common parent ID + Revision number.
|
|
709
|
-
*/
|
|
710
|
-
const {
|
|
711
|
-
id: uniqueId
|
|
712
|
-
} = (0, _utils.parseIdentifier)(sourceId);
|
|
713
|
-
const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
|
|
714
|
-
id: sourceId
|
|
715
|
-
});
|
|
716
|
-
const latestStorageEntry = await storageOperations.entries.getLatestRevisionByEntryId(model, {
|
|
717
|
-
id: uniqueId
|
|
718
|
-
});
|
|
719
|
-
if (!originalStorageEntry) {
|
|
720
|
-
throw new _handlerGraphql.NotFoundError(`Entry "${sourceId}" of model "${model.modelId}" was not found.`);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
/**
|
|
724
|
-
* We need to convert data from DB to its original form before using it further.
|
|
725
|
-
*/
|
|
726
|
-
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
727
|
-
const initialValues = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry.values), input);
|
|
728
|
-
await (0, _entryDataValidation.validateModelEntryData)({
|
|
729
|
-
context,
|
|
730
|
-
model,
|
|
731
|
-
data: initialValues,
|
|
732
|
-
entry: originalEntry
|
|
733
|
-
});
|
|
734
|
-
const values = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
735
|
-
context,
|
|
736
|
-
model,
|
|
737
|
-
input: initialValues,
|
|
738
|
-
validateEntries: false
|
|
739
|
-
});
|
|
740
|
-
(0, _ownership.checkOwnership)(context, permission, originalEntry);
|
|
741
|
-
const identity = context.security.getIdentity();
|
|
742
|
-
const latestId = latestStorageEntry ? latestStorageEntry.id : sourceId;
|
|
743
|
-
const {
|
|
744
|
-
id,
|
|
745
|
-
version: nextVersion
|
|
746
|
-
} = increaseEntryIdVersion(latestId);
|
|
747
|
-
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
748
|
-
id,
|
|
749
|
-
version: nextVersion,
|
|
750
|
-
savedOn: new Date().toISOString(),
|
|
751
|
-
createdOn: new Date().toISOString(),
|
|
752
|
-
createdBy: {
|
|
753
|
-
id: identity.id,
|
|
754
|
-
displayName: identity.displayName,
|
|
755
|
-
type: identity.type
|
|
756
|
-
},
|
|
757
|
-
locked: false,
|
|
758
|
-
publishedOn: undefined,
|
|
759
|
-
status: STATUS_DRAFT,
|
|
760
|
-
values
|
|
1326
|
+
async createEntryRevisionFrom(model, sourceId, input) {
|
|
1327
|
+
return context.benchmark.measure("headlessCms.crud.entries.createEntryRevisionFrom", async () => {
|
|
1328
|
+
return createEntryRevisionFrom(model, sourceId, input);
|
|
761
1329
|
});
|
|
762
|
-
let storageEntry = null;
|
|
763
|
-
try {
|
|
764
|
-
await onEntryBeforeCreateRevision.publish({
|
|
765
|
-
input,
|
|
766
|
-
entry,
|
|
767
|
-
original: originalEntry,
|
|
768
|
-
model
|
|
769
|
-
});
|
|
770
|
-
storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
771
|
-
const result = await storageOperations.entries.createRevisionFrom(model, {
|
|
772
|
-
entry,
|
|
773
|
-
storageEntry
|
|
774
|
-
});
|
|
775
|
-
await onEntryRevisionAfterCreate.publish({
|
|
776
|
-
input,
|
|
777
|
-
entry,
|
|
778
|
-
model,
|
|
779
|
-
original: originalEntry,
|
|
780
|
-
storageEntry: result
|
|
781
|
-
});
|
|
782
|
-
return result;
|
|
783
|
-
} catch (ex) {
|
|
784
|
-
await onEntryCreateRevisionError.publish({
|
|
785
|
-
entry,
|
|
786
|
-
original: originalEntry,
|
|
787
|
-
model,
|
|
788
|
-
input,
|
|
789
|
-
error: ex
|
|
790
|
-
});
|
|
791
|
-
throw new _error.default(ex.message || "Could not create entry from existing one.", ex.code || "CREATE_FROM_REVISION_ERROR", {
|
|
792
|
-
error: ex,
|
|
793
|
-
entry,
|
|
794
|
-
storageEntry,
|
|
795
|
-
originalEntry,
|
|
796
|
-
originalStorageEntry
|
|
797
|
-
});
|
|
798
|
-
}
|
|
799
1330
|
},
|
|
800
|
-
async updateEntry(
|
|
801
|
-
|
|
802
|
-
|
|
1331
|
+
async updateEntry(model, id, input, meta) {
|
|
1332
|
+
return context.benchmark.measure("headlessCms.crud.entries.updateEntry", async () => {
|
|
1333
|
+
return updateEntry(model, id, input, meta);
|
|
803
1334
|
});
|
|
804
|
-
await (0, _access.checkModelAccess)(context, initialModel);
|
|
805
|
-
const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
|
|
806
|
-
model: initialModel,
|
|
807
|
-
plugins
|
|
808
|
-
});
|
|
809
|
-
|
|
810
|
-
/**
|
|
811
|
-
* Make sure we only work with fields that are defined in the model.
|
|
812
|
-
*/
|
|
813
|
-
const input = mapAndCleanUpdatedInputData(model, inputData);
|
|
814
|
-
|
|
815
|
-
/**
|
|
816
|
-
* The entry we are going to update.
|
|
817
|
-
*/
|
|
818
|
-
const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
|
|
819
|
-
id
|
|
820
|
-
});
|
|
821
|
-
if (!originalStorageEntry) {
|
|
822
|
-
throw new _handlerGraphql.NotFoundError(`Entry "${id}" of model "${model.modelId}" was not found.`);
|
|
823
|
-
}
|
|
824
|
-
if (originalStorageEntry.locked) {
|
|
825
|
-
throw new _error.default(`Cannot update entry because it's locked.`, "CONTENT_ENTRY_UPDATE_ERROR");
|
|
826
|
-
}
|
|
827
|
-
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
828
|
-
await (0, _entryDataValidation.validateModelEntryData)({
|
|
829
|
-
context,
|
|
830
|
-
model,
|
|
831
|
-
data: input,
|
|
832
|
-
entry: originalEntry
|
|
833
|
-
});
|
|
834
|
-
(0, _ownership.checkOwnership)(context, permission, originalEntry);
|
|
835
|
-
const initialValues = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry.values), input);
|
|
836
|
-
const values = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
837
|
-
context,
|
|
838
|
-
model,
|
|
839
|
-
input: initialValues,
|
|
840
|
-
validateEntries: false
|
|
841
|
-
});
|
|
842
|
-
/**
|
|
843
|
-
* If users wants to remove a key from meta values, they need to send meta key with the null value.
|
|
844
|
-
*/
|
|
845
|
-
const meta = createEntryMeta(metaInput, originalEntry.meta);
|
|
846
|
-
/**
|
|
847
|
-
* We always send the full entry to the hooks and storage operations update.
|
|
848
|
-
*/
|
|
849
|
-
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
850
|
-
savedOn: new Date().toISOString(),
|
|
851
|
-
values,
|
|
852
|
-
meta,
|
|
853
|
-
status: transformEntryStatus(originalEntry.status)
|
|
854
|
-
});
|
|
855
|
-
let storageEntry = null;
|
|
856
|
-
try {
|
|
857
|
-
await onEntryBeforeUpdate.publish({
|
|
858
|
-
entry,
|
|
859
|
-
model,
|
|
860
|
-
input,
|
|
861
|
-
original: originalEntry
|
|
862
|
-
});
|
|
863
|
-
storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
864
|
-
const result = await storageOperations.entries.update(model, {
|
|
865
|
-
entry,
|
|
866
|
-
storageEntry
|
|
867
|
-
});
|
|
868
|
-
await onEntryAfterUpdate.publish({
|
|
869
|
-
entry,
|
|
870
|
-
storageEntry: result,
|
|
871
|
-
model,
|
|
872
|
-
input,
|
|
873
|
-
original: originalEntry
|
|
874
|
-
});
|
|
875
|
-
return result;
|
|
876
|
-
} catch (ex) {
|
|
877
|
-
await onEntryUpdateError.publish({
|
|
878
|
-
entry,
|
|
879
|
-
model,
|
|
880
|
-
input,
|
|
881
|
-
error: ex
|
|
882
|
-
});
|
|
883
|
-
throw new _error.default(ex.message || "Could not update existing entry.", ex.code || "UPDATE_ERROR", {
|
|
884
|
-
error: ex,
|
|
885
|
-
entry,
|
|
886
|
-
storageEntry,
|
|
887
|
-
originalEntry,
|
|
888
|
-
input
|
|
889
|
-
});
|
|
890
|
-
}
|
|
891
1335
|
},
|
|
892
1336
|
/**
|
|
893
1337
|
* Method used internally. Not documented and should not be used in users systems.
|
|
894
1338
|
* @internal
|
|
895
1339
|
*/
|
|
896
|
-
async republishEntry(
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
});
|
|
900
|
-
await (0, _access.checkModelAccess)(context, initialModel);
|
|
901
|
-
const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
|
|
902
|
-
model: initialModel,
|
|
903
|
-
plugins
|
|
904
|
-
});
|
|
905
|
-
/**
|
|
906
|
-
* Fetch the entry from the storage.
|
|
907
|
-
*/
|
|
908
|
-
const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
|
|
909
|
-
id
|
|
910
|
-
});
|
|
911
|
-
if (!originalStorageEntry) {
|
|
912
|
-
throw new _handlerGraphql.NotFoundError(`Entry "${id}" was not found!`);
|
|
913
|
-
}
|
|
914
|
-
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
915
|
-
/**
|
|
916
|
-
* We can only process published entries.
|
|
917
|
-
*/
|
|
918
|
-
if (originalEntry.status !== "published") {
|
|
919
|
-
throw new _error.default("Entry with given ID is not published!", "NOT_PUBLISHED_ERROR", {
|
|
920
|
-
id,
|
|
921
|
-
original: originalEntry
|
|
922
|
-
});
|
|
923
|
-
}
|
|
924
|
-
const values = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
925
|
-
context,
|
|
926
|
-
model,
|
|
927
|
-
input: originalEntry.values,
|
|
928
|
-
validateEntries: false
|
|
929
|
-
});
|
|
930
|
-
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
931
|
-
savedOn: new Date().toISOString(),
|
|
932
|
-
webinyVersion: context.WEBINY_VERSION,
|
|
933
|
-
values
|
|
934
|
-
});
|
|
935
|
-
const storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
936
|
-
/**
|
|
937
|
-
* First we need to update existing entry.
|
|
938
|
-
*/
|
|
939
|
-
try {
|
|
940
|
-
await storageOperations.entries.update(model, {
|
|
941
|
-
entry,
|
|
942
|
-
storageEntry
|
|
943
|
-
});
|
|
944
|
-
} catch (ex) {
|
|
945
|
-
throw new _error.default("Could not update existing entry with new data while re-publishing.", "REPUBLISH_UPDATE_ERROR", {
|
|
946
|
-
entry
|
|
947
|
-
});
|
|
948
|
-
}
|
|
949
|
-
/**
|
|
950
|
-
* Then we move onto publishing it again.
|
|
951
|
-
*/
|
|
952
|
-
try {
|
|
953
|
-
await onEntryBeforeRepublish.publish({
|
|
954
|
-
entry,
|
|
955
|
-
model
|
|
956
|
-
});
|
|
957
|
-
const result = await storageOperations.entries.publish(model, {
|
|
958
|
-
entry,
|
|
959
|
-
storageEntry
|
|
960
|
-
});
|
|
961
|
-
await onEntryAfterRepublish.publish({
|
|
962
|
-
entry,
|
|
963
|
-
model,
|
|
964
|
-
storageEntry
|
|
965
|
-
});
|
|
966
|
-
return result;
|
|
967
|
-
} catch (ex) {
|
|
968
|
-
await onEntryRepublishError.publish({
|
|
969
|
-
entry,
|
|
970
|
-
model,
|
|
971
|
-
error: ex
|
|
972
|
-
});
|
|
973
|
-
throw new _error.default("Could not publish existing entry while re-publishing.", "REPUBLISH_PUBLISH_ERROR", {
|
|
974
|
-
entry
|
|
975
|
-
});
|
|
976
|
-
}
|
|
977
|
-
},
|
|
978
|
-
async deleteEntryRevision(initialModel, revisionId) {
|
|
979
|
-
const permission = await checkEntryPermissions({
|
|
980
|
-
rwd: "d"
|
|
1340
|
+
async republishEntry(model, id) {
|
|
1341
|
+
return context.benchmark.measure("headlessCms.crud.entries.republishEntry", async () => {
|
|
1342
|
+
return republishEntry(model, id);
|
|
981
1343
|
});
|
|
982
|
-
await (0, _access.checkModelAccess)(context, initialModel);
|
|
983
|
-
const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
|
|
984
|
-
model: initialModel,
|
|
985
|
-
plugins
|
|
986
|
-
});
|
|
987
|
-
const {
|
|
988
|
-
id: entryId,
|
|
989
|
-
version
|
|
990
|
-
} = (0, _utils.parseIdentifier)(revisionId);
|
|
991
|
-
const storageEntryToDelete = await storageOperations.entries.getRevisionById(model, {
|
|
992
|
-
id: revisionId
|
|
993
|
-
});
|
|
994
|
-
const latestStorageEntry = await storageOperations.entries.getLatestRevisionByEntryId(model, {
|
|
995
|
-
id: entryId
|
|
996
|
-
});
|
|
997
|
-
const previousStorageEntry = await storageOperations.entries.getPreviousRevision(model, {
|
|
998
|
-
entryId,
|
|
999
|
-
version: version
|
|
1000
|
-
});
|
|
1001
|
-
if (!storageEntryToDelete) {
|
|
1002
|
-
throw new _handlerGraphql.NotFoundError(`Entry "${revisionId}" was not found!`);
|
|
1003
|
-
}
|
|
1004
|
-
(0, _ownership.checkOwnership)(context, permission, storageEntryToDelete);
|
|
1005
|
-
const latestEntryRevisionId = latestStorageEntry ? latestStorageEntry.id : null;
|
|
1006
|
-
const entryToDelete = await (0, _entryStorage.entryFromStorageTransform)(context, model, storageEntryToDelete);
|
|
1007
|
-
/**
|
|
1008
|
-
* If targeted record is the latest entry record and there is no previous one, we need to run full delete with hooks.
|
|
1009
|
-
* At this point deleteRevision hooks are not fired.
|
|
1010
|
-
*/
|
|
1011
|
-
if (entryToDelete.id === latestEntryRevisionId && !previousStorageEntry) {
|
|
1012
|
-
return await deleteEntry({
|
|
1013
|
-
model,
|
|
1014
|
-
entry: entryToDelete
|
|
1015
|
-
});
|
|
1016
|
-
}
|
|
1017
|
-
/**
|
|
1018
|
-
* If targeted record is latest entry revision, set the previous one as the new latest
|
|
1019
|
-
*/
|
|
1020
|
-
let entryToSetAsLatest = null;
|
|
1021
|
-
let storageEntryToSetAsLatest = null;
|
|
1022
|
-
if (entryToDelete.id === latestEntryRevisionId && previousStorageEntry) {
|
|
1023
|
-
entryToSetAsLatest = await (0, _entryStorage.entryFromStorageTransform)(context, model, previousStorageEntry);
|
|
1024
|
-
storageEntryToSetAsLatest = previousStorageEntry;
|
|
1025
|
-
}
|
|
1026
|
-
try {
|
|
1027
|
-
await onEntryRevisionBeforeDelete.publish({
|
|
1028
|
-
entry: entryToDelete,
|
|
1029
|
-
model
|
|
1030
|
-
});
|
|
1031
|
-
await storageOperations.entries.deleteRevision(model, {
|
|
1032
|
-
entry: entryToDelete,
|
|
1033
|
-
storageEntry: storageEntryToDelete,
|
|
1034
|
-
latestEntry: entryToSetAsLatest,
|
|
1035
|
-
latestStorageEntry: storageEntryToSetAsLatest
|
|
1036
|
-
});
|
|
1037
|
-
await onEntryRevisionAfterDelete.publish({
|
|
1038
|
-
entry: entryToDelete,
|
|
1039
|
-
model
|
|
1040
|
-
});
|
|
1041
|
-
} catch (ex) {
|
|
1042
|
-
await onEntryRevisionDeleteError.publish({
|
|
1043
|
-
entry: entryToDelete,
|
|
1044
|
-
model,
|
|
1045
|
-
error: ex
|
|
1046
|
-
});
|
|
1047
|
-
throw new _error.default(ex.message, ex.code || "DELETE_REVISION_ERROR", {
|
|
1048
|
-
error: ex,
|
|
1049
|
-
entry: entryToDelete,
|
|
1050
|
-
storageEntry: storageEntryToDelete,
|
|
1051
|
-
latestEntry: entryToSetAsLatest,
|
|
1052
|
-
latestStorageEntry: storageEntryToSetAsLatest
|
|
1053
|
-
});
|
|
1054
|
-
}
|
|
1055
1344
|
},
|
|
1056
|
-
async
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
});
|
|
1060
|
-
await (0, _access.checkModelAccess)(context, initialModel);
|
|
1061
|
-
const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
|
|
1062
|
-
model: initialModel,
|
|
1063
|
-
plugins
|
|
1064
|
-
});
|
|
1065
|
-
const storageEntry = await storageOperations.entries.getLatestRevisionByEntryId(model, {
|
|
1066
|
-
id: entryId
|
|
1067
|
-
});
|
|
1068
|
-
if (!storageEntry) {
|
|
1069
|
-
throw new _handlerGraphql.NotFoundError(`Entry "${entryId}" was not found!`);
|
|
1070
|
-
}
|
|
1071
|
-
(0, _ownership.checkOwnership)(context, permission, storageEntry);
|
|
1072
|
-
const entry = await (0, _entryStorage.entryFromStorageTransform)(context, model, storageEntry);
|
|
1073
|
-
return await deleteEntry({
|
|
1074
|
-
model,
|
|
1075
|
-
entry
|
|
1345
|
+
async deleteEntryRevision(model, id) {
|
|
1346
|
+
return context.benchmark.measure("headlessCms.crud.entries.deleteEntryRevision", async () => {
|
|
1347
|
+
return deleteEntryRevision(model, id);
|
|
1076
1348
|
});
|
|
1077
1349
|
},
|
|
1078
|
-
async
|
|
1079
|
-
|
|
1080
|
-
|
|
1350
|
+
async deleteEntry(model, entryId) {
|
|
1351
|
+
return context.benchmark.measure("headlessCms.crud.entries.deleteEntry", async () => {
|
|
1352
|
+
return deleteEntry(model, entryId);
|
|
1081
1353
|
});
|
|
1082
|
-
await (0, _access.checkModelAccess)(context, initialModel);
|
|
1083
|
-
const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
|
|
1084
|
-
model: initialModel,
|
|
1085
|
-
plugins
|
|
1086
|
-
});
|
|
1087
|
-
const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
|
|
1088
|
-
id
|
|
1089
|
-
});
|
|
1090
|
-
if (!originalStorageEntry) {
|
|
1091
|
-
throw new _handlerGraphql.NotFoundError(`Entry "${id}" in the model "${model.modelId}" was not found.`);
|
|
1092
|
-
}
|
|
1093
|
-
(0, _ownership.checkOwnership)(context, permission, originalStorageEntry);
|
|
1094
|
-
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
1095
|
-
const currentDate = new Date().toISOString();
|
|
1096
|
-
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
1097
|
-
status: STATUS_PUBLISHED,
|
|
1098
|
-
locked: true,
|
|
1099
|
-
savedOn: currentDate,
|
|
1100
|
-
publishedOn: currentDate
|
|
1101
|
-
});
|
|
1102
|
-
let storageEntry = null;
|
|
1103
|
-
try {
|
|
1104
|
-
await onEntryBeforePublish.publish({
|
|
1105
|
-
entry,
|
|
1106
|
-
model
|
|
1107
|
-
});
|
|
1108
|
-
storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
1109
|
-
const result = await storageOperations.entries.publish(model, {
|
|
1110
|
-
entry,
|
|
1111
|
-
storageEntry
|
|
1112
|
-
});
|
|
1113
|
-
await onEntryAfterPublish.publish({
|
|
1114
|
-
entry,
|
|
1115
|
-
storageEntry: result,
|
|
1116
|
-
model
|
|
1117
|
-
});
|
|
1118
|
-
return result;
|
|
1119
|
-
} catch (ex) {
|
|
1120
|
-
await onEntryPublishError.publish({
|
|
1121
|
-
entry,
|
|
1122
|
-
model,
|
|
1123
|
-
error: ex
|
|
1124
|
-
});
|
|
1125
|
-
throw new _error.default(ex.message || "Could not publish entry.", ex.code || "PUBLISH_ERROR", {
|
|
1126
|
-
error: ex,
|
|
1127
|
-
entry,
|
|
1128
|
-
storageEntry,
|
|
1129
|
-
originalEntry,
|
|
1130
|
-
originalStorageEntry
|
|
1131
|
-
});
|
|
1132
|
-
}
|
|
1133
1354
|
},
|
|
1134
|
-
async
|
|
1135
|
-
|
|
1136
|
-
|
|
1355
|
+
async deleteMultipleEntries(model, ids) {
|
|
1356
|
+
return context.benchmark.measure("headlessCms.crud.entries.deleteMultipleEntries", async () => {
|
|
1357
|
+
return deleteMultipleEntries(model, ids);
|
|
1137
1358
|
});
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1359
|
+
},
|
|
1360
|
+
async publishEntry(model, id) {
|
|
1361
|
+
return context.benchmark.measure("headlessCms.crud.entries.publishEntry", async () => {
|
|
1362
|
+
return publishEntry(model, id);
|
|
1141
1363
|
});
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
id: entryId
|
|
1364
|
+
},
|
|
1365
|
+
async unpublishEntry(model, id) {
|
|
1366
|
+
return context.benchmark.measure("headlessCms.crud.entries.unpublishEntry", async () => {
|
|
1367
|
+
return unpublishEntry(model, id);
|
|
1147
1368
|
});
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
throw new _error.default(`Entry is not published.`, "UNPUBLISH_ERROR", {
|
|
1153
|
-
entry: originalStorageEntry
|
|
1154
|
-
});
|
|
1155
|
-
}
|
|
1156
|
-
(0, _ownership.checkOwnership)(context, permission, originalStorageEntry);
|
|
1157
|
-
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
1158
|
-
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
1159
|
-
status: STATUS_UNPUBLISHED
|
|
1369
|
+
},
|
|
1370
|
+
async getUniqueFieldValues(model, params) {
|
|
1371
|
+
return context.benchmark.measure("headlessCms.crud.entries.getUniqueFieldValues", async () => {
|
|
1372
|
+
return getUniqueFieldValues(model, params);
|
|
1160
1373
|
});
|
|
1161
|
-
let storageEntry = null;
|
|
1162
|
-
try {
|
|
1163
|
-
await onEntryBeforeUnpublish.publish({
|
|
1164
|
-
entry,
|
|
1165
|
-
model
|
|
1166
|
-
});
|
|
1167
|
-
storageEntry = await (0, _entryStorage.entryToStorageTransform)(context, model, entry);
|
|
1168
|
-
const result = await storageOperations.entries.unpublish(model, {
|
|
1169
|
-
entry,
|
|
1170
|
-
storageEntry
|
|
1171
|
-
});
|
|
1172
|
-
await onEntryAfterUnpublish.publish({
|
|
1173
|
-
entry,
|
|
1174
|
-
storageEntry: result,
|
|
1175
|
-
model
|
|
1176
|
-
});
|
|
1177
|
-
return result;
|
|
1178
|
-
} catch (ex) {
|
|
1179
|
-
await onEntryUnpublishError.publish({
|
|
1180
|
-
entry,
|
|
1181
|
-
model,
|
|
1182
|
-
error: ex
|
|
1183
|
-
});
|
|
1184
|
-
throw new _error.default(ex.message || "Could not unpublish entry.", ex.code || "UNPUBLISH_ERROR", {
|
|
1185
|
-
originalEntry,
|
|
1186
|
-
originalStorageEntry,
|
|
1187
|
-
entry,
|
|
1188
|
-
storageEntry
|
|
1189
|
-
});
|
|
1190
|
-
}
|
|
1191
1374
|
}
|
|
1192
1375
|
};
|
|
1193
1376
|
};
|