@webiny/api-headless-cms 0.0.0-unstable.9e825fd5fb → 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 (135) hide show
  1. package/context.js +4 -3
  2. package/context.js.map +1 -1
  3. package/crud/contentEntry/referenceFieldsMapping.js +34 -5
  4. package/crud/contentEntry/referenceFieldsMapping.js.map +1 -1
  5. package/crud/contentEntry.crud.d.ts +4 -4
  6. package/crud/contentEntry.crud.js +207 -106
  7. package/crud/contentEntry.crud.js.map +1 -1
  8. package/crud/contentModel/beforeDelete.d.ts +1 -1
  9. package/crud/contentModel/beforeDelete.js +1 -5
  10. package/crud/contentModel/beforeDelete.js.map +1 -1
  11. package/crud/contentModel/validation.d.ts +48 -16
  12. package/crud/contentModel/validation.js +2 -2
  13. package/crud/contentModel/validation.js.map +1 -1
  14. package/crud/contentModelGroup.crud.js +1 -7
  15. package/crud/contentModelGroup.crud.js.map +1 -1
  16. package/graphql/checkEndpointAccess.d.ts +2 -0
  17. package/graphql/checkEndpointAccess.js +18 -0
  18. package/graphql/checkEndpointAccess.js.map +1 -0
  19. package/graphql/createRequestBody.d.ts +2 -0
  20. package/graphql/createRequestBody.js +14 -0
  21. package/graphql/createRequestBody.js.map +1 -0
  22. package/graphql/formatErrorPayload.d.ts +1 -0
  23. package/graphql/formatErrorPayload.js +25 -0
  24. package/graphql/formatErrorPayload.js.map +1 -0
  25. package/graphql/generateSchema.js.map +1 -1
  26. package/graphql/getSchema.d.ts +17 -0
  27. package/graphql/getSchema.js +102 -0
  28. package/graphql/getSchema.js.map +1 -0
  29. package/graphql/graphQLHandlerFactory.js +5 -190
  30. package/graphql/graphQLHandlerFactory.js.map +1 -1
  31. package/graphql/handleRequest.d.ts +11 -0
  32. package/graphql/handleRequest.js +81 -0
  33. package/graphql/handleRequest.js.map +1 -0
  34. package/graphql/schema/baseSchema.js +15 -0
  35. package/graphql/schema/baseSchema.js.map +1 -1
  36. package/graphql/schema/createFieldResolvers.d.ts +1 -1
  37. package/graphql/schema/createFieldResolvers.js +6 -12
  38. package/graphql/schema/createFieldResolvers.js.map +1 -1
  39. package/graphql/schema/createFieldTypePluginRecords.d.ts +3 -0
  40. package/graphql/schema/createFieldTypePluginRecords.js +13 -0
  41. package/graphql/schema/createFieldTypePluginRecords.js.map +1 -0
  42. package/graphql/schema/createManageResolvers.js +4 -0
  43. package/graphql/schema/createManageResolvers.js.map +1 -1
  44. package/graphql/schema/createManageSDL.js +34 -26
  45. package/graphql/schema/createManageSDL.js.map +1 -1
  46. package/graphql/schema/createReadSDL.js +22 -19
  47. package/graphql/schema/createReadSDL.js.map +1 -1
  48. package/graphql/schema/resolvers/manage/resolveDelete.d.ts +2 -1
  49. package/graphql/schema/resolvers/manage/resolveDelete.js +13 -3
  50. package/graphql/schema/resolvers/manage/resolveDelete.js.map +1 -1
  51. package/graphql/schema/resolvers/manage/resolveDeleteMultiple.d.ts +7 -0
  52. package/graphql/schema/resolvers/manage/resolveDeleteMultiple.js +20 -0
  53. package/graphql/schema/resolvers/manage/resolveDeleteMultiple.js.map +1 -0
  54. package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.d.ts +4 -0
  55. package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.js +18 -0
  56. package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.js.map +1 -0
  57. package/graphql/schema/schemaPlugins.js +2 -11
  58. package/graphql/schema/schemaPlugins.js.map +1 -1
  59. package/graphqlFields/dynamicZone/dynamicZoneField.d.ts +1 -1
  60. package/graphqlFields/dynamicZone/dynamicZoneField.js +44 -17
  61. package/graphqlFields/dynamicZone/dynamicZoneField.js.map +1 -1
  62. package/graphqlFields/object.js.map +1 -1
  63. package/graphqlFields/ref.js +7 -7
  64. package/graphqlFields/ref.js.map +1 -1
  65. package/index.d.ts +1 -1
  66. package/index.js +13 -9
  67. package/index.js.map +1 -1
  68. package/package.json +35 -35
  69. package/plugins/CmsModelPlugin.d.ts +3 -1
  70. package/plugins/CmsModelPlugin.js +5 -5
  71. package/plugins/CmsModelPlugin.js.map +1 -1
  72. package/plugins/StorageOperationsCmsModelPlugin.d.ts +23 -0
  73. package/plugins/StorageOperationsCmsModelPlugin.js +42 -0
  74. package/plugins/StorageOperationsCmsModelPlugin.js.map +1 -0
  75. package/plugins/index.d.ts +1 -0
  76. package/plugins/index.js +11 -0
  77. package/plugins/index.js.map +1 -1
  78. package/types.d.ts +122 -71
  79. package/types.js +11 -0
  80. package/types.js.map +1 -1
  81. package/utils/converters/valueKeyStorageConverter.d.ts +1 -5
  82. package/utils/converters/valueKeyStorageConverter.js +24 -25
  83. package/utils/converters/valueKeyStorageConverter.js.map +1 -1
  84. package/utils/createTypeFromFields.js +1 -2
  85. package/utils/createTypeFromFields.js.map +1 -1
  86. package/utils/createTypeName.d.ts +0 -2
  87. package/utils/createTypeName.js +2 -10
  88. package/utils/createTypeName.js.map +1 -1
  89. package/utils/getBaseFieldType.d.ts +1 -3
  90. package/utils/getBaseFieldType.js.map +1 -1
  91. package/utils/getEntryDescription.d.ts +1 -1
  92. package/utils/getEntryDescription.js.map +1 -1
  93. package/utils/getEntryImage.d.ts +1 -1
  94. package/utils/getEntryImage.js.map +1 -1
  95. package/utils/getEntryTitle.d.ts +1 -1
  96. package/utils/getEntryTitle.js.map +1 -1
  97. package/utils/renderFields.d.ts +2 -1
  98. package/utils/renderFields.js +2 -1
  99. package/utils/renderFields.js.map +1 -1
  100. package/utils/renderGetFilterFields.d.ts +2 -2
  101. package/utils/renderGetFilterFields.js +7 -20
  102. package/utils/renderGetFilterFields.js.map +1 -1
  103. package/utils/renderInputFields.d.ts +2 -1
  104. package/utils/renderInputFields.js +14 -6
  105. package/utils/renderInputFields.js.map +1 -1
  106. package/utils/renderListFilterFields.d.ts +2 -1
  107. package/utils/renderListFilterFields.js +9 -20
  108. package/utils/renderListFilterFields.js.map +1 -1
  109. package/utils/renderSortEnum.d.ts +2 -1
  110. package/utils/renderSortEnum.js +2 -1
  111. package/utils/renderSortEnum.js.map +1 -1
  112. package/crud/contentModel/createFieldModels.d.ts +0 -2
  113. package/crud/contentModel/createFieldModels.js +0 -26
  114. package/crud/contentModel/createFieldModels.js.map +0 -1
  115. package/crud/contentModel/fieldIdValidation.d.ts +0 -1
  116. package/crud/contentModel/fieldIdValidation.js +0 -25
  117. package/crud/contentModel/fieldIdValidation.js.map +0 -1
  118. package/crud/contentModel/idValidation.d.ts +0 -1
  119. package/crud/contentModel/idValidation.js +0 -22
  120. package/crud/contentModel/idValidation.js.map +0 -1
  121. package/crud/contentModel/models.d.ts +0 -4
  122. package/crud/contentModel/models.js +0 -192
  123. package/crud/contentModel/models.js.map +0 -1
  124. package/crud/contentModel/systemFields.d.ts +0 -1
  125. package/crud/contentModel/systemFields.js +0 -8
  126. package/crud/contentModel/systemFields.js.map +0 -1
  127. package/upgrades/5.33.0/index.d.ts +0 -3
  128. package/upgrades/5.33.0/index.js +0 -182
  129. package/upgrades/5.33.0/index.js.map +0 -1
  130. package/upgrades/index.d.ts +0 -1
  131. package/upgrades/index.js +0 -12
  132. package/upgrades/index.js.map +0 -1
  133. package/utils/pluralizedTypeName.d.ts +0 -1
  134. package/utils/pluralizedTypeName.js +0 -26
  135. package/utils/pluralizedTypeName.js.map +0 -1
