@webiny/api-headless-cms 0.0.0-unstable.496cf268ac → 0.0.0-unstable.606fc9c866

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 (138) hide show
  1. package/context.js +47 -43
  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 +6 -4
  6. package/crud/contentEntry.crud.js +896 -821
  7. package/crud/contentEntry.crud.js.map +1 -1
  8. package/crud/contentModel/beforeCreate.js +38 -79
  9. package/crud/contentModel/beforeCreate.js.map +1 -1
  10. package/crud/contentModel/beforeDelete.d.ts +1 -1
  11. package/crud/contentModel/beforeDelete.js +1 -5
  12. package/crud/contentModel/beforeDelete.js.map +1 -1
  13. package/crud/contentModel/beforeUpdate.js +30 -6
  14. package/crud/contentModel/beforeUpdate.js.map +1 -1
  15. package/crud/contentModel/validate/endingAllowed.d.ts +6 -0
  16. package/crud/contentModel/validate/endingAllowed.js +26 -0
  17. package/crud/contentModel/validate/endingAllowed.js.map +1 -0
  18. package/crud/contentModel/validate/isModelEndingAllowed.d.ts +6 -0
  19. package/crud/contentModel/validate/isModelEndingAllowed.js +24 -0
  20. package/crud/contentModel/validate/isModelEndingAllowed.js.map +1 -0
  21. package/crud/contentModel/validate/modelId.d.ts +11 -0
  22. package/crud/contentModel/validate/modelId.js +36 -0
  23. package/crud/contentModel/validate/modelId.js.map +1 -0
  24. package/crud/contentModel/validate/pluralApiName.d.ts +7 -0
  25. package/crud/contentModel/validate/pluralApiName.js +24 -0
  26. package/crud/contentModel/validate/pluralApiName.js.map +1 -0
  27. package/crud/contentModel/validate/singularApiName.d.ts +7 -0
  28. package/crud/contentModel/validate/singularApiName.js +24 -0
  29. package/crud/contentModel/validate/singularApiName.js.map +1 -0
  30. package/crud/contentModel/validateModelFields.js +6 -7
  31. package/crud/contentModel/validateModelFields.js.map +1 -1
  32. package/crud/contentModel/validation.d.ts +127 -95
  33. package/crud/contentModel/validation.js +4 -4
  34. package/crud/contentModel/validation.js.map +1 -1
  35. package/crud/contentModel.crud.js +334 -296
  36. package/crud/contentModel.crud.js.map +1 -1
  37. package/crud/contentModelGroup/validation.d.ts +4 -4
  38. package/crud/contentModelGroup.crud.js +170 -142
  39. package/crud/contentModelGroup.crud.js.map +1 -1
  40. package/crud/settings.crud.d.ts +1 -1
  41. package/crud/settings.crud.js +5 -10
  42. package/crud/settings.crud.js.map +1 -1
  43. package/graphql/checkEndpointAccess.d.ts +2 -0
  44. package/graphql/checkEndpointAccess.js +18 -0
  45. package/graphql/checkEndpointAccess.js.map +1 -0
  46. package/graphql/createExecutableSchema.d.ts +2 -3
  47. package/graphql/createExecutableSchema.js.map +1 -1
  48. package/graphql/createRequestBody.d.ts +2 -0
  49. package/graphql/createRequestBody.js +14 -0
  50. package/graphql/createRequestBody.js.map +1 -0
  51. package/graphql/formatErrorPayload.d.ts +1 -0
  52. package/graphql/formatErrorPayload.js +25 -0
  53. package/graphql/formatErrorPayload.js.map +1 -0
  54. package/graphql/generateSchema.js.map +1 -1
  55. package/graphql/getSchema.d.ts +17 -0
  56. package/graphql/getSchema.js +102 -0
  57. package/graphql/getSchema.js.map +1 -0
  58. package/graphql/graphQLHandlerFactory.js +6 -150
  59. package/graphql/graphQLHandlerFactory.js.map +1 -1
  60. package/graphql/handleRequest.d.ts +11 -0
  61. package/graphql/handleRequest.js +81 -0
  62. package/graphql/handleRequest.js.map +1 -0
  63. package/graphql/index.d.ts +1 -1
  64. package/graphql/schema/contentModelGroups.js +6 -6
  65. package/graphql/schema/contentModelGroups.js.map +1 -1
  66. package/graphql/schema/contentModels.js +3 -3
  67. package/graphql/schema/contentModels.js.map +1 -1
  68. package/graphql/schema/createFieldResolvers.js +2 -1
  69. package/graphql/schema/createFieldResolvers.js.map +1 -1
  70. package/graphql/schema/createManageResolvers.js +6 -0
  71. package/graphql/schema/createManageResolvers.js.map +1 -1
  72. package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.d.ts +4 -0
  73. package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.js +18 -0
  74. package/graphql/schema/resolvers/manage/resolveGetUniqueFieldValues.js.map +1 -0
  75. package/graphqlFields/dynamicZone/dynamicZoneField.d.ts +1 -1
  76. package/graphqlFields/dynamicZone/dynamicZoneField.js +44 -17
  77. package/graphqlFields/dynamicZone/dynamicZoneField.js.map +1 -1
  78. package/graphqlFields/object.js +14 -1
  79. package/graphqlFields/object.js.map +1 -1
  80. package/graphqlFields/ref.js +7 -7
  81. package/graphqlFields/ref.js.map +1 -1
  82. package/index.d.ts +3 -1
  83. package/index.js +24 -0
  84. package/index.js.map +1 -1
  85. package/package.json +22 -22
  86. package/plugins/CmsModelPlugin.d.ts +15 -7
  87. package/plugins/CmsModelPlugin.js +21 -6
  88. package/plugins/CmsModelPlugin.js.map +1 -1
  89. package/plugins/StorageOperationsCmsModelPlugin.d.ts +23 -0
  90. package/plugins/StorageOperationsCmsModelPlugin.js +42 -0
  91. package/plugins/StorageOperationsCmsModelPlugin.js.map +1 -0
  92. package/plugins/index.d.ts +1 -0
  93. package/plugins/index.js +11 -0
  94. package/plugins/index.js.map +1 -1
  95. package/types.d.ts +72 -48
  96. package/types.js +4 -0
  97. package/types.js.map +1 -1
  98. package/utils/converters/valueKeyStorageConverter.d.ts +1 -5
  99. package/utils/converters/valueKeyStorageConverter.js +19 -17
  100. package/utils/converters/valueKeyStorageConverter.js.map +1 -1
  101. package/utils/createTypeFromFields.js +1 -2
  102. package/utils/createTypeFromFields.js.map +1 -1
  103. package/utils/createTypeName.d.ts +0 -2
  104. package/utils/createTypeName.js +2 -10
  105. package/utils/createTypeName.js.map +1 -1
  106. package/utils/incrementEntryIdVersion.d.ts +5 -0
  107. package/utils/incrementEntryIdVersion.js +29 -0
  108. package/utils/incrementEntryIdVersion.js.map +1 -0
  109. package/crud/contentModel/createFieldModels.d.ts +0 -2
  110. package/crud/contentModel/createFieldModels.js +0 -26
  111. package/crud/contentModel/createFieldModels.js.map +0 -1
  112. package/crud/contentModel/fieldIdValidation.d.ts +0 -1
  113. package/crud/contentModel/fieldIdValidation.js +0 -25
  114. package/crud/contentModel/fieldIdValidation.js.map +0 -1
  115. package/crud/contentModel/idValidation.d.ts +0 -1
  116. package/crud/contentModel/idValidation.js +0 -22
  117. package/crud/contentModel/idValidation.js.map +0 -1
  118. package/crud/contentModel/models.d.ts +0 -4
  119. package/crud/contentModel/models.js +0 -192
  120. package/crud/contentModel/models.js.map +0 -1
  121. package/crud/contentModel/systemFields.d.ts +0 -1
  122. package/crud/contentModel/systemFields.js +0 -8
  123. package/crud/contentModel/systemFields.js.map +0 -1
  124. package/upgrades/5.33.0/index.d.ts +0 -3
  125. package/upgrades/5.33.0/index.js +0 -182
  126. package/upgrades/5.33.0/index.js.map +0 -1
  127. package/upgrades/index.d.ts +0 -1
  128. package/upgrades/index.js +0 -12
  129. package/upgrades/index.js.map +0 -1
  130. package/utils/pluralizedTypeName.d.ts +0 -1
  131. package/utils/pluralizedTypeName.js +0 -26
  132. package/utils/pluralizedTypeName.js.map +0 -1
  133. package/utils/removeNullValues.d.ts +0 -1
  134. package/utils/removeNullValues.js +0 -17
  135. package/utils/removeNullValues.js.map +0 -1
  136. package/utils/removeUndefinedValues.d.ts +0 -1
  137. package/utils/removeUndefinedValues.js +0 -17
  138. package/utils/removeUndefinedValues.js.map +0 -1
