@webiny/api-headless-cms 0.0.0-unstable.1e66d121db → 0.0.0-unstable.3386f66516

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 (173) hide show
  1. package/context.d.ts +5 -2
  2. package/context.js +63 -4
  3. package/context.js.map +1 -1
  4. package/crud/contentEntry/markLockedFields.js +5 -2
  5. package/crud/contentEntry/markLockedFields.js.map +1 -1
  6. package/crud/contentEntry/referenceFieldsMapping.js +9 -5
  7. package/crud/contentEntry/referenceFieldsMapping.js.map +1 -1
  8. package/crud/contentEntry/searchableFields.d.ts +9 -0
  9. package/crud/contentEntry/searchableFields.js +83 -0
  10. package/crud/contentEntry/searchableFields.js.map +1 -0
  11. package/crud/contentEntry.crud.js +96 -42
  12. package/crud/contentEntry.crud.js.map +1 -1
  13. package/crud/contentModel/beforeCreate.d.ts +2 -3
  14. package/crud/contentModel/beforeCreate.js +4 -4
  15. package/crud/contentModel/beforeCreate.js.map +1 -1
  16. package/crud/contentModel/beforeUpdate.d.ts +2 -4
  17. package/crud/contentModel/beforeUpdate.js +2 -2
  18. package/crud/contentModel/beforeUpdate.js.map +1 -1
  19. package/crud/contentModel/createFieldStorageId.js +5 -1
  20. package/crud/contentModel/createFieldStorageId.js.map +1 -1
  21. package/crud/contentModel/models.js +12 -0
  22. package/crud/contentModel/models.js.map +1 -1
  23. package/crud/contentModel/validateModel.d.ts +3 -4
  24. package/crud/contentModel/validateModel.js +6 -3
  25. package/crud/contentModel/validateModel.js.map +1 -1
  26. package/crud/contentModel/validateModelFields.d.ts +3 -4
  27. package/crud/contentModel/validateModelFields.js +116 -39
  28. package/crud/contentModel/validateModelFields.js.map +1 -1
  29. package/crud/contentModel/validation.d.ts +477 -0
  30. package/crud/contentModel/validation.js +109 -0
  31. package/crud/contentModel/validation.js.map +1 -0
  32. package/crud/contentModel.crud.js +240 -188
  33. package/crud/contentModel.crud.js.map +1 -1
  34. package/crud/contentModelGroup/validation.d.ts +30 -0
  35. package/crud/contentModelGroup/validation.js +43 -0
  36. package/crud/contentModelGroup/validation.js.map +1 -0
  37. package/crud/contentModelGroup.crud.js +54 -54
  38. package/crud/contentModelGroup.crud.js.map +1 -1
  39. package/fieldConverters/CmsModelDynamicZoneFieldConverterPlugin.d.ts +11 -0
  40. package/fieldConverters/CmsModelDynamicZoneFieldConverterPlugin.js +239 -0
  41. package/fieldConverters/CmsModelDynamicZoneFieldConverterPlugin.js.map +1 -0
  42. package/fieldConverters/index.d.ts +2 -1
  43. package/fieldConverters/index.js +3 -1
  44. package/fieldConverters/index.js.map +1 -1
  45. package/graphql/buildSchemaPlugins.d.ts +8 -3
  46. package/graphql/buildSchemaPlugins.js +3 -6
  47. package/graphql/buildSchemaPlugins.js.map +1 -1
  48. package/graphql/createExecutableSchema.d.ts +7 -0
  49. package/graphql/createExecutableSchema.js +33 -0
  50. package/graphql/createExecutableSchema.js.map +1 -0
  51. package/graphql/generateSchema.d.ts +8 -0
  52. package/graphql/generateSchema.js +38 -0
  53. package/graphql/generateSchema.js.map +1 -0
  54. package/graphql/graphQLHandlerFactory.js +101 -57
  55. package/graphql/graphQLHandlerFactory.js.map +1 -1
  56. package/graphql/index.d.ts +1 -3
  57. package/graphql/index.js +2 -41
  58. package/graphql/index.js.map +1 -1
  59. package/graphql/schema/baseContentSchema.d.ts +6 -2
  60. package/graphql/schema/baseContentSchema.js +8 -6
  61. package/graphql/schema/baseContentSchema.js.map +1 -1
  62. package/graphql/schema/baseSchema.d.ts +3 -0
  63. package/graphql/schema/baseSchema.js +60 -0
  64. package/graphql/schema/baseSchema.js.map +1 -0
  65. package/graphql/schema/contentEntries.d.ts +6 -2
  66. package/graphql/schema/contentEntries.js +12 -6
  67. package/graphql/schema/contentEntries.js.map +1 -1
  68. package/graphql/schema/contentModelGroups.d.ts +6 -2
  69. package/graphql/schema/contentModelGroups.js +8 -4
  70. package/graphql/schema/contentModelGroups.js.map +1 -1
  71. package/graphql/schema/contentModels.d.ts +6 -2
  72. package/graphql/schema/contentModels.js +63 -5
  73. package/graphql/schema/contentModels.js.map +1 -1
  74. package/graphql/schema/createFieldResolvers.d.ts +1 -1
  75. package/graphql/schema/createFieldResolvers.js +23 -7
  76. package/graphql/schema/createFieldResolvers.js.map +1 -1
  77. package/graphql/schema/createManageSDL.d.ts +2 -0
  78. package/graphql/schema/createManageSDL.js +9 -6
  79. package/graphql/schema/createManageSDL.js.map +1 -1
  80. package/graphql/schema/createReadResolvers.js +5 -0
  81. package/graphql/schema/createReadResolvers.js.map +1 -1
  82. package/graphql/schema/createReadSDL.d.ts +2 -0
  83. package/graphql/schema/createReadSDL.js +11 -5
  84. package/graphql/schema/createReadSDL.js.map +1 -1
  85. package/graphql/schema/schemaPlugins.d.ts +8 -3
  86. package/graphql/schema/schemaPlugins.js +58 -50
  87. package/graphql/schema/schemaPlugins.js.map +1 -1
  88. package/graphql/system.js +79 -82
  89. package/graphql/system.js.map +1 -1
  90. package/graphqlFields/dynamicZone/dynamicZoneField.d.ts +2 -0
  91. package/graphqlFields/dynamicZone/dynamicZoneField.js +234 -0
  92. package/graphqlFields/dynamicZone/dynamicZoneField.js.map +1 -0
  93. package/graphqlFields/dynamicZone/dynamicZoneStorage.d.ts +3 -0
  94. package/graphqlFields/dynamicZone/dynamicZoneStorage.js +79 -0
  95. package/graphqlFields/dynamicZone/dynamicZoneStorage.js.map +1 -0
  96. package/graphqlFields/dynamicZone/index.d.ts +2 -0
  97. package/graphqlFields/dynamicZone/index.js +21 -0
  98. package/graphqlFields/dynamicZone/index.js.map +1 -0
  99. package/graphqlFields/index.d.ts +1 -1
  100. package/graphqlFields/index.js +3 -1
  101. package/graphqlFields/index.js.map +1 -1
  102. package/graphqlFields/number.js +4 -0
  103. package/graphqlFields/number.js.map +1 -1
  104. package/graphqlFields/object.js +122 -72
  105. package/graphqlFields/object.js.map +1 -1
  106. package/graphqlFields/ref.js +34 -48
  107. package/graphqlFields/ref.js.map +1 -1
  108. package/index.d.ts +3 -3
  109. package/index.js +4 -8
  110. package/index.js.map +1 -1
  111. package/package.json +26 -27
  112. package/plugins/CmsGraphQLSchemaPlugin.d.ts +5 -0
  113. package/plugins/CmsGraphQLSchemaPlugin.js +17 -0
  114. package/plugins/CmsGraphQLSchemaPlugin.js.map +1 -0
  115. package/plugins/CmsGraphQLSchemaSorterPlugin.d.ts +20 -0
  116. package/plugins/CmsGraphQLSchemaSorterPlugin.js +38 -0
  117. package/plugins/CmsGraphQLSchemaSorterPlugin.js.map +1 -0
  118. package/plugins/CmsModelFieldConverterPlugin.d.ts +2 -2
  119. package/plugins/CmsModelFieldConverterPlugin.js.map +1 -1
  120. package/plugins/StorageTransformPlugin.d.ts +11 -11
  121. package/plugins/StorageTransformPlugin.js.map +1 -1
  122. package/plugins/index.d.ts +2 -0
  123. package/plugins/index.js +26 -0
  124. package/plugins/index.js.map +1 -1
  125. package/storage/object.js +5 -2
  126. package/storage/object.js.map +1 -1
  127. package/types.d.ts +251 -57
  128. package/types.js +79 -7
  129. package/types.js.map +1 -1
  130. package/utils/converters/ConverterCollection.d.ts +7 -0
  131. package/utils/converters/ConverterCollection.js +32 -2
  132. package/utils/converters/ConverterCollection.js.map +1 -1
  133. package/utils/createTypeFromFields.d.ts +15 -0
  134. package/utils/createTypeFromFields.js +75 -0
  135. package/utils/createTypeFromFields.js.map +1 -0
  136. package/utils/createTypeName.js +3 -1
  137. package/utils/createTypeName.js.map +1 -1
  138. package/utils/entryStorage.js +15 -12
  139. package/utils/entryStorage.js.map +1 -1
  140. package/utils/getBaseFieldType.d.ts +4 -0
  141. package/utils/getBaseFieldType.js +12 -0
  142. package/utils/getBaseFieldType.js.map +1 -0
  143. package/utils/getSchemaFromFieldPlugins.d.ts +4 -7
  144. package/utils/getSchemaFromFieldPlugins.js +27 -14
  145. package/utils/getSchemaFromFieldPlugins.js.map +1 -1
  146. package/utils/renderFields.js +3 -1
  147. package/utils/renderFields.js.map +1 -1
  148. package/utils/renderGetFilterFields.js +8 -3
  149. package/utils/renderGetFilterFields.js.map +1 -1
  150. package/utils/renderInputFields.js +3 -1
  151. package/utils/renderInputFields.js.map +1 -1
  152. package/utils/renderListFilterFields.js +5 -2
  153. package/utils/renderListFilterFields.js.map +1 -1
  154. package/utils/renderSortEnum.d.ts +7 -4
  155. package/utils/renderSortEnum.js +23 -4
  156. package/utils/renderSortEnum.js.map +1 -1
  157. package/validators/dynamicZone.d.ts +2 -0
  158. package/validators/dynamicZone.js +24 -0
  159. package/validators/dynamicZone.js.map +1 -0
  160. package/validators/index.js +3 -1
  161. package/validators/index.js.map +1 -1
  162. package/crud/index.d.ts +0 -6
  163. package/crud/index.js +0 -85
  164. package/crud/index.js.map +0 -1
  165. package/graphql/schema/resolvers/manage/resolveRequestChanges.d.ts +0 -7
  166. package/graphql/schema/resolvers/manage/resolveRequestChanges.js +0 -21
  167. package/graphql/schema/resolvers/manage/resolveRequestChanges.js.map +0 -1
  168. package/graphql/schema/resolvers/manage/resolveRequestReview.d.ts +0 -7
  169. package/graphql/schema/resolvers/manage/resolveRequestReview.js +0 -21
  170. package/graphql/schema/resolvers/manage/resolveRequestReview.js.map +0 -1
  171. package/utils/filterModelFields.d.ts +0 -16
  172. package/utils/filterModelFields.js +0 -77
  173. package/utils/filterModelFields.js.map +0 -1
