@webiny/api-headless-cms 0.0.0-unstable.b02d94bba0 → 0.0.0-unstable.b14eaecf38
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.crud.d.ts +3 -1
- package/crud/contentEntry.crud.js +829 -817
- 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 +48 -16
- package/crud/contentModel/validation.js +2 -2
- package/crud/contentModel/validation.js.map +1 -1
- package/crud/contentModel.crud.js +334 -295
- package/crud/contentModel.crud.js.map +1 -1
- 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/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/graphqlFields/dynamicZone/dynamicZoneField.d.ts +1 -1
- package/graphqlFields/dynamicZone/dynamicZoneField.js +13 -1
- package/graphqlFields/dynamicZone/dynamicZoneField.js.map +1 -1
- package/graphqlFields/ref.js +7 -7
- package/graphqlFields/ref.js.map +1 -1
- package/index.d.ts +2 -0
- package/index.js +24 -0
- package/index.js.map +1 -1
- package/package.json +22 -22
- package/plugins/CmsModelPlugin.d.ts +13 -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 +46 -47
- 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
|
@@ -140,21 +140,25 @@ const createModelsCrud = params => {
|
|
|
140
140
|
return databaseModels.concat(pluginsModels);
|
|
141
141
|
};
|
|
142
142
|
const listModels = async () => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
+
});
|
|
150
152
|
});
|
|
151
153
|
};
|
|
152
154
|
const getModel = async modelId => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
+
});
|
|
158
162
|
};
|
|
159
163
|
const getModelManager = async target => {
|
|
160
164
|
const modelId = typeof target === "string" ? target : target.modelId;
|
|
@@ -231,6 +235,311 @@ const createModelsCrud = params => {
|
|
|
231
235
|
context,
|
|
232
236
|
onModelAfterDelete
|
|
233
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
|
+
};
|
|
234
543
|
return {
|
|
235
544
|
/**
|
|
236
545
|
* Deprecated - will be removed in 5.36.0
|
|
@@ -263,308 +572,38 @@ const createModelsCrud = params => {
|
|
|
263
572
|
getModel,
|
|
264
573
|
listModels,
|
|
265
574
|
async createModel(input) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if (!result.success) {
|
|
269
|
-
throw (0, _utils.createZodError)(result.error);
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* We need to extract the defaultFields because it is not for the CmsModel object.
|
|
273
|
-
*/
|
|
274
|
-
const _removeUndefinedValue = (0, _utils.removeUndefinedValues)(result.data),
|
|
275
|
-
{
|
|
276
|
-
defaultFields
|
|
277
|
-
} = _removeUndefinedValue,
|
|
278
|
-
data = (0, _objectWithoutProperties2.default)(_removeUndefinedValue, _excluded);
|
|
279
|
-
if (defaultFields) {
|
|
280
|
-
(0, _defaultFields.assignModelDefaultFields)(data);
|
|
281
|
-
}
|
|
282
|
-
context.security.disableAuthorization();
|
|
283
|
-
const group = await context.cms.getGroup(data.group);
|
|
284
|
-
context.security.enableAuthorization();
|
|
285
|
-
if (!group) {
|
|
286
|
-
throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
|
|
287
|
-
}
|
|
288
|
-
const identity = getIdentity();
|
|
289
|
-
const model = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, data), {}, {
|
|
290
|
-
modelId: data.modelId || "",
|
|
291
|
-
singularApiName: data.singularApiName,
|
|
292
|
-
pluralApiName: data.pluralApiName,
|
|
293
|
-
titleFieldId: "id",
|
|
294
|
-
descriptionFieldId: null,
|
|
295
|
-
imageFieldId: null,
|
|
296
|
-
description: data.description || "",
|
|
297
|
-
locale: getLocale().code,
|
|
298
|
-
tenant: getTenant().id,
|
|
299
|
-
group: {
|
|
300
|
-
id: group.id,
|
|
301
|
-
name: group.name
|
|
302
|
-
},
|
|
303
|
-
createdBy: {
|
|
304
|
-
id: identity.id,
|
|
305
|
-
displayName: identity.displayName,
|
|
306
|
-
type: identity.type
|
|
307
|
-
},
|
|
308
|
-
createdOn: new Date().toISOString(),
|
|
309
|
-
savedOn: new Date().toISOString(),
|
|
310
|
-
lockedFields: [],
|
|
311
|
-
webinyVersion: context.WEBINY_VERSION
|
|
575
|
+
return context.benchmark.measure("headlessCms.crud.models.createModel", async () => {
|
|
576
|
+
return createModel(input);
|
|
312
577
|
});
|
|
313
|
-
model.tags = ensureTypeTag(model);
|
|
314
|
-
try {
|
|
315
|
-
await onModelBeforeCreate.publish({
|
|
316
|
-
input: data,
|
|
317
|
-
model
|
|
318
|
-
});
|
|
319
|
-
const createdModel = await storageOperations.models.create({
|
|
320
|
-
model
|
|
321
|
-
});
|
|
322
|
-
loaders.listModels.clearAll();
|
|
323
|
-
await updateManager(context, model);
|
|
324
|
-
await onModelAfterCreate.publish({
|
|
325
|
-
input: data,
|
|
326
|
-
model: createdModel
|
|
327
|
-
});
|
|
328
|
-
return createdModel;
|
|
329
|
-
} catch (ex) {
|
|
330
|
-
await onModelCreateError.publish({
|
|
331
|
-
input: data,
|
|
332
|
-
model,
|
|
333
|
-
error: ex
|
|
334
|
-
});
|
|
335
|
-
throw ex;
|
|
336
|
-
}
|
|
337
578
|
},
|
|
338
579
|
/**
|
|
339
580
|
* Method does not check for permissions or ownership.
|
|
340
581
|
* @internal
|
|
341
582
|
*/
|
|
342
583
|
async updateModelDirect(params) {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
original
|
|
346
|
-
} = params;
|
|
347
|
-
const model = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, initialModel), {}, {
|
|
348
|
-
tenant: initialModel.tenant || getTenant().id,
|
|
349
|
-
locale: initialModel.locale || getLocale().code,
|
|
350
|
-
webinyVersion: context.WEBINY_VERSION
|
|
584
|
+
return context.benchmark.measure("headlessCms.crud.models.updateModelDirect", async () => {
|
|
585
|
+
return updateModelDirect(params);
|
|
351
586
|
});
|
|
352
|
-
try {
|
|
353
|
-
await onModelBeforeUpdate.publish({
|
|
354
|
-
input: {},
|
|
355
|
-
original,
|
|
356
|
-
model
|
|
357
|
-
});
|
|
358
|
-
const resultModel = await storageOperations.models.update({
|
|
359
|
-
model
|
|
360
|
-
});
|
|
361
|
-
await updateManager(context, resultModel);
|
|
362
|
-
loaders.listModels.clearAll();
|
|
363
|
-
await onModelAfterUpdate.publish({
|
|
364
|
-
input: {},
|
|
365
|
-
original,
|
|
366
|
-
model: resultModel
|
|
367
|
-
});
|
|
368
|
-
return resultModel;
|
|
369
|
-
} catch (ex) {
|
|
370
|
-
await onModelUpdateError.publish({
|
|
371
|
-
input: {},
|
|
372
|
-
original,
|
|
373
|
-
model,
|
|
374
|
-
error: ex
|
|
375
|
-
});
|
|
376
|
-
throw ex;
|
|
377
|
-
}
|
|
378
587
|
},
|
|
379
588
|
async createModelFrom(modelId, userInput) {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
* Get a model record; this will also perform ownership validation.
|
|
383
|
-
*/
|
|
384
|
-
const original = await getModel(modelId);
|
|
385
|
-
const result = await (0, _validation.createModelCreateFromValidation)().safeParseAsync((0, _objectSpread2.default)((0, _objectSpread2.default)({}, userInput), {}, {
|
|
386
|
-
description: userInput.description || original.description
|
|
387
|
-
}));
|
|
388
|
-
if (!result.success) {
|
|
389
|
-
throw (0, _utils.createZodError)(result.error);
|
|
390
|
-
}
|
|
391
|
-
const data = (0, _utils.removeUndefinedValues)(result.data);
|
|
392
|
-
const locale = await context.i18n.getLocale(data.locale || original.locale);
|
|
393
|
-
if (!locale) {
|
|
394
|
-
throw new _handlerGraphql.NotFoundError(`There is no locale "${data.locale}".`);
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Use storage operations directly because we cannot get group from different locale via context methods.
|
|
398
|
-
*/
|
|
399
|
-
const group = await context.cms.storageOperations.groups.get({
|
|
400
|
-
id: data.group,
|
|
401
|
-
tenant: original.tenant,
|
|
402
|
-
locale: locale.code
|
|
403
|
-
});
|
|
404
|
-
if (!group) {
|
|
405
|
-
throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
|
|
406
|
-
}
|
|
407
|
-
const identity = getIdentity();
|
|
408
|
-
const model = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, original), {}, {
|
|
409
|
-
singularApiName: data.singularApiName,
|
|
410
|
-
pluralApiName: data.pluralApiName,
|
|
411
|
-
locale: locale.code,
|
|
412
|
-
group: {
|
|
413
|
-
id: group.id,
|
|
414
|
-
name: group.name
|
|
415
|
-
},
|
|
416
|
-
icon: data.icon,
|
|
417
|
-
name: data.name,
|
|
418
|
-
modelId: data.modelId || "",
|
|
419
|
-
description: data.description || "",
|
|
420
|
-
createdBy: {
|
|
421
|
-
id: identity.id,
|
|
422
|
-
displayName: identity.displayName,
|
|
423
|
-
type: identity.type
|
|
424
|
-
},
|
|
425
|
-
createdOn: new Date().toISOString(),
|
|
426
|
-
savedOn: new Date().toISOString(),
|
|
427
|
-
lockedFields: [],
|
|
428
|
-
webinyVersion: context.WEBINY_VERSION
|
|
589
|
+
return context.benchmark.measure("headlessCms.crud.models.createModelFrom", async () => {
|
|
590
|
+
return createModelFrom(modelId, userInput);
|
|
429
591
|
});
|
|
430
|
-
try {
|
|
431
|
-
await onModelBeforeCreateFrom.publish({
|
|
432
|
-
input: data,
|
|
433
|
-
model,
|
|
434
|
-
original
|
|
435
|
-
});
|
|
436
|
-
const createdModel = await storageOperations.models.create({
|
|
437
|
-
model
|
|
438
|
-
});
|
|
439
|
-
loaders.listModels.clearAll();
|
|
440
|
-
await updateManager(context, model);
|
|
441
|
-
await onModelAfterCreateFrom.publish({
|
|
442
|
-
input: data,
|
|
443
|
-
original,
|
|
444
|
-
model: createdModel
|
|
445
|
-
});
|
|
446
|
-
return createdModel;
|
|
447
|
-
} catch (ex) {
|
|
448
|
-
await onModelCreateFromError.publish({
|
|
449
|
-
input: data,
|
|
450
|
-
original,
|
|
451
|
-
model,
|
|
452
|
-
error: ex
|
|
453
|
-
});
|
|
454
|
-
throw ex;
|
|
455
|
-
}
|
|
456
592
|
},
|
|
457
593
|
async updateModel(modelId, input) {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
// Get a model record; this will also perform ownership validation.
|
|
461
|
-
const original = await getModel(modelId);
|
|
462
|
-
const result = await (0, _validation.createModelUpdateValidation)().safeParseAsync(input);
|
|
463
|
-
if (!result.success) {
|
|
464
|
-
throw (0, _utils.createZodError)(result.error);
|
|
465
|
-
}
|
|
466
|
-
const data = (0, _utils.removeUndefinedValues)(result.data);
|
|
467
|
-
if (Object.keys(data).length === 0) {
|
|
468
|
-
/**
|
|
469
|
-
* We need to return the original if nothing is to be updated.
|
|
470
|
-
*/
|
|
471
|
-
return original;
|
|
472
|
-
}
|
|
473
|
-
let group = {
|
|
474
|
-
id: original.group.id,
|
|
475
|
-
name: original.group.name
|
|
476
|
-
};
|
|
477
|
-
if (data.group) {
|
|
478
|
-
context.security.disableAuthorization();
|
|
479
|
-
const groupData = await context.cms.getGroup(data.group);
|
|
480
|
-
context.security.enableAuthorization();
|
|
481
|
-
if (!groupData) {
|
|
482
|
-
throw new _handlerGraphql.NotFoundError(`There is no group "${data.group}".`);
|
|
483
|
-
}
|
|
484
|
-
group = {
|
|
485
|
-
id: groupData.id,
|
|
486
|
-
name: groupData.name
|
|
487
|
-
};
|
|
488
|
-
}
|
|
489
|
-
const model = (0, _objectSpread2.default)((0, _objectSpread2.default)((0, _objectSpread2.default)({}, original), data), {}, {
|
|
490
|
-
titleFieldId: data.titleFieldId === undefined ? original.titleFieldId : data.titleFieldId,
|
|
491
|
-
descriptionFieldId: data.descriptionFieldId === undefined ? original.descriptionFieldId : data.descriptionFieldId,
|
|
492
|
-
imageFieldId: data.imageFieldId === undefined ? original.imageFieldId : data.imageFieldId,
|
|
493
|
-
group,
|
|
494
|
-
description: data.description || original.description,
|
|
495
|
-
tenant: original.tenant || getTenant().id,
|
|
496
|
-
locale: original.locale || getLocale().code,
|
|
497
|
-
webinyVersion: context.WEBINY_VERSION,
|
|
498
|
-
savedOn: new Date().toISOString()
|
|
594
|
+
return context.benchmark.measure("headlessCms.crud.models.updateModel", async () => {
|
|
595
|
+
return updateModel(modelId, input);
|
|
499
596
|
});
|
|
500
|
-
model.tags = ensureTypeTag(model);
|
|
501
|
-
try {
|
|
502
|
-
await onModelBeforeUpdate.publish({
|
|
503
|
-
input: data,
|
|
504
|
-
original,
|
|
505
|
-
model
|
|
506
|
-
});
|
|
507
|
-
const resultModel = await storageOperations.models.update({
|
|
508
|
-
model
|
|
509
|
-
});
|
|
510
|
-
await updateManager(context, resultModel);
|
|
511
|
-
await onModelAfterUpdate.publish({
|
|
512
|
-
input: data,
|
|
513
|
-
original,
|
|
514
|
-
model: resultModel
|
|
515
|
-
});
|
|
516
|
-
return resultModel;
|
|
517
|
-
} catch (ex) {
|
|
518
|
-
await onModelUpdateError.publish({
|
|
519
|
-
input: data,
|
|
520
|
-
model,
|
|
521
|
-
original,
|
|
522
|
-
error: ex
|
|
523
|
-
});
|
|
524
|
-
throw ex;
|
|
525
|
-
}
|
|
526
597
|
},
|
|
527
598
|
async deleteModel(modelId) {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
await onModelBeforeDelete.publish({
|
|
532
|
-
model
|
|
533
|
-
});
|
|
534
|
-
try {
|
|
535
|
-
await storageOperations.models.delete({
|
|
536
|
-
model
|
|
537
|
-
});
|
|
538
|
-
} catch (ex) {
|
|
539
|
-
throw new _error.default(ex.message || "Could not delete the content model", ex.code || "CONTENT_MODEL_DELETE_ERROR", {
|
|
540
|
-
error: ex,
|
|
541
|
-
modelId: model.modelId
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
await onModelAfterDelete.publish({
|
|
545
|
-
model
|
|
546
|
-
});
|
|
547
|
-
managers.delete(model.modelId);
|
|
548
|
-
} catch (ex) {
|
|
549
|
-
await onModelDeleteError.publish({
|
|
550
|
-
model,
|
|
551
|
-
error: ex
|
|
552
|
-
});
|
|
553
|
-
throw ex;
|
|
554
|
-
}
|
|
599
|
+
return context.benchmark.measure("headlessCms.crud.models.deleteModel", async () => {
|
|
600
|
+
return deleteModel(modelId);
|
|
601
|
+
});
|
|
555
602
|
},
|
|
556
603
|
async initializeModel(modelId, data) {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
* Maybe introduce another permission for it?
|
|
560
|
-
*/
|
|
561
|
-
await checkModelPermissions("w");
|
|
562
|
-
const model = await getModel(modelId);
|
|
563
|
-
await onModelInitialize.publish({
|
|
564
|
-
model,
|
|
565
|
-
data
|
|
604
|
+
return context.benchmark.measure("headlessCms.crud.models.initializeModel", async () => {
|
|
605
|
+
return initializeModel(modelId, data);
|
|
566
606
|
});
|
|
567
|
-
return true;
|
|
568
607
|
},
|
|
569
608
|
getModelManager,
|
|
570
609
|
getEntryManager: async model => {
|