@@ -7,32 +7,27 @@ Object.defineProperty(exports, "__esModule", {
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
9
  var _merge = _interopRequireDefault(require("lodash/merge"));
10
- var _mdbid = _interopRequireDefault(require("mdbid"));
10
+ var _utils = require("@webiny/utils");
11
11
  var _error = _interopRequireDefault(require("@webiny/error"));
12
12
  var _handlerGraphql = require("@webiny/handler-graphql");
13
+ var _types = require("../types");
13
14
  var _entryDataValidation = require("./contentEntry/entryDataValidation");
14
15
  var _pubsub = require("@webiny/pubsub");
15
16
  var _beforeCreate = require("./contentEntry/beforeCreate");
16
17
  var _beforeUpdate = require("./contentEntry/beforeUpdate");
17
- var _utils = require("@webiny/utils");
18
18
  var _afterDelete = require("./contentEntry/afterDelete");
19
19
  var _referenceFieldsMapping = require("./contentEntry/referenceFieldsMapping");
20
20
  var _permissions = require("../utils/permissions");
21
21
  var _access = require("../utils/access");
22
22
  var _ownership = require("../utils/ownership");
23
23
  var _entryStorage = require("../utils/entryStorage");
24
- var _valueKeyStorageConverter = require("../utils/converters/valueKeyStorageConverter");
25
24
  var _searchableFields = require("./contentEntry/searchableFields");
26
- /**
27
- * Package mdbid does not have types.
28
- */
29
- // @ts-ignore
30
-
31
- const STATUS_DRAFT = "draft";
25
+ var _filterAsync = require("../utils/filterAsync");
26
+ const STATUS_DRAFT = _types.CONTENT_ENTRY_STATUS.DRAFT;
32
27
  exports.STATUS_DRAFT = STATUS_DRAFT;
33
- const STATUS_PUBLISHED = "published";
28
+ const STATUS_PUBLISHED = _types.CONTENT_ENTRY_STATUS.PUBLISHED;
34
29
  exports.STATUS_PUBLISHED = STATUS_PUBLISHED;
35
- const STATUS_UNPUBLISHED = "unpublished";
30
+ const STATUS_UNPUBLISHED = _types.CONTENT_ENTRY_STATUS.UNPUBLISHED;
36
31
  exports.STATUS_UNPUBLISHED = STATUS_UNPUBLISHED;
37
32
  /**
38
33
  * Used for some fields to convert their values.
@@ -134,7 +129,7 @@ const createEntryMeta = (input, original) => {
134
129
  return (0, _utils.removeUndefinedValues)((0, _utils.removeNullValues)(meta));
135
130
  };
136
131
  const createEntryId = input => {
137
- let entryId = (0, _mdbid.default)();
132
+ let entryId = (0, _utils.mdbid)();
138
133
  if (input.id) {
139
134
  if (input.id.match(/^([a-zA-Z0-9])([a-zA-Z0-9\-]+)([a-zA-Z0-9])$/) === null) {
140
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", {
@@ -184,9 +179,6 @@ const createContentEntryCrud = params => {
184
179
  getTenant,
185
180
  getLocale
186
181
  } = params;
187
- const {
188
- plugins
189
- } = context;
190
182
  const getCreatedBy = () => {
191
183
  const identity = getIdentity();
192
184
  return {
@@ -251,6 +243,12 @@ const createContentEntryCrud = params => {
251
243
  const onEntryRevisionBeforeDelete = (0, _pubsub.createTopic)("cms.onEntryRevisionBeforeDelete");
252
244
  const onEntryRevisionAfterDelete = (0, _pubsub.createTopic)("cms.onEntryRevisionAfterDelete");
253
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");
254
252
 
255
253
  /**
256
254
  * Get entry
@@ -317,30 +315,22 @@ const createContentEntryCrud = params => {
317
315
  /**
318
316
  * A helper to get entries by revision IDs
319
317
  */
320
- const getEntriesByIds = async (initialModel, ids) => {
318
+ const getEntriesByIds = async (model, ids) => {
321
319
  return context.benchmark.measure("headlessCms.crud.entries.getEntriesByIds", async () => {
322
320
  const permission = await checkEntryPermissions({
323
321
  rwd: "r"
324
322
  });
325
- await (0, _access.checkModelAccess)(context, initialModel);
326
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
327
- model: initialModel,
328
- plugins
329
- });
323
+ await (0, _access.checkModelAccess)(context, model);
330
324
  const entries = await storageOperations.entries.getByIds(model, {
331
325
  ids
332
326
  });
333
327
  return entries.filter(entry => (0, _ownership.validateOwnership)(context, permission, entry));
334
328
  });
335
329
  };
336
- const getEntryById = async (initialModel, id) => {
330
+ const getEntryById = async (model, id) => {
337
331
  const where = {
338
332
  id
339
333
  };
340
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
341
- model: initialModel,
342
- plugins
343
- });
344
334
  await onEntryBeforeGet.publish({
345
335
  where,
346
336
  model
@@ -351,42 +341,30 @@ const createContentEntryCrud = params => {
351
341
  }
352
342
  return entry;
353
343
  };
354
- const getPublishedEntriesByIds = async (initialModel, ids) => {
344
+ const getPublishedEntriesByIds = async (model, ids) => {
355
345
  const permission = await checkEntryPermissions({
356
346
  rwd: "r"
357
347
  });
358
- await (0, _access.checkModelAccess)(context, initialModel);
359
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
360
- model: initialModel,
361
- plugins
362
- });
348
+ await (0, _access.checkModelAccess)(context, model);
363
349
  const entries = await storageOperations.entries.getPublishedByIds(model, {
364
350
  ids
365
351
  });
366
352
  return entries.filter(entry => (0, _ownership.validateOwnership)(context, permission, entry));
367
353
  };
368
- const getLatestEntriesByIds = async (initialModel, ids) => {
354
+ const getLatestEntriesByIds = async (model, ids) => {
369
355
  const permission = await checkEntryPermissions({
370
356
  rwd: "r"
371
357
  });
372
- await (0, _access.checkModelAccess)(context, initialModel);
373
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
374
- model: initialModel,
375
- plugins
376
- });
358
+ await (0, _access.checkModelAccess)(context, model);
377
359
  const entries = await storageOperations.entries.getLatestByIds(model, {
378
360
  ids
379
361
  });
380
362
  return entries.filter(entry => (0, _ownership.validateOwnership)(context, permission, entry));
381
363
  };