@@ -11,16 +11,12 @@ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/obje
11
11
 
12
12
  var _dataloader = _interopRequireDefault(require("dataloader"));
13
13
 
14
+ var _error = _interopRequireDefault(require("@webiny/error"));
15
+
14
16
  var _handlerGraphql = require("@webiny/handler-graphql");
15
17
 
16
18
  var _contentModelManagerFactory = require("./contentModel/contentModelManagerFactory");
17
19
 
18
- var _models = require("./contentModel/models");
19
-
20
- var _createFieldModels = require("./contentModel/createFieldModels");
21
-
22
- var _error = _interopRequireDefault(require("@webiny/error"));
23
-
24
20
  var _pubsub = require("@webiny/pubsub");
25
21
 
26
22
  var _beforeCreate = require("./contentModel/beforeCreate");
@@ -47,58 +43,23 @@ var _ownership = require("../utils/ownership");
47
43
 
48
44
  var _access = require("../utils/access");
49
45
 
50
- var _validateModelFields = require("./contentModel/validateModelFields");
46
+ var _validation = require("./contentModel/validation");
51
47
 
52
- var _semver = _interopRequireDefault(require("semver"));
48
+ var _utils = require("@webiny/utils");
53
49
 
54
50
  /**
55
- * TODO: remove for 5.34.0
56
- * Required because of the 5.33.0 upgrade.
57
- * Until the upgrade is done, API will break because there is no storageId assigned.
51
+ * Given a model, return an array of tags ensuring the `type` tag is set.
58
52
  */