@@ -27,7 +27,6 @@ var _access = require("../utils/access");
27
27
  var _validation = require("./contentModel/validation");
28
28
  var _utils = require("@webiny/utils");
29
29
  var _defaultFields = require("./contentModel/defaultFields");
30
- var _removeUndefinedValues = require("../utils/removeUndefinedValues");
31
30
  var _modelApiName = require("./contentModel/compatibility/modelApiName");
32
31
  const _excluded = ["defaultFields"];
33
32
  /**
@@ -141,21 +140,25 @@ const createModelsCrud = params => {
141
140
  return databaseModels.concat(pluginsModels);
142
141
  };
143
142
  const listModels = async () => {
144
- const permission = await checkModelPermissions("r");
145
- const models = await modelsList();
146
- return (0, _filterAsync.filterAsync)(models, async model => {
147
- if (!(0, _ownership.validateOwnership)(context, permission, model)) {
148
- return false;
149
- }
150
- return (0, _access.validateModelAccess)(context, model);
143
+ return context.benchmark.measure("headlessCms.crud.models.listModels", async () => {
144
+ const permission = await checkModelPermissions("r");
145
+ const models = await modelsList();
146
+ return (0, _filterAsync.filterAsync)(models, async model => {
147
+ if (!(0, _ownership.validateOwnership)(context, permission, model)) {
148
+ return false;
149
+ }
150
+ return (0, _access.validateModelAccess)(context, model);
151
+ });
151
152
  });
152
153
  };
153
154
  const getModel = async modelId => {
154
- const permission = await checkModelPermissions("r");
155
- const model = await modelsGet(modelId);
156
- (0, _ownership.checkOwnership)(context, permission, model);
157
- await (0, _access.checkModelAccess)(context, model);
158
- return model;
155
+ return context.benchmark.measure("headlessCms.crud.models.getModel", async () => {
156
+ const permission = await checkModelPermissions("r");
157
+ const model = await modelsGet(modelId);
158
+ (0, _ownership.checkOwnership)(context, permission, model);
159
+ await (0, _access.checkModelAccess)(context, model);
160
+ return model;
161
+ });
159
162
  };
160
163
  const getModelManager = async target => {
161
164
  const modelId = typeof target === "string" ? target : target.modelId;
@@ -232,6 +235,311 @@ const createModelsCrud = params => {
232
235
  context,
233
236
  onModelAfterDelete
234
237
  });
238
+
239
+ /**
240
+ * CRUD methods
241
+ */
242
+ const createModel = async input => {
243
+ await checkModelPermissions("w");
244
+ const result = await (0, _validation.createModelCreateValidation)().safeParseAsync(input);
245
+ if (!result.success) {
246
+ throw (0, _utils.createZodError)(result.error);
247
+ }
248
+ /**
249
+ * We need to extract the defaultFields because it is not for the CmsModel object.
250
+ */
251
+ const _removeUndefinedValue = (0, _utils.removeUndefinedValues)(result.data),
252
+ {
253
+ defaultFields
254
+ } = _removeUndefinedValue,
255
+ data = (0, _objectWithoutProperties2.default)(_removeUndefinedValue, _excluded);
256
+ if (defaultFields) {
257
+ (0, _defaultFields.assignModelDefaultFields)(data);
258
+ }
259
+ const group = await context.security.withoutAuthorization(async () => {
260
+ return context.cms.getGroup(data.group);
261
+ });
262
+ if (!group) {
263
+ throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
264
+ }
265
+ const identity = getIdentity();
266
+ const model = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, data), {}, {
267
+ modelId: data.modelId || "",
268
+ singularApiName: data.singularApiName,
269
+ pluralApiName: data.pluralApiName,
270
+ titleFieldId: "id",
271
+ descriptionFieldId: null,
272
+ imageFieldId: null,
273
+ description: data.description || "",
274
+ locale: getLocale().code,
275
+ tenant: getTenant().id,
276
+ group: {
277
+ id: group.id,
278
+ name: group.name
279
+ },
280
+ createdBy: {
281
+ id: identity.id,
282
+ displayName: identity.displayName,
283
+ type: identity.type
284
+ },
285
+ createdOn: new Date().toISOString(),
286
+ savedOn: new Date().toISOString(),
287
+ lockedFields: [],
288
+ webinyVersion: context.WEBINY_VERSION
289
+ });
290
+ model.tags = ensureTypeTag(model);
291
+ try {
292
+ await onModelBeforeCreate.publish({
293
+ input: data,
294
+ model
295
+ });
296
+ const createdModel = await storageOperations.models.create({
297
+ model
298
+ });
299
+ loaders.listModels.clearAll();
300
+ await updateManager(context, model);
301
+ await onModelAfterCreate.publish({
302
+ input: data,
303
+ model: createdModel
304
+ });
305
+ return createdModel;
306
+ } catch (ex) {
307
+ await onModelCreateError.publish({
308
+ input: data,
309
+ model,
310
+ error: ex
311
+ });
312
+ throw ex;
313
+ }
314
+ };
315
+ const updateModel = async (modelId, input) => {
316
+ await checkModelPermissions("w");
317
+
318
+ // Get a model record; this will also perform ownership validation.
319
+ const original = await getModel(modelId);
320
+ const result = await (0, _validation.createModelUpdateValidation)().safeParseAsync(input);
321
+ if (!result.success) {
322
+ throw (0, _utils.createZodError)(result.error);
323
+ }
324
+ const data = (0, _utils.removeUndefinedValues)(result.data);
325
+ if (Object.keys(data).length === 0) {
326
+ /**
327
+ * We need to return the original if nothing is to be updated.
328
+ */
329
+ return original;
330
+ }
331
+ let group = {
332
+ id: original.group.id,
333
+ name: original.group.name
334
+ };
335
+ const groupId = data.group;
336
+ if (groupId) {
337
+ const groupData = await context.security.withoutAuthorization(async () => {
338
+ return context.cms.getGroup(groupId);
339
+ });
340
+ if (!groupData) {
341
+ throw new _handlerGraphql.NotFoundError(`There is no group "${groupId}".`);
342
+ }
343
+ group = {
344
+ id: groupData.id,
345
+ name: groupData.name
346
+ };
347
+ }
348
+ const model = (0, _objectSpread2.default)((0, _objectSpread2.default)((0, _objectSpread2.default)({}, original), data), {}, {
349
+ titleFieldId: data.titleFieldId === undefined ? original.titleFieldId : data.titleFieldId,
350
+ descriptionFieldId: data.descriptionFieldId === undefined ? original.descriptionFieldId : data.descriptionFieldId,
351
+ imageFieldId: data.imageFieldId === undefined ? original.imageFieldId : data.imageFieldId,
352
+ group,
353
+ description: data.description || original.description,
354
+ tenant: original.tenant || getTenant().id,
355
+ locale: original.locale || getLocale().code,
356
+ webinyVersion: context.WEBINY_VERSION,
357
+ savedOn: new Date().toISOString()
358
+ });
359
+ model.tags = ensureTypeTag(model);
360
+ try {
361
+ await onModelBeforeUpdate.publish({
362
+ input: data,
363
+ original,
364
+ model
365
+ });
366
+ const resultModel = await storageOperations.models.update({
367
+ model
368
+ });
369
+ await updateManager(context, resultModel);
370
+ await onModelAfterUpdate.publish({
371
+ input: data,
372
+ original,
373
+ model: resultModel
374
+ });
375
+ return resultModel;
376
+ } catch (ex) {
377
+ await onModelUpdateError.publish({
378
+ input: data,
379
+ model,
380
+ original,
381
+ error: ex
382
+ });
383
+ throw ex;
384
+ }
385
+ };
386
+ const updateModelDirect = async params => {
387
+ const {
388
+ model: initialModel,
389
+ original
390
+ } = params;
391
+ const model = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, initialModel), {}, {
392
+ tenant: initialModel.tenant || getTenant().id,
393
+ locale: initialModel.locale || getLocale().code,
394
+ webinyVersion: context.WEBINY_VERSION
395
+ });
396
+ try {
397
+ await onModelBeforeUpdate.publish({
398
+ input: {},
399
+ original,
400
+ model
401
+ });
402
+ const resultModel = await storageOperations.models.update({
403
+ model
404
+ });
405
+ await updateManager(context, resultModel);
406
+ loaders.listModels.clearAll();
407
+ await onModelAfterUpdate.publish({
408
+ input: {},
409
+ original,
410
+ model: resultModel
411
+ });
412
+ return resultModel;
413
+ } catch (ex) {
414
+ await onModelUpdateError.publish({
415
+ input: {},
416
+ original,
417
+ model,
418
+ error: ex
419
+ });
420
+ throw ex;
421
+ }
422
+ };
423
+ const createModelFrom = async (modelId, input) => {
424
+ await checkModelPermissions("w");
425
+ /**
426
+ * Get a model record; this will also perform ownership validation.
427
+ */
428
+ const original = await getModel(modelId);
429
+ const result = await (0, _validation.createModelCreateFromValidation)().safeParseAsync((0, _objectSpread2.default)((0, _objectSpread2.default)({}, input), {}, {
430
+ description: input.description || original.description
431
+ }));
432
+ if (!result.success) {
433
+ throw (0, _utils.createZodError)(result.error);
434
+ }
435
+ const data = (0, _utils.removeUndefinedValues)(result.data);
436
+ const locale = await context.i18n.getLocale(data.locale || original.locale);
437
+ if (!locale) {
438
+ throw new _handlerGraphql.NotFoundError(`There is no locale "${data.locale}".`);
439
+ }
440
+ /**
441
+ * Use storage operations directly because we cannot get group from different locale via context methods.
442
+ */
443
+ const group = await context.cms.storageOperations.groups.get({
444
+ id: data.group,
445
+ tenant: original.tenant,
446
+ locale: locale.code
447
+ });
448
+ if (!group) {
449
+ throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
450
+ }
451
+ const identity = getIdentity();
452
+ const model = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, original), {}, {
453
+ singularApiName: data.singularApiName,
454
+ pluralApiName: data.pluralApiName,
455
+ locale: locale.code,
456
+ group: {
457
+ id: group.id,
458
+ name: group.name
459
+ },
460
+ icon: data.icon,
461
+ name: data.name,
462
+ modelId: data.modelId || "",
463
+ description: data.description || "",
464
+ createdBy: {
465
+ id: identity.id,
466
+ displayName: identity.displayName,
467
+ type: identity.type
468
+ },
469
+ createdOn: new Date().toISOString(),
470
+ savedOn: new Date().toISOString(),
471
+ lockedFields: [],
472
+ webinyVersion: context.WEBINY_VERSION
473
+ });
474
+ try {
475
+ await onModelBeforeCreateFrom.publish({
476
+ input: data,
477
+ model,
478
+ original
479
+ });
480
+ const createdModel = await storageOperations.models.create({
481
+ model
482
+ });
483
+ loaders.listModels.clearAll();
484
+ await updateManager(context, model);
485
+ await onModelAfterCreateFrom.publish({
486
+ input: data,
487
+ original,
488
+ model: createdModel
489
+ });
490
+ return createdModel;
491
+ } catch (ex) {
492
+ await onModelCreateFromError.publish({
493
+ input: data,
494
+ original,
495
+ model,
496
+ error: ex
497
+ });
498
+ throw ex;
499
+ }
500
+ };
501
+ const deleteModel = async modelId => {
502
+ await checkModelPermissions("d");
503
+ const model = await getModel(modelId);
504
+ try {
505
+ await onModelBeforeDelete.publish({
506
+ model
507
+ });
508
+ try {
509
+ await storageOperations.models.delete({
510
+ model
511
+ });
512
+ } catch (ex) {
513
+ throw new _error.default(ex.message || "Could not delete the content model", ex.code || "CONTENT_MODEL_DELETE_ERROR", {
514
+ error: ex,
515
+ modelId: model.modelId
516
+ });
517
+ }
518
+ await onModelAfterDelete.publish({
519
+ model
520
+ });
521
+ managers.delete(model.modelId);
522
+ } catch (ex) {
523
+ await onModelDeleteError.publish({
524
+ model,
525
+ error: ex
526
+ });
527
+ throw ex;
528
+ }
529
+ };
530
+ const initializeModel = async (modelId, data) => {
531
+ /**
532
+ * We require that users have write permissions to initialize models.
533
+ * Maybe introduce another permission for it?
534
+ */
535
+ await checkModelPermissions("w");
536
+ const model = await getModel(modelId);
537
+ await onModelInitialize.publish({
538
+ model,
539
+ data
540
+ });
541
+ return true;
542
+ };
235
543
  return {
236
544
  /**
237
545
  * Deprecated - will be removed in 5.36.0
@@ -264,308 +572,38 @@ const createModelsCrud = params => {
264
572
  getModel,
265
573
  listModels,
266
574
  async createModel(input) {
267
- await checkModelPermissions("w");
268
- const result = await (0, _validation.createModelCreateValidation)().safeParseAsync(input);
269
- if (!result.success) {
270
- throw (0, _utils.createZodError)(result.error);
271
- }
272
- /**
273
- * We need to extract the defaultFields because it is not for the CmsModel object.
274
- */
275
- const _removeUndefinedValue = (0, _removeUndefinedValues.removeUndefinedValues)(result.data),
276
- {
277
- defaultFields
278
- } = _removeUndefinedValue,
279
- data = (0, _objectWithoutProperties2.default)(_removeUndefinedValue, _excluded);
280
- if (defaultFields) {
281
- (0, _defaultFields.assignModelDefaultFields)(data);
282
- }
283
- context.security.disableAuthorization();
284
- const group = await context.cms.getGroup(data.group);
285
- context.security.enableAuthorization();
286
- if (!group) {
287
- throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
288
- }
289
- const identity = getIdentity();
290
- const model = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, data), {}, {
291
- modelId: data.modelId || "",
292
- singularApiName: data.singularApiName,
293
- pluralApiName: data.pluralApiName,
294
- titleFieldId: "id",
295
- descriptionFieldId: null,
296
- imageFieldId: null,
297
- description: data.description || "",
298
- locale: getLocale().code,
299
- tenant: getTenant().id,
300
- group: {
301
- id: group.id,
302
- name: group.name
303
- },
304
- createdBy: {
305
- id: identity.id,
306
- displayName: identity.displayName,
307
- type: identity.type
308
- },
309
- createdOn: new Date().toISOString(),
310
- savedOn: new Date().toISOString(),
311
- lockedFields: [],
312
- webinyVersion: context.WEBINY_VERSION
575
+ return context.benchmark.measure("headlessCms.crud.models.createModel", async () => {
576
+ return createModel(input);
313
577
  });
314
- model.tags = ensureTypeTag(model);
315
- try {
316
- await onModelBeforeCreate.publish({
317
- input: data,
318
- model
319
- });
320
- const createdModel = await storageOperations.models.create({
321
- model
322
- });
323
- loaders.listModels.clearAll();
324
- await updateManager(context, model);
325
- await onModelAfterCreate.publish({
326
- input: data,
327
- model: createdModel
328
- });
329
- return createdModel;
330
- } catch (ex) {
331
- await onModelCreateError.publish({
332
- input: data,
333
- model,
334
- error: ex
335
- });
336
- throw ex;
337
- }
338
578
  },