382
- const getEntry = async (initialModel, params) => {
364
+ const getEntry = async (model, params) => {
383
365
  await checkEntryPermissions({
384
366
  rwd: "r"
385
367
  });
386
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
387
- model: initialModel,
388
- plugins
389
- });
390
368
  const {
391
369
  where,
392
370
  sort
@@ -406,32 +384,21 @@ const createContentEntryCrud = params => {
406
384
  }
407
385
  return item;
408
386
  };
409
- const getEntryRevisions = async (initialModel, entryId) => {
410
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
411
- model: initialModel,
412
- plugins
413
- });
387
+ const getEntryRevisions = async (model, entryId) => {
414
388
  return storageOperations.entries.getRevisions(model, {
415
389
  id: entryId
416
390
  });
417
391
  };
418
- const listEntries = async (initialModel, params) => {
392
+ const listEntries = async (model, params) => {
419
393
  const permission = await checkEntryPermissions({
420
394
  rwd: "r"
421
395
  });
422
- await (0, _access.checkModelAccess)(context, initialModel);
423
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
424
- model: initialModel,
425
- plugins
426
- });
396
+ await (0, _access.checkModelAccess)(context, model);
427
397
  const {
428
398
  where: initialWhere,
429
399
  limit: initialLimit
430
400
  } = params;