59
- const featureVersion = _semver.default.coerce("5.33.0");
60
-
61
- const attachStorageIdToFields = fields => {
62
- return fields.map(field => {
63
- var _field$settings;
64
-
65
- if ((_field$settings = field.settings) !== null && _field$settings !== void 0 && _field$settings.fields) {
66
- field.settings.fields = attachStorageIdToFields(field.settings.fields);
67
- }
68
-
69
- if (!field.storageId) {
70
- field.storageId = field.fieldId;
71
- }
72
-
73
- return field;
74
- });
75
- };
76
-
77
- const attachStorageIdToModelFields = model => {
78
- if (!model.webinyVersion) {
79
- return model.fields;
80
- }
53
+ const ensureTypeTag = model => {
54
+ // Let's make sure we have a `type` tag assigned.
55
+ // If `type` tag is not set, set it to a default one (`model`).
56
+ const tags = model.tags || [];
81
57
 
82
- const version = _semver.default.coerce(model.webinyVersion);
83
-
84
- if (!version) {
85
- return model.fields;
86
- }
87
- /**
88
- * Unfortunately we need to check for beta and next.
89
- * TODO remove after 5.33.0
90
- */
91
-
92
-
93
- if (model.webinyVersion.match(/beta|next/)) {
94
- return attachStorageIdToFields(model.fields);
95
- }
96
-
97
- if (_semver.default.compare(version, featureVersion) >= 0) {
98
- return model.fields;
58
+ if (!tags.some(tag => tag.startsWith("type:"))) {
59
+ tags.push("type:model");
99
60
  }
100
61
 
101
- return attachStorageIdToFields(model.fields);
62
+ return tags;
102
63
  };
103
64
 
104
65
  const createModelsCrud = params => {
@@ -119,7 +80,7 @@ const createModelsCrud = params => {
119
80
  });
120
81
  return [models.map(model => {
121
82
  return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, model), {}, {
122
- fields: attachStorageIdToModelFields(model),
83
+ tags: ensureTypeTag(model),
123
84
  tenant: model.tenant || getTenant().id,
124
85
  locale: model.locale || getLocale().code
125
86
  });
@@ -150,43 +111,32 @@ const createModelsCrud = params => {
150
111
  const getModelsAsPlugins = () => {
151
112
  const tenant = getTenant().id;
152
113
  const locale = getLocale().code;
153
- const models = context.plugins.byType(_CmsModelPlugin.CmsModelPlugin.type)
114
+ return context.plugins.byType(_CmsModelPlugin.CmsModelPlugin.type)
154
115
  /**
155
116
  * We need to filter out models that are not for this tenant or locale.
156
117
  * If it does not have tenant or locale define, it is for every locale and tenant
157
118
  */
158
119
  .filter(plugin => {
159
120
  const {
160
- tenant: t,
161
- locale: l
121
+ tenant: modelTenant,
122
+ locale: modelLocale
162
123
  } = plugin.contentModel;
163
124
 
164
- if (t && t !== tenant) {
125
+ if (modelTenant && modelTenant !== tenant) {
165
126
  return false;
166
- } else if (l && l !== locale) {
127
+ } else if (modelLocale && modelLocale !== locale) {
167
128
  return false;
168
129
  }
169
130
 
170
131
  return true;
171
132
  }).map(plugin => {
172
133
  return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, plugin.contentModel), {}, {
134
+ tags: ensureTypeTag(plugin.contentModel),
173
135
  tenant,
174
136
  locale,
175
137
  webinyVersion: context.WEBINY_VERSION
176
138
  });
177
139
  });
178
- /**
179
- * Only point where we can truly validate the user model is in the runtime.
180
- */
181
-
182
- for (const model of models) {
183
- (0, _validateModelFields.validateModelFields)({
184
- model,
185
- plugins: context.plugins
186
- });
187
- }
188
-
189
- return models;
190
140
  };
191
141
 
192
142
  const modelsGet = async modelId => {
@@ -207,6 +157,7 @@ const createModelsCrud = params => {
207
157
  }
208
158
 
209
159
  return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, model), {}, {
160
+ tags: ensureTypeTag(model),
210
161
  tenant: model.tenant || getTenant().id,
211
162
  locale: model.locale || getLocale().code
212
163
  });
@@ -253,20 +204,41 @@ const createModelsCrud = params => {
253
204
  }
254
205
 
255
206
  return await updateManager(context, model);
256
- }; // create
207
+ };
208
+ /**
209
+ * Create
210
+ */
257
211
 
