@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.
- package/context.js +47 -43
- 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 +6 -4
- package/crud/contentEntry.crud.js +896 -821
- package/crud/contentEntry.crud.js.map +1 -1
- package/crud/contentModel/beforeCreate.js +38 -79
- package/crud/contentModel/beforeCreate.js.map +1 -1
- package/crud/contentModel/beforeDelete.d.ts +1 -1
- package/crud/contentModel/beforeDelete.js +1 -5
- package/crud/contentModel/beforeDelete.js.map +1 -1
- package/crud/contentModel/beforeUpdate.js +30 -6
- package/crud/contentModel/beforeUpdate.js.map +1 -1
- package/crud/contentModel/validate/endingAllowed.d.ts +6 -0
- package/crud/contentModel/validate/endingAllowed.js +26 -0
- package/crud/contentModel/validate/endingAllowed.js.map +1 -0
- package/crud/contentModel/validate/isModelEndingAllowed.d.ts +6 -0
- package/crud/contentModel/validate/isModelEndingAllowed.js +24 -0
- package/crud/contentModel/validate/isModelEndingAllowed.js.map +1 -0
- package/crud/contentModel/validate/modelId.d.ts +11 -0
- package/crud/contentModel/validate/modelId.js +36 -0
- package/crud/contentModel/validate/modelId.js.map +1 -0
- package/crud/contentModel/validate/pluralApiName.d.ts +7 -0
- package/crud/contentModel/validate/pluralApiName.js +24 -0
- package/crud/contentModel/validate/pluralApiName.js.map +1 -0
- package/crud/contentModel/validate/singularApiName.d.ts +7 -0
- package/crud/contentModel/validate/singularApiName.js +24 -0
- package/crud/contentModel/validate/singularApiName.js.map +1 -0
- package/crud/contentModel/validateModelFields.js +6 -7
- package/crud/contentModel/validateModelFields.js.map +1 -1
- package/crud/contentModel/validation.d.ts +127 -95
- package/crud/contentModel/validation.js +4 -4
- package/crud/contentModel/validation.js.map +1 -1
- package/crud/contentModel.crud.js +334 -296
- package/crud/contentModel.crud.js.map +1 -1
- package/crud/contentModelGroup/validation.d.ts +4 -4
- package/crud/contentModelGroup.crud.js +170 -142
- package/crud/contentModelGroup.crud.js.map +1 -1
- package/crud/settings.crud.d.ts +1 -1
- package/crud/settings.crud.js +5 -10
- package/crud/settings.crud.js.map +1 -1
- package/graphql/checkEndpointAccess.d.ts +2 -0
- package/graphql/checkEndpointAccess.js +18 -0
- package/graphql/checkEndpointAccess.js.map +1 -0
- package/graphql/createExecutableSchema.d.ts +2 -3
- package/graphql/createExecutableSchema.js.map +1 -1
- package/graphql/createRequestBody.d.ts +2 -0
- package/graphql/createRequestBody.js +14 -0
- package/graphql/createRequestBody.js.map +1 -0
- package/graphql/formatErrorPayload.d.ts +1 -0
- package/graphql/formatErrorPayload.js +25 -0
- package/graphql/formatErrorPayload.js.map +1 -0
- package/graphql/generateSchema.js.map +1 -1
- package/graphql/getSchema.d.ts +17 -0
- package/graphql/getSchema.js +102 -0
- package/graphql/getSchema.js.map +1 -0
- package/graphql/graphQLHandlerFactory.js +6 -150
- package/graphql/graphQLHandlerFactory.js.map +1 -1
- package/graphql/handleRequest.d.ts +11 -0
- package/graphql/handleRequest.js +81 -0
- package/graphql/handleRequest.js.map +1 -0
- package/graphql/index.d.ts +1 -1
- package/graphql/schema/contentModelGroups.js +6 -6
- package/graphql/schema/contentModelGroups.js.map +1 -1
- package/graphql/schema/contentModels.js +3 -3
- package/graphql/schema/contentModels.js.map +1 -1
- package/graphql/schema/createFieldResolvers.js +2 -1
- package/graphql/schema/createFieldResolvers.js.map +1 -1
- package/graphql/schema/createManageResolvers.js +6 -0
- package/graphql/schema/createManageResolvers.js.map +1 -1
- 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/graphqlFields/dynamicZone/dynamicZoneField.d.ts +1 -1
- package/graphqlFields/dynamicZone/dynamicZoneField.js +44 -17
- package/graphqlFields/dynamicZone/dynamicZoneField.js.map +1 -1
- package/graphqlFields/object.js +14 -1
- package/graphqlFields/object.js.map +1 -1
- package/graphqlFields/ref.js +7 -7
- package/graphqlFields/ref.js.map +1 -1
- package/index.d.ts +3 -1
- package/index.js +24 -0
- package/index.js.map +1 -1
- package/package.json +22 -22
- package/plugins/CmsModelPlugin.d.ts +15 -7
- package/plugins/CmsModelPlugin.js +21 -6
- package/plugins/CmsModelPlugin.js.map +1 -1
- package/plugins/StorageOperationsCmsModelPlugin.d.ts +23 -0
- package/plugins/StorageOperationsCmsModelPlugin.js +42 -0
- package/plugins/StorageOperationsCmsModelPlugin.js.map +1 -0
- package/plugins/index.d.ts +1 -0
- package/plugins/index.js +11 -0
- package/plugins/index.js.map +1 -1
- package/types.d.ts +72 -48
- package/types.js +4 -0
- package/types.js.map +1 -1
- package/utils/converters/valueKeyStorageConverter.d.ts +1 -5
- package/utils/converters/valueKeyStorageConverter.js +19 -17
- package/utils/converters/valueKeyStorageConverter.js.map +1 -1
- package/utils/createTypeFromFields.js +1 -2
- package/utils/createTypeFromFields.js.map +1 -1
- package/utils/createTypeName.d.ts +0 -2
- package/utils/createTypeName.js +2 -10
- package/utils/createTypeName.js.map +1 -1
- package/utils/incrementEntryIdVersion.d.ts +5 -0
- package/utils/incrementEntryIdVersion.js +29 -0
- package/utils/incrementEntryIdVersion.js.map +1 -0
- 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/pluralizedTypeName.d.ts +0 -1
- package/utils/pluralizedTypeName.js +0 -26
- package/utils/pluralizedTypeName.js.map +0 -1
- package/utils/removeNullValues.d.ts +0 -1
- package/utils/removeNullValues.js +0 -17
- package/utils/removeNullValues.js.map +0 -1
- package/utils/removeUndefinedValues.d.ts +0 -1
- package/utils/removeUndefinedValues.js +0 -17
- 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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
268
|
-
|
|
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
|
-
|
|
345
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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
|
-
|
|
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 => {
|