431
401
  const limit = initialLimit && initialLimit > 0 ? initialLimit : 50;
432
- /**
433
- * We always assign tenant and locale because we do not allow one model to have content through multiple tenants.
434
- */
435
402
  const where = (0, _objectSpread2.default)({}, initialWhere);
436
403
  /**
437
404
  * Possibly only get records which are owned by current user.
@@ -497,15 +464,11 @@ const createContentEntryCrud = params => {
497
464
  });
498
465
  }
499
466
  };
500
- const createEntry = async (initialModel, inputData) => {
467
+ const createEntry = async (model, inputData) => {
501
468
  await checkEntryPermissions({
502
469
  rwd: "w"
503
470
  });
504
- await (0, _access.checkModelAccess)(context, initialModel);
505
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
506
- model: initialModel,
507
- plugins
508
- });
471
+ await (0, _access.checkModelAccess)(context, model);
509
472
 
510
473
  /**
511
474
  * Make sure we only work with fields that are defined in the model.
@@ -584,15 +547,11 @@ const createContentEntryCrud = params => {
584
547
  });
585
548
  }
586
549
  };
587
- const createEntryRevisionFrom = async (initialModel, sourceId, inputData) => {
550
+ const createEntryRevisionFrom = async (model, sourceId, inputData) => {
588
551
  const permission = await checkEntryPermissions({
589
552
  rwd: "w"
590
553
  });
591
- await (0, _access.checkModelAccess)(context, initialModel);
592
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
593
- model: initialModel,
594
- plugins
595
- });
554
+ await (0, _access.checkModelAccess)(context, model);
596
555
 
597
556
  /**
598
557
  * Make sure we only work with fields that are defined in the model.
@@ -693,15 +652,11 @@ const createContentEntryCrud = params => {
693
652
  });
694
653
  }
695
654
  };
696
- const updateEntry = async (initialModel, id, inputData, metaInput) => {
655
+ const updateEntry = async (model, id, inputData, metaInput) => {
697
656
  const permission = await checkEntryPermissions({
698
657
  rwd: "w"
699
658
  });
700
- await (0, _access.checkModelAccess)(context, initialModel);
701
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
702
- model: initialModel,
703
- plugins
704
- });
659
+ await (0, _access.checkModelAccess)(context, model);
705
660
 
706
661
  /**
707
662
  * Make sure we only work with fields that are defined in the model.
@@ -786,15 +741,11 @@ const createContentEntryCrud = params => {
786
741
  });
787
742
  }
788
743
  };
789
- const republishEntry = async (initialModel, id) => {
744
+ const republishEntry = async (model, id) => {
790
745
  await checkEntryPermissions({
791
746
  rwd: "w"
792
747
  });
793
- await (0, _access.checkModelAccess)(context, initialModel);
794
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
795
- model: initialModel,
796
- plugins
797
- });
748
+ await (0, _access.checkModelAccess)(context, model);
798
749
  /**
799
750
  * Fetch the entry from the storage.
800
751
  */