339
579
  /**
340
580
  * Method does not check for permissions or ownership.
341
581
  * @internal
342
582
  */
343
583
  async updateModelDirect(params) {
344
- const {
345
- model: initialModel,
346
- original
347
- } = params;
348
- const model = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, initialModel), {}, {
349
- tenant: initialModel.tenant || getTenant().id,
350
- locale: initialModel.locale || getLocale().code,
351
- webinyVersion: context.WEBINY_VERSION
584
+ return context.benchmark.measure("headlessCms.crud.models.updateModelDirect", async () => {
585
+ return updateModelDirect(params);
352
586
  });
353
- try {
354
- await onModelBeforeUpdate.publish({
355
- input: {},
356
- original,
357
- model
358
- });
359
- const resultModel = await storageOperations.models.update({
360
- model
361
- });
362
- await updateManager(context, resultModel);
363
- loaders.listModels.clearAll();
364
- await onModelAfterUpdate.publish({
365
- input: {},
366
- original,
367
- model: resultModel
368
- });
369
- return resultModel;
370
- } catch (ex) {
371
- await onModelUpdateError.publish({
372
- input: {},
373
- original,
374
- model,
375
- error: ex
376
- });
377
- throw ex;
378
- }
379
587
  },
380
588
  async createModelFrom(modelId, userInput) {
381
- await checkModelPermissions("w");
382
- /**
383
- * Get a model record; this will also perform ownership validation.
384
- */
385
- const original = await getModel(modelId);
386
- const result = await (0, _validation.createModelCreateFromValidation)().safeParseAsync((0, _objectSpread2.default)((0, _objectSpread2.default)({}, userInput), {}, {
387
- description: userInput.description || original.description
388
- }));
389
- if (!result.success) {
390
- throw (0, _utils.createZodError)(result.error);
391
- }
392
- const data = (0, _removeUndefinedValues.removeUndefinedValues)(result.data);
393
- const locale = await context.i18n.getLocale(data.locale || original.locale);
394
- if (!locale) {
395
- throw new _handlerGraphql.NotFoundError(`There is no locale "${data.locale}".`);
396
- }
397
- /**
398
- * Use storage operations directly because we cannot get group from different locale via context methods.
399
- */
400
- const group = await context.cms.storageOperations.groups.get({
401
- id: data.group,
402
- tenant: original.tenant,
403
- locale: locale.code
404
- });
405
- if (!group) {
406
- throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
407
- }
408
- const identity = getIdentity();
409
- const model = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, original), {}, {
410
- singularApiName: data.singularApiName,
411
- pluralApiName: data.pluralApiName,
412
- locale: locale.code,
413
- group: {
414
- id: group.id,
415
- name: group.name
416
- },
417
- icon: data.icon,
418
- name: data.name,
419
- modelId: data.modelId || "",
420
- description: data.description || "",
421
- createdBy: {
422
- id: identity.id,
423
- displayName: identity.displayName,
424
- type: identity.type
425
- },
426
- createdOn: new Date().toISOString(),
427
- savedOn: new Date().toISOString(),
428
- lockedFields: [],
429
- webinyVersion: context.WEBINY_VERSION
589
+ return context.benchmark.measure("headlessCms.crud.models.createModelFrom", async () => {
590
+ return createModelFrom(modelId, userInput);
430
591
  });
431
- try {
432
- await onModelBeforeCreateFrom.publish({
433
- input: data,
434
- model,
435
- original
436
- });
437
- const createdModel = await storageOperations.models.create({
438
- model
439
- });
440
- loaders.listModels.clearAll();
441
- await updateManager(context, model);
442
- await onModelAfterCreateFrom.publish({
443
- input: data,
444
- original,
445
- model: createdModel
446
- });
447
- return createdModel;
448
- } catch (ex) {
449
- await onModelCreateFromError.publish({
450
- input: data,
451
- original,
452
- model,
453
- error: ex
454
- });
455
- throw ex;
456
- }
457
592
  },