258
212
 
259
213
  const onModelBeforeCreate = (0, _pubsub.createTopic)("cms.onModelBeforeCreate");
260
- const onModelAfterCreate = (0, _pubsub.createTopic)("cms.onModelAfterCreate"); // create from
214
+ const onModelAfterCreate = (0, _pubsub.createTopic)("cms.onModelAfterCreate");
215
+ const onModelCreateError = (0, _pubsub.createTopic)("cms.onModelCreateError");
216
+ /**
217
+ * Create from / clone
218
+ */
261
219
 
262
220
  const onModelBeforeCreateFrom = (0, _pubsub.createTopic)("cms.onModelBeforeCreateFrom");
263
- const onModelAfterCreateFrom = (0, _pubsub.createTopic)("cms.onModelAfterCreateFrom"); // update
221
+ const onModelAfterCreateFrom = (0, _pubsub.createTopic)("cms.onModelAfterCreateFrom");
222
+ const onModelCreateFromError = (0, _pubsub.createTopic)("cms.onModelCreateFromError");
223
+ /**
224
+ * Update
225
+ */
264
226
 
265
227
  const onModelBeforeUpdate = (0, _pubsub.createTopic)("cms.onModelBeforeUpdate");
266
- const onModelAfterUpdate = (0, _pubsub.createTopic)("cms.onModelAfterUpdate"); // delete
228
+ const onModelAfterUpdate = (0, _pubsub.createTopic)("cms.onModelAfterUpdate");
229
+ const onModelUpdateError = (0, _pubsub.createTopic)("cms.onModelUpdateError");
230
+ /**
231
+ * Delete
232
+ */
267
233
 