@@ -868,15 +819,11 @@ const createContentEntryCrud = params => {
868
819
  });
869
820
  }
870
821
  };
871
- const deleteEntryRevision = async (initialModel, revisionId) => {
822
+ const deleteEntryRevision = async (model, revisionId) => {
872
823
  const permission = await checkEntryPermissions({
873
824
  rwd: "d"
874
825
  });
875
- await (0, _access.checkModelAccess)(context, initialModel);
876
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
877
- model: initialModel,
878
- plugins
879
- });
826
+ await (0, _access.checkModelAccess)(context, model);
880
827
  const {
881
828
  id: entryId,
882
829
  version
@@ -946,20 +893,110 @@ const createContentEntryCrud = params => {
946
893
  });
947
894
  }
948
895
  };
949
- const deleteEntry = async (initialModel, entryId) => {
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
+ }
950
914
  const permission = await checkEntryPermissions({
951
915
  rwd: "d"
952
916
  });
953
- await (0, _access.checkModelAccess)(context, initialModel);
954
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
955
- model: initialModel,
956
- plugins
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"
957
968
  });
969
+ await (0, _access.checkModelAccess)(context, model);
970
+ const {
971
+ force
972
+ } = options || {};
958
973
  const storageEntry = await storageOperations.entries.getLatestRevisionByEntryId(model, {
959
- id: entryId
974
+ id
960
975
  });