458
593
  async updateModel(modelId, input) {
459
- await checkModelPermissions("w");
460
-
461
- // Get a model record; this will also perform ownership validation.
462
- const original = await getModel(modelId);
463
- const result = await (0, _validation.createModelUpdateValidation)().safeParseAsync(input);
464
- if (!result.success) {
465
- throw (0, _utils.createZodError)(result.error);
466
- }
467
- const data = (0, _removeUndefinedValues.removeUndefinedValues)(result.data);
468
- if (Object.keys(data).length === 0) {
469
- /**
470
- * We need to return the original if nothing is to be updated.
471
- */
472
- return original;
473
- }
474
- let group = {
475
- id: original.group.id,
476
- name: original.group.name
477
- };
478
- if (data.group) {
479
- context.security.disableAuthorization();
480
- const groupData = await context.cms.getGroup(data.group);
481
- context.security.enableAuthorization();
482
- if (!groupData) {
483
- throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
484
- }
485
- group = {
486
- id: groupData.id,
487
- name: groupData.name
488
- };
489
- }
490
- const model = (0, _objectSpread2.default)((0, _objectSpread2.default)((0, _objectSpread2.default)({}, original), data), {}, {
491
- titleFieldId: data.titleFieldId === undefined ? original.titleFieldId : data.titleFieldId,
492
- descriptionFieldId: data.descriptionFieldId === undefined ? original.descriptionFieldId : data.descriptionFieldId,
493
- imageFieldId: data.imageFieldId === undefined ? original.imageFieldId : data.imageFieldId,
494
- group,
495
- description: data.description || original.description,
496
- tenant: original.tenant || getTenant().id,
497
- locale: original.locale || getLocale().code,
498
- webinyVersion: context.WEBINY_VERSION,
499
- savedOn: new Date().toISOString()
594
+ return context.benchmark.measure("headlessCms.crud.models.updateModel", async () => {
595
+ return updateModel(modelId, input);
500
596
  });
501
- model.tags = ensureTypeTag(model);
502
- try {
503
- await onModelBeforeUpdate.publish({
504
- input: data,
505
- original,
506
- model
507
- });
508
- const resultModel = await storageOperations.models.update({
509
- model
510
- });
511
- await updateManager(context, resultModel);
512
- await onModelAfterUpdate.publish({
513
- input: data,
514
- original,
515
- model: resultModel
516
- });
517
- return resultModel;
518
- } catch (ex) {
519
- await onModelUpdateError.publish({
520
- input: data,
521
- model,
522
- original,
523
- error: ex
524
- });
525
- throw ex;
526
- }
527
597
  },
528
598
  async deleteModel(modelId) {
529
- await checkModelPermissions("d");
530
- const model = await getModel(modelId);
531
- try {
532
- await onModelBeforeDelete.publish({
533
- model
534
- });
535
- try {
536
- await storageOperations.models.delete({
537
- model
538
- });
539
- } catch (ex) {
540
- throw new _error.default(ex.message || "Could not delete the content model", ex.code || "CONTENT_MODEL_DELETE_ERROR", {
541
- error: ex,
542
- modelId: model.modelId
543
- });
544
- }
545
- await onModelAfterDelete.publish({
546
- model
547
- });
548
- managers.delete(model.modelId);
549
- } catch (ex) {
550
- await onModelDeleteError.publish({
551
- model,
552
- error: ex
553
- });
554
- throw ex;
555
- }
599
+ return context.benchmark.measure("headlessCms.crud.models.deleteModel", async () => {
600
+ return deleteModel(modelId);
601
+ });
556
602
  },
557
603
  async initializeModel(modelId, data) {
558
- /**
559
- * We require that users have write permissions to initialize models.
560
- * Maybe introduce another permission for it?
561
- */
562
- await checkModelPermissions("w");
563
- const model = await getModel(modelId);
564
- await onModelInitialize.publish({
565
- model,
566
- data
604
+ return context.benchmark.measure("headlessCms.crud.models.initializeModel", async () => {
605
+ return initializeModel(modelId, data);
567
606
  });
568
- return true;
569
607
  },
570
608
  getModelManager,
571
609
  getEntryManager: async model => {