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