268
234
  const onModelBeforeDelete = (0, _pubsub.createTopic)("cms.onModelBeforeDelete");
269
235
  const onModelAfterDelete = (0, _pubsub.createTopic)("cms.onModelAfterDelete");
236
+ const onModelDeleteError = (0, _pubsub.createTopic)("cms.onModelDeleteError");
237
+ /**
238
+ * Initialize
239
+ */
240
+
241
+ const onModelInitialize = (0, _pubsub.createTopic)("cms.onModelInitialize");
270
242
  /**
271
243
  * We need to assign some default behaviors.
272
244
  */
@@ -274,7 +246,7 @@ const createModelsCrud = params => {
274
246
  (0, _beforeCreate.assignModelBeforeCreate)({
275
247
  onModelBeforeCreate,
276
248
  onModelBeforeCreateFrom,
277
- plugins: context.plugins,
249
+ context,
278
250
  storageOperations
279
251
  });
280
252
  (0, _afterCreate.assignModelAfterCreate)({
@@ -283,8 +255,7 @@ const createModelsCrud = params => {
283
255
  });
284
256
  (0, _beforeUpdate.assignModelBeforeUpdate)({
285
257
  onModelBeforeUpdate,
286
- plugins: context.plugins,
287
- storageOperations
258
+ context
288
259
  });
289
260
  (0, _afterUpdate.assignModelAfterUpdate)({
290
261
  context,
@@ -321,35 +292,43 @@ const createModelsCrud = params => {
321
292
  */
322
293
  onModelBeforeCreate,
323
294
  onModelAfterCreate,
295
+ onModelCreateError,
324
296
  onModelBeforeCreateFrom,
325
297
  onModelAfterCreateFrom,
298
+ onModelCreateFromError,
326
299
  onModelBeforeUpdate,
327
300
  onModelAfterUpdate,
301
+ onModelUpdateError,
328
302
  onModelBeforeDelete,
329
303
  onModelAfterDelete,
304
+ onModelDeleteError,
305
+ onModelInitialize,
330
306
  clearModelsCache,
331
307
  getModel,
332
308
  listModels,
333
309
 
334
- async createModel(inputData) {
310
+ async createModel(input) {
335
311
  await checkModelPermissions("w");
336
- const createdData = new _models.CreateContentModelModel().populate(inputData);
337
- await createdData.validate();
338
- const input = await createdData.toJSON();
312
+ const result = await (0, _validation.createModelCreateValidation)().safeParseAsync(input);
313
+
314
+ if (!result.success) {
315
+ throw (0, _utils.createZodError)(result.error);
316
+ }
317
+
318
+ const data = result.data;
339
319
  context.security.disableAuthorization();
340
- const group = await context.cms.getGroup(input.group);
320
+ const group = await context.cms.getGroup(data.group);
341
321
  context.security.enableAuthorization();
342
322
 
343
323
  if (!group) {
344
- throw new _handlerGraphql.NotFoundError(`There is no group "${input.group}".`);
324
+ throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
345
325
  }
346
326
 
347
- const fields = await (0, _createFieldModels.createFieldModels)(input.fields);
348
327
  const identity = getIdentity();
349
328
  const model = {
350
- name: input.name,
351
- description: input.description || "",
352
- modelId: input.modelId || "",
329
+ name: data.name,
330
+ description: data.description || "",
331
+ modelId: data.modelId || "",
353
332
  titleFieldId: "id",
354
333
  locale: getLocale().code,
355
334
  tenant: getTenant().id,
@@ -364,25 +343,37 @@ const createModelsCrud = params => {
364
343
  },
365
344
  createdOn: new Date().toISOString(),
366
345
  savedOn: new Date().toISOString(),
367
- fields,
346
+ fields: data.fields,
368
347
  lockedFields: [],
369
- layout: input.layout || [],
348
+ layout: data.layout || [],
349
+ tags: [...(data.tags || [])],
370
350
  webinyVersion: context.WEBINY_VERSION
371
351
  };
372
- await onModelBeforeCreate.publish({
373
- input,
374
- model
375
- });
376
- const createdModel = await storageOperations.models.create({
377
- model
378
- });
379
- loaders.listModels.clearAll();
380
- await updateManager(context, model);
381
- await onModelAfterCreate.publish({
382
- input,
383
- model: createdModel
384
- });
385
- return createdModel;
352
+ model.tags = ensureTypeTag(model);
353
+
354
+ try {
355
+ await onModelBeforeCreate.publish({
356
+ input: data,
357
+ model
358
+ });
359
+ const createdModel = await storageOperations.models.create({
360
+ model
361
+ });
362
+ loaders.listModels.clearAll();
363
+ await updateManager(context, model);
364
+ await onModelAfterCreate.publish({
365
+ input: data,
366
+ model: createdModel
367
+ });
368
+ return createdModel;
369
+ } catch (ex) {
370
+ await onModelCreateError.publish({
371
+ input: data,
372
+ model,
373
+ error: ex
374
+ });
375
+ throw ex;
376
+ }
386
377
  },
387
378
 
388
379
  /**
@@ -399,44 +390,59 @@ const createModelsCrud = params => {
399
390
  locale: initialModel.locale || getLocale().code,
400
391
  webinyVersion: context.WEBINY_VERSION
401
392
  });
402
- await onModelBeforeUpdate.publish({
403
- input: {},
404
- original,
405
- model
406
- });
407
- const resultModel = await storageOperations.models.update({
408
- model
409
- });
410
- await updateManager(context, resultModel);
411
- loaders.listModels.clearAll();
412
- await onModelAfterUpdate.publish({
413
- input: {},
414
- original,
415
- model: resultModel
416
- });
417
- return resultModel;
393
+
394
+ try {
395
+ await onModelBeforeUpdate.publish({
396
+ input: {},
397
+ original,
398
+ model
399
+ });
400
+ const resultModel = await storageOperations.models.update({
401
+ model
402
+ });
403
+ await updateManager(context, resultModel);
404
+ loaders.listModels.clearAll();
405
+ await onModelAfterUpdate.publish({
406
+ input: {},
407
+ original,
408
+ model: resultModel
409
+ });
410
+ return resultModel;
411
+ } catch (ex) {
412
+ await onModelUpdateError.publish({
413
+ input: {},
414
+ original,
415
+ model,
416
+ error: ex
417
+ });
418
+ throw ex;
419
+ }
418
420
  },
419
421
 
420
- async createModelFrom(modelId, data) {
422
+ async createModelFrom(modelId, userInput) {
421
423
  await checkModelPermissions("w");
422
424
  /**
423
425
  * Get a model record; this will also perform ownership validation.
424
426
  */
425
427
 
426
428
  const original = await getModel(modelId);
427
- const createdData = new _models.CreateContentModelModelFrom().populate({
428
- name: data.name,
429
- modelId: data.modelId,
430
- description: data.description || original.description,
431
- group: data.group,
432
- locale: data.locale
429
+ const result = await (0, _validation.createModelCreateFromValidation)().safeParseAsync({
430
+ name: userInput.name,
431
+ modelId: userInput.modelId,
432
+ description: userInput.description || original.description,
433
+ group: userInput.group,
434
+ locale: userInput.locale
433
435
  });
434
- await createdData.validate();
435
- const input = await createdData.toJSON();
436
- const locale = await context.i18n.getLocale(input.locale || original.locale);
436
+
437
+ if (!result.success) {
438
+ throw (0, _utils.createZodError)(result.error);
439
+ }
440
+
441
+ const data = result.data;
442
+ const locale = await context.i18n.getLocale(data.locale || original.locale);
437
443
 
438
444
  if (!locale) {
439
- throw new _handlerGraphql.NotFoundError(`There is no locale "${input.locale}".`);
445
+ throw new _handlerGraphql.NotFoundError(`There is no locale "${data.locale}".`);
440
446
  }
441
447
  /**
442
448
  * Use storage operations directly because we cannot get group from different locale via context methods.
@@ -444,13 +450,13 @@ const createModelsCrud = params => {
444
450
 
445
451
 
446
452
  const group = await context.cms.storageOperations.groups.get({
447
- id: input.group,
453
+ id: data.group,
448
454
  tenant: original.tenant,
449
455
  locale: locale.code
450
456
  });
451
457
 
452
458
  if (!group) {
453
- throw new _handlerGraphql.NotFoundError(`There is no group "${input.group}".`);
459
+ throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
454
460
  }
455
461
 
456
462
  const identity = getIdentity();
@@ -460,9 +466,9 @@ const createModelsCrud = params => {
460
466
  id: group.id,
461
467
  name: group.name
462
468
  },
463
- name: input.name,
464
- modelId: input.modelId || "",
465
- description: input.description || "",
469
+ name: data.name,
470
+ modelId: data.modelId || "",
471
+ description: data.description || "",
466
472
  createdBy: {
467
473
  id: identity.id,
468
474
  displayName: identity.displayName,
@@ -473,35 +479,48 @@ const createModelsCrud = params => {
473
479
  lockedFields: [],
474
480
  webinyVersion: context.WEBINY_VERSION
475
481
  });
476
- await onModelBeforeCreateFrom.publish({
477
- input,
478
- model,
479
- original
480
- });
481
- const createdModel = await storageOperations.models.create({
482
- model
483
- });
484
- loaders.listModels.clearAll();
485
- await updateManager(context, model);
486
- await onModelAfterCreateFrom.publish({
487
- input,
488
- original,
489
- model: createdModel
490
- });
491
- return createdModel;
482
+
483
+ try {
484
+ await onModelBeforeCreateFrom.publish({
485
+ input: data,
486
+ model,
487
+ original
488
+ });
489
+ const createdModel = await storageOperations.models.create({
490
+ model
491
+ });
492
+ loaders.listModels.clearAll();
493
+ await updateManager(context, model);
494
+ await onModelAfterCreateFrom.publish({
495
+ input: data,
496
+ original,
497
+ model: createdModel
498
+ });
499
+ return createdModel;
500
+ } catch (ex) {
501
+ await onModelCreateFromError.publish({
502
+ input: data,
503
+ original,
504
+ model,
505
+ error: ex
506
+ });
507
+ throw ex;
508
+ }
492
509
  },
493
510
 
494
- async updateModel(modelId, inputData) {
511
+ async updateModel(modelId, input) {
495
512
  await checkModelPermissions("w"); // Get a model record; this will also perform ownership validation.
496
513
 
497
514
  const original = await getModel(modelId);
498
- const updatedData = new _models.UpdateContentModelModel().populate(inputData);
499
- await updatedData.validate();
500
- const input = await updatedData.toJSON({
501
- onlyDirty: true
502
- });
515
+ const result = await (0, _validation.createModelUpdateValidation)().safeParseAsync(input);
516
+
517
+ if (!result.success) {
518
+ throw (0, _utils.createZodError)(result.error);
519
+ }
503
520
 
504
- if (Object.keys(input).length === 0) {
521
+ const data = result.data;
522
+
523
+ if (Object.keys(data).length === 0) {
505
524
  /**
506
525
  * We need to return the original if nothing is to be updated.
507
526
  */
@@ -513,13 +532,13 @@ const createModelsCrud = params => {
513
532
  name: original.group.name
514
533
  };
515
534
 
516
- if (input.group) {
535
+ if (data.group) {
517
536
  context.security.disableAuthorization();
518
- const groupData = await context.cms.getGroup(input.group);
537
+ const groupData = await context.cms.getGroup(data.group);
519
538
  context.security.enableAuthorization();
520
539
 
521
540
  if (!groupData) {
522
- throw new _handlerGraphql.NotFoundError(`There is no group "${input.group}".`);
541
+ throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
523
542
  }
524
543
 
525
544
  group = {
@@ -528,54 +547,87 @@ const createModelsCrud = params => {
528
547
  };
529
548
  }
530
549
 
531
- const fields = await (0, _createFieldModels.createFieldModels)(inputData.fields);
532
- const model = (0, _objectSpread2.default)((0, _objectSpread2.default)((0, _objectSpread2.default)({}, original), input), {}, {
550
+ const model = (0, _objectSpread2.default)((0, _objectSpread2.default)((0, _objectSpread2.default)({}, original), data), {}, {
533
551
  group,
534
552
  tenant: original.tenant || getTenant().id,
535
553
  locale: original.locale || getLocale().code,
536
554
  webinyVersion: context.WEBINY_VERSION,
537
- fields,
538
555
  savedOn: new Date().toISOString()
539
556
  });
540
- await onModelBeforeUpdate.publish({
541
- input,
542
- original,
543
- model
544
- });
545
- const resultModel = await storageOperations.models.update({
546
- model
547
- });
548
- await updateManager(context, resultModel);
549
- await onModelAfterUpdate.publish({
550
- input,
551
- original,
552
- model: resultModel
553
- });
554
- return resultModel;
557
+ model.tags = ensureTypeTag(model);
558
+
559
+ try {
560
+ await onModelBeforeUpdate.publish({
561
+ input: data,
562
+ original,
563
+ model
564
+ });
565
+ const resultModel = await storageOperations.models.update({
566
+ model
567
+ });
568
+ await updateManager(context, resultModel);
569
+ await onModelAfterUpdate.publish({
570
+ input: data,
571
+ original,
572
+ model: resultModel
573
+ });
574
+ return resultModel;
575
+ } catch (ex) {
576
+ await onModelUpdateError.publish({
577
+ input: data,
578
+ model,
579
+ original,
580
+ error: ex
581
+ });
582
+ throw ex;
583
+ }
555
584
  },
556
585
 
557
586
  async deleteModel(modelId) {
558
587
  await checkModelPermissions("d");
559
588
  const model = await getModel(modelId);
560
- await onModelBeforeDelete.publish({
561
- model
562
- });
563
589
 
564
590
  try {
565
- await storageOperations.models.delete({
591
+ await onModelBeforeDelete.publish({
592
+ model
593
+ });
594
+
595
+ try {
596
+ await storageOperations.models.delete({
597
+ model
598
+ });
599
+ } catch (ex) {
600
+ throw new _error.default(ex.message || "Could not delete the content model", ex.code || "CONTENT_MODEL_DELETE_ERROR", {
601
+ error: ex,
602
+ modelId: model.modelId
603
+ });
604
+ }
605
+
606
+ await onModelAfterDelete.publish({
566
607
  model
567
608
  });
609
+ managers.delete(model.modelId);
568
610
  } catch (ex) {
569
- throw new _error.default(ex.message || "Could not delete the content model", ex.code || "CONTENT_MODEL_DELETE_ERROR", {
570
- error: ex,
571
- modelId: model.modelId
611
+ await onModelDeleteError.publish({
612
+ model,
613
+ error: ex
572
614
  });
615
+ throw ex;
573
616
  }
617
+ },
574
618
 
575
- await onModelAfterDelete.publish({
576
- model
619
+ async initializeModel(modelId, data) {
620
+ /**
621
+ * We require that users have write permissions to initialize models.
622
+ * Maybe introduce another permission for it?
623
+ */
624
+ await checkModelPermissions("w");
625
+ const model = await getModel(modelId);
626
+ await onModelInitialize.publish({
627
+ model,
628
+ data
577
629
  });
578
- managers.delete(model.modelId);
630
+ return true;
579
631
  },
580
632
 
581
633
  getModelManager,