@webiny/api-headless-cms 0.0.0-unstable.c2780f51fe → 0.0.0-unstable.c7dec08bb0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/constants.d.ts +1 -0
- package/constants.js +8 -0
- package/constants.js.map +1 -0
- package/context.js +37 -5
- package/context.js.map +1 -1
- package/crud/contentEntry/referenceFieldsMapping.js +34 -5
- package/crud/contentEntry/referenceFieldsMapping.js.map +1 -1
- package/crud/contentEntry.crud.d.ts +8 -4
- package/crud/contentEntry.crud.js +329 -64
- package/crud/contentEntry.crud.js.map +1 -1
- package/crud/contentModel/validateModelFields.js +1 -1
- package/crud/contentModel/validateModelFields.js.map +1 -1
- package/crud/contentModel/validation.d.ts +76 -76
- package/crud/contentModel.crud.d.ts +2 -0
- package/crud/contentModel.crud.js +22 -12
- package/crud/contentModel.crud.js.map +1 -1
- package/crud/contentModelGroup/validation.d.ts +4 -4
- package/crud/contentModelGroup.crud.d.ts +2 -0
- package/crud/contentModelGroup.crud.js +42 -27
- package/crud/contentModelGroup.crud.js.map +1 -1
- package/crud/settings.crud.d.ts +2 -0
- package/crud/settings.crud.js +2 -6
- package/crud/settings.crud.js.map +1 -1
- package/graphql/getSchema.js +1 -1
- package/graphql/getSchema.js.map +1 -1
- package/graphql/index.d.ts +1 -1
- package/graphql/schema/baseSchema.js +31 -0
- package/graphql/schema/baseSchema.js.map +1 -1
- package/graphql/schema/contentEntries.js +6 -1
- package/graphql/schema/contentEntries.js.map +1 -1
- package/graphql/schema/createFieldResolvers.d.ts +1 -1
- package/graphql/schema/createFieldResolvers.js +6 -12
- package/graphql/schema/createFieldResolvers.js.map +1 -1
- package/graphql/schema/createFieldTypePluginRecords.d.ts +3 -0
- package/graphql/schema/createFieldTypePluginRecords.js +13 -0
- package/graphql/schema/createFieldTypePluginRecords.js.map +1 -0
- package/graphql/schema/createManageResolvers.d.ts +1 -1
- package/graphql/schema/createManageResolvers.js +14 -0
- package/graphql/schema/createManageResolvers.js.map +1 -1
- package/graphql/schema/createManageSDL.js +51 -28
- package/graphql/schema/createManageSDL.js.map +1 -1
- package/graphql/schema/createReadSDL.js +23 -19
- package/graphql/schema/createReadSDL.js.map +1 -1
- package/graphql/schema/resolvers/manage/resolveDelete.d.ts +2 -1
- package/graphql/schema/resolvers/manage/resolveDelete.js +13 -3
- package/graphql/schema/resolvers/manage/resolveDelete.js.map +1 -1
- package/graphql/schema/resolvers/manage/resolveDeleteMultiple.d.ts +7 -0
- package/graphql/schema/resolvers/manage/resolveDeleteMultiple.js +20 -0
- package/graphql/schema/resolvers/manage/resolveDeleteMultiple.js.map +1 -0
- package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.d.ts +4 -0
- package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.js +18 -0
- package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.js.map +1 -0
- package/graphql/schema/resolvers/manage/resolveMove.d.ts +8 -0
- package/graphql/schema/resolvers/manage/resolveMove.js +30 -0
- package/graphql/schema/resolvers/manage/resolveMove.js.map +1 -0
- package/graphql/schema/schemaPlugins.js +2 -11
- package/graphql/schema/schemaPlugins.js.map +1 -1
- package/graphql/system.d.ts +2 -5
- package/graphql/system.js +1 -11
- package/graphql/system.js.map +1 -1
- package/graphqlFields/dynamicZone/dynamicZoneField.js +43 -28
- package/graphqlFields/dynamicZone/dynamicZoneField.js.map +1 -1
- package/graphqlFields/number.js +1 -0
- package/graphqlFields/number.js.map +1 -1
- package/graphqlFields/object.js +2 -2
- package/graphqlFields/object.js.map +1 -1
- package/graphqlFields/text.js +2 -0
- package/graphqlFields/text.js.map +1 -1
- package/index.d.ts +1 -1
- package/package.json +31 -35
- package/plugins/CmsModelPlugin.d.ts +3 -1
- package/plugins/CmsModelPlugin.js.map +1 -1
- package/types.d.ts +101 -17
- package/types.js +11 -0
- package/types.js.map +1 -1
- package/utils/converters/valueKeyStorageConverter.js +5 -2
- package/utils/converters/valueKeyStorageConverter.js.map +1 -1
- package/utils/createTypeFromFields.js +1 -1
- package/utils/createTypeFromFields.js.map +1 -1
- package/utils/getBaseFieldType.d.ts +1 -3
- package/utils/getBaseFieldType.js.map +1 -1
- package/utils/getEntryDescription.d.ts +1 -1
- package/utils/getEntryDescription.js.map +1 -1
- package/utils/getEntryImage.d.ts +1 -1
- package/utils/getEntryImage.js.map +1 -1
- package/utils/getEntryTitle.d.ts +1 -1
- package/utils/getEntryTitle.js.map +1 -1
- package/utils/permissions/EntriesPermissions.d.ts +4 -0
- package/utils/permissions/EntriesPermissions.js +9 -0
- package/utils/permissions/EntriesPermissions.js.map +1 -0
- package/utils/permissions/ModelGroupsPermissions.d.ts +11 -0
- package/utils/permissions/ModelGroupsPermissions.js +48 -0
- package/utils/permissions/ModelGroupsPermissions.js.map +1 -0
- package/utils/permissions/ModelsPermissions.d.ts +20 -0
- package/utils/permissions/ModelsPermissions.js +91 -0
- package/utils/permissions/ModelsPermissions.js.map +1 -0
- package/utils/permissions/SettingsPermissions.d.ts +4 -0
- package/utils/permissions/SettingsPermissions.js +9 -0
- package/utils/permissions/SettingsPermissions.js.map +1 -0
- package/utils/renderFields.d.ts +2 -1
- package/utils/renderFields.js +2 -1
- package/utils/renderFields.js.map +1 -1
- package/utils/renderGetFilterFields.d.ts +2 -2
- package/utils/renderGetFilterFields.js +7 -20
- package/utils/renderGetFilterFields.js.map +1 -1
- package/utils/renderInputFields.d.ts +2 -1
- package/utils/renderInputFields.js +14 -6
- package/utils/renderInputFields.js.map +1 -1
- package/utils/renderListFilterFields.d.ts +3 -1
- package/utils/renderListFilterFields.js +16 -21
- package/utils/renderListFilterFields.js.map +1 -1
- package/utils/renderSortEnum.d.ts +3 -2
- package/utils/renderSortEnum.js +5 -1
- package/utils/renderSortEnum.js.map +1 -1
- package/crud/contentModel/createFieldModels.d.ts +0 -2
- package/crud/contentModel/createFieldModels.js +0 -26
- package/crud/contentModel/createFieldModels.js.map +0 -1
- package/crud/contentModel/fieldIdValidation.d.ts +0 -1
- package/crud/contentModel/fieldIdValidation.js +0 -25
- package/crud/contentModel/fieldIdValidation.js.map +0 -1
- package/crud/contentModel/idValidation.d.ts +0 -1
- package/crud/contentModel/idValidation.js +0 -22
- package/crud/contentModel/idValidation.js.map +0 -1
- package/crud/contentModel/models.d.ts +0 -4
- package/crud/contentModel/models.js +0 -192
- package/crud/contentModel/models.js.map +0 -1
- package/crud/contentModel/systemFields.d.ts +0 -1
- package/crud/contentModel/systemFields.js +0 -8
- package/crud/contentModel/systemFields.js.map +0 -1
- package/upgrades/5.33.0/index.d.ts +0 -3
- package/upgrades/5.33.0/index.js +0 -182
- package/upgrades/5.33.0/index.js.map +0 -1
- package/upgrades/index.d.ts +0 -1
- package/upgrades/index.js +0 -12
- package/upgrades/index.js.map +0 -1
- package/utils/access.d.ts +0 -8
- package/utils/access.js +0 -76
- package/utils/access.js.map +0 -1
- package/utils/ownership.d.ts +0 -8
- package/utils/ownership.js +0 -33
- package/utils/ownership.js.map +0 -1
- package/utils/permissions.d.ts +0 -7
- package/utils/permissions.js +0 -91
- package/utils/permissions.js.map +0 -1
- package/utils/pluralizedTypeName.d.ts +0 -1
- package/utils/pluralizedTypeName.js +0 -26
- package/utils/pluralizedTypeName.js.map +0 -1
|
@@ -7,31 +7,26 @@ 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
|
|
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
|
-
var _permissions = require("../utils/permissions");
|
|
21
|
-
var _access = require("../utils/access");
|
|
22
|
-
var _ownership = require("../utils/ownership");
|
|
23
20
|
var _entryStorage = require("../utils/entryStorage");
|
|
24
21
|
var _searchableFields = require("./contentEntry/searchableFields");
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const STATUS_DRAFT = "draft";
|
|
22
|
+
var _filterAsync = require("../utils/filterAsync");
|
|
23
|
+
var _apiSecurity = require("@webiny/api-security/");
|
|
24
|
+
var _constants = require("../constants");
|
|
25
|
+
const STATUS_DRAFT = _types.CONTENT_ENTRY_STATUS.DRAFT;
|
|
31
26
|
exports.STATUS_DRAFT = STATUS_DRAFT;
|
|
32
|
-
const STATUS_PUBLISHED =
|
|
27
|
+
const STATUS_PUBLISHED = _types.CONTENT_ENTRY_STATUS.PUBLISHED;
|
|
33
28
|
exports.STATUS_PUBLISHED = STATUS_PUBLISHED;
|
|
34
|
-
const STATUS_UNPUBLISHED =
|
|
29
|
+
const STATUS_UNPUBLISHED = _types.CONTENT_ENTRY_STATUS.UNPUBLISHED;
|
|
35
30
|
exports.STATUS_UNPUBLISHED = STATUS_UNPUBLISHED;
|
|
36
31
|
/**
|
|
37
32
|
* Used for some fields to convert their values.
|
|
@@ -133,7 +128,7 @@ const createEntryMeta = (input, original) => {
|
|
|
133
128
|
return (0, _utils.removeUndefinedValues)((0, _utils.removeNullValues)(meta));
|
|
134
129
|
};
|
|
135
130
|
const createEntryId = input => {
|
|
136
|
-
let entryId = (0,
|
|
131
|
+
let entryId = (0, _utils.mdbid)();
|
|
137
132
|
if (input.id) {
|
|
138
133
|
if (input.id.match(/^([a-zA-Z0-9])([a-zA-Z0-9\-]+)([a-zA-Z0-9])$/) === null) {
|
|
139
134
|
throw new _error.default("The provided ID is not valid. It must be a string which can be A-Z, a-z, 0-9, - and it cannot start or end with a -.", "INVALID_ID", {
|
|
@@ -175,9 +170,19 @@ const allowedEntryStatus = ["draft", "published", "unpublished"];
|
|
|
175
170
|
const transformEntryStatus = status => {
|
|
176
171
|
return allowedEntryStatus.includes(status) ? status : "draft";
|
|
177
172
|
};
|
|
173
|
+
const createSort = sort => {
|
|
174
|
+
if (!Array.isArray(sort)) {
|
|
175
|
+
return ["createdOn_DESC"];
|
|
176
|
+
} else if (sort.filter(s => !!s).length === 0) {
|
|
177
|
+
return ["createdOn_DESC"];
|
|
178
|
+
}
|
|
179
|
+
return sort;
|
|
180
|
+
};
|
|
178
181
|
const createContentEntryCrud = params => {
|
|
179
182
|
const {
|
|
180
183
|
storageOperations,
|
|
184
|
+
entriesPermissions,
|
|
185
|
+
modelsPermissions,
|
|
181
186
|
context,
|
|
182
187
|
getIdentity,
|
|
183
188
|
getTenant,
|
|
@@ -247,6 +252,12 @@ const createContentEntryCrud = params => {
|
|
|
247
252
|
const onEntryRevisionBeforeDelete = (0, _pubsub.createTopic)("cms.onEntryRevisionBeforeDelete");
|
|
248
253
|
const onEntryRevisionAfterDelete = (0, _pubsub.createTopic)("cms.onEntryRevisionAfterDelete");
|
|
249
254
|
const onEntryRevisionDeleteError = (0, _pubsub.createTopic)("cms.onEntryRevisionDeleteError");
|
|
255
|
+
/**
|
|
256
|
+
* Delete multiple entries
|
|
257
|
+
*/
|
|
258
|
+
const onEntryBeforeDeleteMultiple = (0, _pubsub.createTopic)("cms.onEntryBeforeDeleteMultiple");
|
|
259
|
+
const onEntryAfterDeleteMultiple = (0, _pubsub.createTopic)("cms.onEntryAfterDeleteMultiple");
|
|
260
|
+
const onEntryDeleteMultipleError = (0, _pubsub.createTopic)("cms.onEntryDeleteMultipleError");
|
|
250
261
|
|
|
251
262
|
/**
|
|
252
263
|
* Get entry
|
|
@@ -273,9 +284,6 @@ const createContentEntryCrud = params => {
|
|
|
273
284
|
context,
|
|
274
285
|
onEntryAfterDelete
|
|
275
286
|
});
|
|
276
|
-
const checkEntryPermissions = check => {
|
|
277
|
-
return (0, _permissions.checkPermissions)(context, "cms.contentEntry", check);
|
|
278
|
-
};
|
|
279
287
|
|
|
280
288
|
/**
|
|
281
289
|
* A helper to delete the entire entry.
|
|
@@ -315,14 +323,23 @@ const createContentEntryCrud = params => {
|
|
|
315
323
|
*/
|
|
316
324
|
const getEntriesByIds = async (model, ids) => {
|
|
317
325
|
return context.benchmark.measure("headlessCms.crud.entries.getEntriesByIds", async () => {
|
|
318
|
-
|
|
326
|
+
await entriesPermissions.ensure({
|
|
319
327
|
rwd: "r"
|
|
320
328
|
});
|
|
321
|
-
await
|
|
329
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
330
|
+
model,
|
|
331
|
+
locale: getLocale().code
|
|
332
|
+
});
|
|
322
333
|
const entries = await storageOperations.entries.getByIds(model, {
|
|
323
334
|
ids
|
|
324
335
|
});
|
|
325
|
-
return
|
|
336
|
+
return (0, _filterAsync.filterAsync)(entries, async entry => {
|
|
337
|
+
return entriesPermissions.ensure({
|
|
338
|
+
owns: entry.createdBy
|
|
339
|
+
}, {
|
|
340
|
+
throw: false
|
|
341
|
+
});
|
|
342
|
+
});
|
|
326
343
|
});
|
|
327
344
|
};
|
|
328
345
|
const getEntryById = async (model, id) => {
|
|
@@ -340,27 +357,45 @@ const createContentEntryCrud = params => {
|
|
|
340
357
|
return entry;
|
|
341
358
|
};
|
|
342
359
|
const getPublishedEntriesByIds = async (model, ids) => {
|
|
343
|
-
|
|
360
|
+
await entriesPermissions.ensure({
|
|
344
361
|
rwd: "r"
|
|
345
362
|
});
|
|
346
|
-
await
|
|
363
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
364
|
+
model,
|
|
365
|
+
locale: getLocale().code
|
|
366
|
+
});
|
|
347
367
|
const entries = await storageOperations.entries.getPublishedByIds(model, {
|
|
348
368
|
ids
|
|
349
369
|
});
|
|
350
|
-
return
|
|
370
|
+
return (0, _filterAsync.filterAsync)(entries, async entry => {
|
|
371
|
+
return entriesPermissions.ensure({
|
|
372
|
+
owns: entry.createdBy
|
|
373
|
+
}, {
|
|
374
|
+
throw: false
|
|
375
|
+
});
|
|
376
|
+
});
|
|
351
377
|
};
|
|
352
378
|
const getLatestEntriesByIds = async (model, ids) => {
|
|
353
|
-
|
|
379
|
+
await entriesPermissions.ensure({
|
|
354
380
|
rwd: "r"
|
|
355
381
|
});
|
|
356
|
-
await
|
|
382
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
383
|
+
model,
|
|
384
|
+
locale: getLocale().code
|
|
385
|
+
});
|
|
357
386
|
const entries = await storageOperations.entries.getLatestByIds(model, {
|
|
358
387
|
ids
|
|
359
388
|
});
|
|
360
|
-
return
|
|
389
|
+
return (0, _filterAsync.filterAsync)(entries, async entry => {
|
|
390
|
+
return entriesPermissions.ensure({
|
|
391
|
+
owns: entry.createdBy
|
|
392
|
+
}, {
|
|
393
|
+
throw: false
|
|
394
|
+
});
|
|
395
|
+
});
|
|
361
396
|
};
|
|
362
397
|
const getEntry = async (model, params) => {
|
|
363
|
-
await
|
|
398
|
+
await entriesPermissions.ensure({
|
|
364
399
|
rwd: "r"
|
|
365
400
|
});
|
|
366
401
|
const {
|
|
@@ -388,27 +423,35 @@ const createContentEntryCrud = params => {
|
|
|
388
423
|
});
|
|
389
424
|
};
|
|
390
425
|
const listEntries = async (model, params) => {
|
|
391
|
-
|
|
392
|
-
|
|
426
|
+
try {
|
|
427
|
+
await entriesPermissions.ensure({
|
|
428
|
+
rwd: "r"
|
|
429
|
+
});
|
|
430
|
+
} catch {
|
|
431
|
+
throw new _apiSecurity.NotAuthorizedError({
|
|
432
|
+
data: {
|
|
433
|
+
reason: 'Not allowed to perform "read" on "cms.contentEntry".'
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
438
|
+
model,
|
|
439
|
+
locale: getLocale().code
|
|
393
440
|
});
|
|
394
|
-
await (0, _access.checkModelAccess)(context, model);
|
|
395
441
|
const {
|
|
396
442
|
where: initialWhere,
|
|
397
443
|
limit: initialLimit
|
|
398
444
|
} = params;
|
|
399
445
|
const limit = initialLimit && initialLimit > 0 ? initialLimit : 50;
|
|
400
|
-
/**
|
|
401
|
-
* We always assign tenant and locale because we do not allow one model to have content through multiple tenants.
|
|
402
|
-
*/
|
|
403
446
|
const where = (0, _objectSpread2.default)({}, initialWhere);
|
|
404
447
|
/**
|
|
405
448
|
* Possibly only get records which are owned by current user.
|
|
406
449
|
* Or if searching for the owner set that value - in the case that user can see other entries than their own.
|
|
407
450
|
*/
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
where.ownedBy = ownedBy;
|
|
451
|
+
if (await entriesPermissions.canAccessOnlyOwnRecords()) {
|
|
452
|
+
where.ownedBy = getIdentity().id;
|
|
411
453
|
}
|
|
454
|
+
|
|
412
455
|
/**
|
|
413
456
|
* Where must contain either latest or published keys.
|
|
414
457
|
* We cannot list entries without one of those
|
|
@@ -438,6 +481,7 @@ const createContentEntryCrud = params => {
|
|
|
438
481
|
cursor,
|
|
439
482
|
items
|
|
440
483
|
} = await storageOperations.entries.list(model, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, params), {}, {
|
|
484
|
+
sort: createSort(params.sort),
|
|
441
485
|
limit,
|
|
442
486
|
where,
|
|
443
487
|
fields
|
|
@@ -466,10 +510,14 @@ const createContentEntryCrud = params => {
|
|
|
466
510
|
}
|
|
467
511
|
};
|
|
468
512
|
const createEntry = async (model, inputData) => {
|
|
469
|
-
|
|
513
|
+
var _inputData$wbyAco_loc;
|
|
514
|
+
await entriesPermissions.ensure({
|
|
470
515
|
rwd: "w"
|
|
471
516
|
});
|
|
472
|
-
await
|
|
517
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
518
|
+
model,
|
|
519
|
+
locale: getLocale().code
|
|
520
|
+
});
|
|
473
521
|
|
|
474
522
|
/**
|
|
475
523
|
* Make sure we only work with fields that are defined in the model.
|
|
@@ -512,7 +560,10 @@ const createContentEntryCrud = params => {
|
|
|
512
560
|
version,
|
|
513
561
|
locked: false,
|
|
514
562
|
status: STATUS_DRAFT,
|
|
515
|
-
values: input
|
|
563
|
+
values: input,
|
|
564
|
+
location: {
|
|
565
|
+
folderId: ((_inputData$wbyAco_loc = inputData.wbyAco_location) === null || _inputData$wbyAco_loc === void 0 ? void 0 : _inputData$wbyAco_loc.folderId) || _constants.ROOT_FOLDER
|
|
566
|
+
}
|
|
516
567
|
};
|
|
517
568
|
let storageEntry = null;
|
|
518
569
|
try {
|
|
@@ -549,10 +600,13 @@ const createContentEntryCrud = params => {
|
|
|
549
600
|
}
|
|
550
601
|
};
|
|
551
602
|
const createEntryRevisionFrom = async (model, sourceId, inputData) => {
|
|
552
|
-
|
|
603
|
+
await entriesPermissions.ensure({
|
|
553
604
|
rwd: "w"
|
|
554
605
|
});
|
|
555
|
-
await
|
|
606
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
607
|
+
model,
|
|
608
|
+
locale: getLocale().code
|
|
609
|
+
});
|
|
556
610
|
|
|
557
611
|
/**
|
|
558
612
|
* Make sure we only work with fields that are defined in the model.
|
|
@@ -592,7 +646,9 @@ const createContentEntryCrud = params => {
|
|
|
592
646
|
input: initialValues,
|
|
593
647
|
validateEntries: false
|
|
594
648
|
});
|
|
595
|
-
|
|
649
|
+
await entriesPermissions.ensure({
|
|
650
|
+
owns: originalEntry.createdBy
|
|
651
|
+
});
|
|
596
652
|
const identity = getIdentity();
|
|
597
653
|
const latestId = latestStorageEntry ? latestStorageEntry.id : sourceId;
|
|
598
654
|
const {
|
|
@@ -654,10 +710,14 @@ const createContentEntryCrud = params => {
|
|
|
654
710
|
}
|
|
655
711
|
};
|
|
656
712
|
const updateEntry = async (model, id, inputData, metaInput) => {
|
|
657
|
-
|
|
713
|
+
var _inputData$wbyAco_loc2;
|
|
714
|
+
await entriesPermissions.ensure({
|
|
658
715
|
rwd: "w"
|
|
659
716
|
});
|
|
660
|
-
await
|
|
717
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
718
|
+
model,
|
|
719
|
+
locale: getLocale().code
|
|
720
|
+
});
|
|
661
721
|
|
|
662
722
|
/**
|
|
663
723
|
* Make sure we only work with fields that are defined in the model.
|
|
@@ -683,7 +743,9 @@ const createContentEntryCrud = params => {
|
|
|
683
743
|
data: input,
|
|
684
744
|
entry: originalEntry
|
|
685
745
|
});
|
|
686
|
-
|
|
746
|
+
await entriesPermissions.ensure({
|
|
747
|
+
owns: originalEntry.createdBy
|
|
748
|
+
});
|
|
687
749
|
const initialValues = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry.values), input);
|
|
688
750
|
const values = await (0, _referenceFieldsMapping.referenceFieldsMapping)({
|
|
689
751
|
context,
|
|
@@ -705,6 +767,12 @@ const createContentEntryCrud = params => {
|
|
|
705
767
|
meta,
|
|
706
768
|
status: transformEntryStatus(originalEntry.status)
|
|
707
769
|
});
|
|
770
|
+
const folderId = (_inputData$wbyAco_loc2 = inputData.wbyAco_location) === null || _inputData$wbyAco_loc2 === void 0 ? void 0 : _inputData$wbyAco_loc2.folderId;
|
|
771
|
+
if (folderId) {
|
|
772
|
+
entry.location = {
|
|
773
|
+
folderId
|
|
774
|
+
};
|
|
775
|
+
}
|
|
708
776
|
let storageEntry = null;
|
|
709
777
|
try {
|
|
710
778
|
await onEntryBeforeUpdate.publish({
|
|
@@ -743,10 +811,14 @@ const createContentEntryCrud = params => {
|
|
|
743
811
|
}
|
|
744
812
|
};
|
|
745
813
|
const republishEntry = async (model, id) => {
|
|
746
|
-
await
|
|
814
|
+
await entriesPermissions.ensure({
|
|
747
815
|
rwd: "w"
|
|
748
816
|
});
|
|
749
|
-
await
|
|
817
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
818
|
+
model,
|
|
819
|
+
locale: getLocale().code
|
|
820
|
+
});
|
|
821
|
+
|
|
750
822
|
/**
|
|
751
823
|
* Fetch the entry from the storage.
|
|
752
824
|
*/
|
|
@@ -821,10 +893,13 @@ const createContentEntryCrud = params => {
|
|
|
821
893
|
}
|
|
822
894
|
};
|
|
823
895
|
const deleteEntryRevision = async (model, revisionId) => {
|
|
824
|
-
|
|
896
|
+
await entriesPermissions.ensure({
|
|
825
897
|
rwd: "d"
|
|
826
898
|
});
|
|
827
|
-
await
|
|
899
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
900
|
+
model,
|
|
901
|
+
locale: getLocale().code
|
|
902
|
+
});
|
|
828
903
|
const {
|
|
829
904
|
id: entryId,
|
|
830
905
|
version
|
|
@@ -842,7 +917,9 @@ const createContentEntryCrud = params => {
|
|
|
842
917
|
if (!storageEntryToDelete) {
|
|
843
918
|
throw new _handlerGraphql.NotFoundError(`Entry "${revisionId}" was not found!`);
|
|
844
919
|
}
|
|
845
|
-
|
|
920
|
+
await entriesPermissions.ensure({
|
|
921
|
+
owns: storageEntryToDelete.createdBy
|
|
922
|
+
});
|
|
846
923
|
const latestEntryRevisionId = latestStorageEntry ? latestStorageEntry.id : null;
|
|
847
924
|
const entryToDelete = await (0, _entryStorage.entryFromStorageTransform)(context, model, storageEntryToDelete);
|
|
848
925
|
/**
|
|
@@ -894,18 +971,124 @@ const createContentEntryCrud = params => {
|
|
|
894
971
|
});
|
|
895
972
|
}
|
|
896
973
|
};
|
|
897
|
-
const
|
|
898
|
-
const
|
|
974
|
+
const deleteMultipleEntries = async (model, params) => {
|
|
975
|
+
const {
|
|
976
|
+
entries: input
|
|
977
|
+
} = params;
|
|
978
|
+
const maxDeletableEntries = 50;
|
|
979
|
+
const entryIdList = new Set();
|
|
980
|
+
for (const id of input) {
|
|
981
|
+
const {
|
|
982
|
+
id: entryId
|
|
983
|
+
} = (0, _utils.parseIdentifier)(id);
|
|
984
|
+
entryIdList.add(entryId);
|
|
985
|
+
}
|
|
986
|
+
const ids = Array.from(entryIdList);
|
|
987
|
+
if (ids.length > maxDeletableEntries) {
|
|
988
|
+
throw new _error.default("Cannot delete more than 50 entries at once.", "DELETE_ENTRIES_MAX", {
|
|
989
|
+
entries: ids
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
await entriesPermissions.ensure({
|
|
993
|
+
rwd: "d"
|
|
994
|
+
});
|
|
995
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
996
|
+
model,
|
|
997
|
+
locale: getLocale().code
|
|
998
|
+
});
|
|
999
|
+
const {
|
|
1000
|
+
items: entries
|
|
1001
|
+
} = await storageOperations.entries.list(model, {
|
|
1002
|
+
where: {
|
|
1003
|
+
latest: true,
|
|
1004
|
+
entryId_in: ids
|
|
1005
|
+
},
|
|
1006
|
+
limit: maxDeletableEntries + 1
|
|
1007
|
+
});
|
|
1008
|
+
/**
|
|
1009
|
+
* We do not want to allow deleting entries that user does not own or cannot access.
|
|
1010
|
+
*/
|
|
1011
|
+
const items = (await (0, _filterAsync.filterAsync)(entries, async entry => {
|
|
1012
|
+
return entriesPermissions.ensure({
|
|
1013
|
+
owns: entry.createdBy
|
|
1014
|
+
}, {
|
|
1015
|
+
throw: false
|
|
1016
|
+
});
|
|
1017
|
+
})).map(entry => entry.id);
|
|
1018
|
+
try {
|
|
1019
|
+
await onEntryBeforeDeleteMultiple.publish({
|
|
1020
|
+
entries,
|
|
1021
|
+
ids,
|
|
1022
|
+
model
|
|
1023
|
+
});
|
|
1024
|
+
await storageOperations.entries.deleteMultipleEntries(model, {
|
|
1025
|
+
entries: items
|
|
1026
|
+
});
|
|
1027
|
+
await onEntryAfterDeleteMultiple.publish({
|
|
1028
|
+
entries,
|
|
1029
|
+
ids,
|
|
1030
|
+
model
|
|
1031
|
+
});
|
|
1032
|
+
return items.map(id => {
|
|
1033
|
+
return {
|
|
1034
|
+
id
|
|
1035
|
+
};
|
|
1036
|
+
});
|
|
1037
|
+
} catch (ex) {
|
|
1038
|
+
await onEntryDeleteMultipleError.publish({
|
|
1039
|
+
entries,
|
|
1040
|
+
ids,
|
|
1041
|
+
model,
|
|
1042
|
+
error: ex
|
|
1043
|
+
});
|
|
1044
|
+
throw new _error.default(ex.message, ex.code || "DELETE_ENTRIES_MULTIPLE_ERROR", {
|
|
1045
|
+
error: ex,
|
|
1046
|
+
entries
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
const deleteEntry = async (model, id, options) => {
|
|
1051
|
+
await entriesPermissions.ensure({
|
|
899
1052
|
rwd: "d"
|
|
900
1053
|
});
|
|
901
|
-
await
|
|
1054
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
1055
|
+
model,
|
|
1056
|
+
locale: getLocale().code
|
|
1057
|
+
});
|
|
1058
|
+
const {
|
|
1059
|
+
force
|
|
1060
|
+
} = options || {};
|
|
902
1061
|
const storageEntry = await storageOperations.entries.getLatestRevisionByEntryId(model, {
|
|
903
|
-
id
|
|
1062
|
+
id
|
|
904
1063
|
});
|
|
905
|
-
|
|
906
|
-
|
|
1064
|
+
/**
|
|
1065
|
+
* If there is no entry, and we do not force the deletion, just throw an error.
|
|
1066
|
+
*/
|
|
1067
|
+
if (!storageEntry && !force) {
|
|
1068
|
+
throw new _handlerGraphql.NotFoundError(`Entry "${id}" was not found!`);
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* In the case we are forcing the deletion, we do not need the storageEntry to exist as it might be an error when loading single database record.
|
|
1072
|
+
*
|
|
1073
|
+
* This happens, sometimes, in the Elasticsearch system as the entry might get deleted from the DynamoDB but not from the Elasticsearch.
|
|
1074
|
+
* This is due to high load on the Elasticsearch at the time of the deletion.
|
|
1075
|
+
*/
|
|
1076
|
+
//
|
|
1077
|
+
else if (!storageEntry && force) {
|
|
1078
|
+
const {
|
|
1079
|
+
id: entryId
|
|
1080
|
+
} = (0, _utils.parseIdentifier)(id);
|
|
1081
|
+
return await deleteEntryHelper({
|
|
1082
|
+
model,
|
|
1083
|
+
entry: {
|
|
1084
|
+
id,
|
|
1085
|
+
entryId
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
907
1088
|
}
|
|
908
|
-
|
|
1089
|
+
await entriesPermissions.ensure({
|
|
1090
|
+
owns: storageEntry.createdBy
|
|
1091
|
+
});
|
|
909
1092
|
const entry = await (0, _entryStorage.entryFromStorageTransform)(context, model, storageEntry);
|
|
910
1093
|
return await deleteEntryHelper({
|
|
911
1094
|
model,
|
|
@@ -913,17 +1096,22 @@ const createContentEntryCrud = params => {
|
|
|
913
1096
|
});
|
|
914
1097
|
};
|
|
915
1098
|
const publishEntry = async (model, id) => {
|
|
916
|
-
|
|
1099
|
+
await entriesPermissions.ensure({
|
|
917
1100
|
pw: "p"
|
|
918
1101
|
});
|
|
919
|
-
await
|
|
1102
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
1103
|
+
model,
|
|
1104
|
+
locale: getLocale().code
|
|
1105
|
+
});
|
|
920
1106
|
const originalStorageEntry = await storageOperations.entries.getRevisionById(model, {
|
|
921
1107
|
id
|
|
922
1108
|
});
|
|
923
1109
|
if (!originalStorageEntry) {
|
|
924
1110
|
throw new _handlerGraphql.NotFoundError(`Entry "${id}" in the model "${model.modelId}" was not found.`);
|
|
925
1111
|
}
|
|
926
|
-
|
|
1112
|
+
await entriesPermissions.ensure({
|
|
1113
|
+
owns: originalStorageEntry.createdBy
|
|
1114
|
+
});
|
|
927
1115
|
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
928
1116
|
const currentDate = new Date().toISOString();
|
|
929
1117
|
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
@@ -965,7 +1153,7 @@ const createContentEntryCrud = params => {
|
|
|
965
1153
|
}
|
|
966
1154
|
};
|
|
967
1155
|
const unpublishEntry = async (model, id) => {
|
|
968
|
-
|
|
1156
|
+
await entriesPermissions.ensure({
|
|
969
1157
|
pw: "u"
|
|
970
1158
|
});
|
|
971
1159
|
const {
|
|
@@ -982,7 +1170,9 @@ const createContentEntryCrud = params => {
|
|
|
982
1170
|
entry: originalStorageEntry
|
|
983
1171
|
});
|
|
984
1172
|
}
|
|
985
|
-
|
|
1173
|
+
await entriesPermissions.ensure({
|
|
1174
|
+
owns: originalStorageEntry.createdBy
|
|
1175
|
+
});
|
|
986
1176
|
const originalEntry = await (0, _entryStorage.entryFromStorageTransform)(context, model, originalStorageEntry);
|
|
987
1177
|
const entry = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, originalEntry), {}, {
|
|
988
1178
|
status: STATUS_UNPUBLISHED
|
|
@@ -1018,6 +1208,71 @@ const createContentEntryCrud = params => {
|
|
|
1018
1208
|
});
|
|
1019
1209
|
}
|
|
1020
1210
|
};
|
|
1211
|
+
const getUniqueFieldValues = async (model, params) => {
|
|
1212
|
+
await entriesPermissions.ensure({
|
|
1213
|
+
rwd: "r"
|
|
1214
|
+
});
|
|
1215
|
+
await modelsPermissions.ensureCanAccessModel({
|
|
1216
|
+
model,
|
|
1217
|
+
locale: getLocale().code
|
|
1218
|
+
});
|
|
1219
|
+
const {
|
|
1220
|
+
where: initialWhere,
|
|
1221
|
+
fieldId
|
|
1222
|
+
} = params;
|
|
1223
|
+
const where = (0, _objectSpread2.default)({}, initialWhere);
|
|
1224
|
+
/**
|
|
1225
|
+
* Possibly only get records which are owned by current user.
|
|
1226
|
+
* Or if searching for the owner set that value - in the case that user can see other entries than their own.
|
|
1227
|
+
*/
|
|
1228
|
+
if (await entriesPermissions.canAccessOnlyOwnRecords()) {
|
|
1229
|
+
where.ownedBy = getIdentity().id;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
/**
|
|
1233
|
+
* Where must contain either latest or published keys.
|
|
1234
|
+
* We cannot list entries without one of those
|
|
1235
|
+
*/
|
|
1236
|
+
if (where.latest && where.published) {
|
|
1237
|
+
throw new _error.default("Cannot list entries that are both published and latest.", "LIST_ENTRIES_ERROR", {
|
|
1238
|
+
where
|
|
1239
|
+
});
|
|
1240
|
+
} else if (!where.latest && !where.published) {
|
|
1241
|
+
throw new _error.default("Cannot list entries if we do not have latest or published defined.", "LIST_ENTRIES_ERROR", {
|
|
1242
|
+
where
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
/**
|
|
1246
|
+
* We need to verify that the field in question is searchable.
|
|
1247
|
+
*/
|
|
1248
|
+
const fields = (0, _searchableFields.getSearchableFields)({
|
|
1249
|
+
fields: model.fields,
|
|
1250
|
+
plugins: context.plugins,
|
|
1251
|
+
input: []
|
|
1252
|
+
});
|
|
1253
|
+
if (!fields.includes(fieldId)) {
|
|
1254
|
+
throw new _error.default("Cannot list unique entry field values if the field is not searchable.", "LIST_UNIQUE_ENTRY_VALUES_ERROR", {
|
|
1255
|
+
fieldId
|
|
1256
|
+
});
|
|
1257
|
+
}
|
|
1258
|
+
try {
|
|
1259
|
+
return await storageOperations.entries.getUniqueFieldValues(model, {
|
|
1260
|
+
where,
|
|
1261
|
+
fieldId
|
|
1262
|
+
});
|
|
1263
|
+
} catch (ex) {
|
|
1264
|
+
throw new _error.default("Error while fetching unique entry values from storage.", "LIST_UNIQUE_ENTRY_VALUES_ERROR", {
|
|
1265
|
+
error: {
|
|
1266
|
+
message: ex.message,
|
|
1267
|
+
code: ex.code,
|
|
1268
|
+
data: ex.data
|
|
1269
|
+
},
|
|
1270
|
+
model,
|
|
1271
|
+
where,
|
|
1272
|
+
fieldId
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
};
|
|
1021
1276
|
return {
|
|
1022
1277
|
/**
|
|
1023
1278
|
* Deprecated - will be removed in 5.35.0
|
|
@@ -1192,9 +1447,14 @@ const createContentEntryCrud = params => {
|
|
|
1192
1447
|
return deleteEntryRevision(model, id);
|
|
1193
1448
|
});
|
|
1194
1449
|
},
|
|
1195
|
-
async deleteEntry(model, entryId) {
|
|
1450
|
+
async deleteEntry(model, entryId, options) {
|
|
1196
1451
|
return context.benchmark.measure("headlessCms.crud.entries.deleteEntry", async () => {
|
|
1197
|
-
return deleteEntry(model, entryId);
|
|
1452
|
+
return deleteEntry(model, entryId, options);
|
|
1453
|
+
});
|
|
1454
|
+
},
|
|
1455
|
+
async deleteMultipleEntries(model, ids) {
|
|
1456
|
+
return context.benchmark.measure("headlessCms.crud.entries.deleteMultipleEntries", async () => {
|
|
1457
|
+
return deleteMultipleEntries(model, ids);
|
|
1198
1458
|
});
|
|
1199
1459
|
},
|
|
1200
1460
|
async publishEntry(model, id) {
|
|
@@ -1206,6 +1466,11 @@ const createContentEntryCrud = params => {
|
|
|
1206
1466
|
return context.benchmark.measure("headlessCms.crud.entries.unpublishEntry", async () => {
|
|
1207
1467
|
return unpublishEntry(model, id);
|
|
1208
1468
|
});
|
|
1469
|
+
},
|
|
1470
|
+
async getUniqueFieldValues(model, params) {
|
|
1471
|
+
return context.benchmark.measure("headlessCms.crud.entries.getUniqueFieldValues", async () => {
|
|
1472
|
+
return getUniqueFieldValues(model, params);
|
|
1473
|
+
});
|
|
1209
1474
|
}
|
|
1210
1475
|
};
|
|
1211
1476
|
};
|