961
- if (!storageEntry) {
962
- throw new _handlerGraphql.NotFoundError(`Entry "${entryId}" was not found!`);
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
+ });
963
1000
  }
964
1001
  (0, _ownership.checkOwnership)(context, permission, storageEntry);
965
1002
  const entry = await (0, _entryStorage.entryFromStorageTransform)(context, model, storageEntry);
@@ -968,15 +1005,11 @@ const createContentEntryCrud = params => {
968
1005
  entry
969
1006
  });
970
1007
  };
971
- const publishEntry = async (initialModel, id) => {
1008
+ const publishEntry = async (model, id) => {
972
1009
  const permission = await checkEntryPermissions({
973
1010
  pw: "p"
974
1011
  });
975
- await (0, _access.checkModelAccess)(context, initialModel);
976
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
977
- model: initialModel,
978
- plugins
979
- });
1012
+ await (0, _access.checkModelAccess)(context, model);
980
1013
  const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
981
1014
  id
982
1015
  });
@@ -1024,14 +1057,10 @@ const createContentEntryCrud = params => {
1024
1057
  });
1025
1058
  }
1026
1059
  };
1027
- const unpublishEntry = async (initialModel, id) => {
1060
+ const unpublishEntry = async (model, id) => {
1028
1061
  const permission = await checkEntryPermissions({
1029
1062
  pw: "u"
1030
1063
  });
1031
- const model = (0, _valueKeyStorageConverter.attachCmsModelFieldConverters)({
1032
- model: initialModel,
1033
- plugins
1034
- });
1035
1064
  const {
1036
1065
  id: entryId
1037
1066
  } = (0, _utils.parseIdentifier)(id);
@@ -1082,6 +1111,68 @@ const createContentEntryCrud = params => {
1082
1111
  });
1083
1112
  }
1084
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
+ };
1085
1176
  return {
1086
1177
  /**
1087
1178
  * Deprecated - will be removed in 5.35.0
@@ -1261,6 +1352,11 @@ const createContentEntryCrud = params => {
1261
1352
  return deleteEntry(model, entryId);
1262
1353
  });
1263
1354
  },
1355
+ async deleteMultipleEntries(model, ids) {
1356
+ return context.benchmark.measure("headlessCms.crud.entries.deleteMultipleEntries", async () => {
1357
+ return deleteMultipleEntries(model, ids);
1358
+ });
1359
+ },
1264
1360
  async publishEntry(model, id) {
1265
1361
  return context.benchmark.measure("headlessCms.crud.entries.publishEntry", async () => {
1266
1362
  return publishEntry(model, id);
@@ -1270,6 +1366,11 @@ const createContentEntryCrud = params => {
1270
1366
  return context.benchmark.measure("headlessCms.crud.entries.unpublishEntry", async () => {
1271
1367
  return unpublishEntry(model, id);
1272
1368
  });
1369
+ },
1370
+ async getUniqueFieldValues(model, params) {
1371
+ return context.benchmark.measure("headlessCms.crud.entries.getUniqueFieldValues", async () => {
1372
+ return getUniqueFieldValues(model, params);
1373
+ });
1273
1374
  }
1274
1375
  };
1275
1376
  };