@webiny/api-headless-cms 0.0.0-unstable.990c3ab1b6 → 0.0.0-unstable.aa00eecd97

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