@webiny/api-headless-cms 0.0.0-unstable.9f53ea597d → 0.0.0-unstable.a4f3e4ea8b

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 (175) hide show
  1. package/crud/contentEntry.crud.js +12 -39
  2. package/crud/contentEntry.crud.js.map +1 -1
  3. package/features/contentEntry/ContentEntriesFeature.js +4 -0
  4. package/features/contentEntry/ContentEntriesFeature.js.map +1 -1
  5. package/features/contentEntry/CreateEntry/CreateEntryRepository.d.ts +4 -2
  6. package/features/contentEntry/CreateEntry/CreateEntryRepository.js +8 -3
  7. package/features/contentEntry/CreateEntry/CreateEntryRepository.js.map +1 -1
  8. package/features/contentEntry/CreateEntry/CreateEntryUseCase.js +1 -2
  9. package/features/contentEntry/CreateEntry/CreateEntryUseCase.js.map +1 -1
  10. package/features/contentEntry/CreateEntryRevisionFrom/CreateEntryRevisionFromRepository.d.ts +4 -2
  11. package/features/contentEntry/CreateEntryRevisionFrom/CreateEntryRevisionFromRepository.js +8 -3
  12. package/features/contentEntry/CreateEntryRevisionFrom/CreateEntryRevisionFromRepository.js.map +1 -1
  13. package/features/contentEntry/CreateEntryRevisionFrom/CreateEntryRevisionFromUseCase.js.map +1 -1
  14. package/features/contentEntry/DeleteEntry/DeleteEntryRepository.d.ts +4 -2
  15. package/features/contentEntry/DeleteEntry/DeleteEntryRepository.js +8 -3
  16. package/features/contentEntry/DeleteEntry/DeleteEntryRepository.js.map +1 -1
  17. package/features/contentEntry/DeleteEntry/MoveEntryToBinRepository.d.ts +3 -1
  18. package/features/contentEntry/DeleteEntry/MoveEntryToBinRepository.js +8 -3
  19. package/features/contentEntry/DeleteEntry/MoveEntryToBinRepository.js.map +1 -1
  20. package/features/contentEntry/DeleteEntryRevision/DeleteEntryRevisionRepository.d.ts +3 -1
  21. package/features/contentEntry/DeleteEntryRevision/DeleteEntryRevisionRepository.js +9 -3
  22. package/features/contentEntry/DeleteEntryRevision/DeleteEntryRevisionRepository.js.map +1 -1
  23. package/features/contentEntry/DeleteMultipleEntries/DeleteMultipleEntriesRepository.d.ts +4 -2
  24. package/features/contentEntry/DeleteMultipleEntries/DeleteMultipleEntriesRepository.js +7 -3
  25. package/features/contentEntry/DeleteMultipleEntries/DeleteMultipleEntriesRepository.js.map +1 -1
  26. package/features/contentEntry/GetEntriesByIds/GetEntriesByIdsRepository.d.ts +4 -4
  27. package/features/contentEntry/GetEntriesByIds/GetEntriesByIdsRepository.js +8 -11
  28. package/features/contentEntry/GetEntriesByIds/GetEntriesByIdsRepository.js.map +1 -1
  29. package/features/contentEntry/GetLatestEntriesByIds/GetLatestEntriesByIdsRepository.d.ts +4 -2
  30. package/features/contentEntry/GetLatestEntriesByIds/GetLatestEntriesByIdsRepository.js +7 -3
  31. package/features/contentEntry/GetLatestEntriesByIds/GetLatestEntriesByIdsRepository.js.map +1 -1
  32. package/features/contentEntry/GetLatestRevisionByEntryId/GetLatestRevisionByEntryIdRepository.d.ts +4 -2
  33. package/features/contentEntry/GetLatestRevisionByEntryId/GetLatestRevisionByEntryIdRepository.js +7 -3
  34. package/features/contentEntry/GetLatestRevisionByEntryId/GetLatestRevisionByEntryIdRepository.js.map +1 -1
  35. package/features/contentEntry/GetPreviousRevisionByEntryId/GetPreviousRevisionByEntryIdRepository.d.ts +4 -2
  36. package/features/contentEntry/GetPreviousRevisionByEntryId/GetPreviousRevisionByEntryIdRepository.js +7 -3
  37. package/features/contentEntry/GetPreviousRevisionByEntryId/GetPreviousRevisionByEntryIdRepository.js.map +1 -1
  38. package/features/contentEntry/GetPublishedEntriesByIds/GetPublishedEntriesByIdsRepository.d.ts +4 -2
  39. package/features/contentEntry/GetPublishedEntriesByIds/GetPublishedEntriesByIdsRepository.js +7 -3
  40. package/features/contentEntry/GetPublishedEntriesByIds/GetPublishedEntriesByIdsRepository.js.map +1 -1
  41. package/features/contentEntry/GetPublishedRevisionByEntryId/GetPublishedRevisionByEntryIdRepository.d.ts +4 -2
  42. package/features/contentEntry/GetPublishedRevisionByEntryId/GetPublishedRevisionByEntryIdRepository.js +7 -3
  43. package/features/contentEntry/GetPublishedRevisionByEntryId/GetPublishedRevisionByEntryIdRepository.js.map +1 -1
  44. package/features/contentEntry/GetRevisionById/GetRevisionByIdRepository.d.ts +4 -2
  45. package/features/contentEntry/GetRevisionById/GetRevisionByIdRepository.js +7 -3
  46. package/features/contentEntry/GetRevisionById/GetRevisionByIdRepository.js.map +1 -1
  47. package/features/contentEntry/GetRevisionsByEntryId/GetRevisionsByEntryIdRepository.d.ts +4 -2
  48. package/features/contentEntry/GetRevisionsByEntryId/GetRevisionsByEntryIdRepository.js +7 -3
  49. package/features/contentEntry/GetRevisionsByEntryId/GetRevisionsByEntryIdRepository.js.map +1 -1
  50. package/features/contentEntry/GetUniqueFieldValues/GetUniqueFieldValuesRepository.d.ts +4 -2
  51. package/features/contentEntry/GetUniqueFieldValues/GetUniqueFieldValuesRepository.js +7 -3
  52. package/features/contentEntry/GetUniqueFieldValues/GetUniqueFieldValuesRepository.js.map +1 -1
  53. package/features/contentEntry/ListEntries/ListEntriesRepository.d.ts +4 -2
  54. package/features/contentEntry/ListEntries/ListEntriesRepository.js +7 -3
  55. package/features/contentEntry/ListEntries/ListEntriesRepository.js.map +1 -1
  56. package/features/contentEntry/MoveEntry/MoveEntryRepository.d.ts +4 -2
  57. package/features/contentEntry/MoveEntry/MoveEntryRepository.js +7 -3
  58. package/features/contentEntry/MoveEntry/MoveEntryRepository.js.map +1 -1
  59. package/features/contentEntry/PublishEntry/PublishEntryRepository.d.ts +4 -2
  60. package/features/contentEntry/PublishEntry/PublishEntryRepository.js +8 -3
  61. package/features/contentEntry/PublishEntry/PublishEntryRepository.js.map +1 -1
  62. package/features/contentEntry/PublishEntry/PublishEntryUseCase.js.map +1 -1
  63. package/features/contentEntry/RepublishEntry/RepublishEntryRepository.d.ts +4 -2
  64. package/features/contentEntry/RepublishEntry/RepublishEntryRepository.js +8 -3
  65. package/features/contentEntry/RepublishEntry/RepublishEntryRepository.js.map +1 -1
  66. package/features/contentEntry/RestoreEntryFromBin/RestoreEntryFromBinRepository.d.ts +4 -2
  67. package/features/contentEntry/RestoreEntryFromBin/RestoreEntryFromBinRepository.js +8 -3
  68. package/features/contentEntry/RestoreEntryFromBin/RestoreEntryFromBinRepository.js.map +1 -1
  69. package/features/contentEntry/UnpublishEntry/UnpublishEntryRepository.d.ts +4 -2
  70. package/features/contentEntry/UnpublishEntry/UnpublishEntryRepository.js +8 -3
  71. package/features/contentEntry/UnpublishEntry/UnpublishEntryRepository.js.map +1 -1
  72. package/features/contentEntry/UpdateEntry/UpdateEntryRepository.d.ts +4 -2
  73. package/features/contentEntry/UpdateEntry/UpdateEntryRepository.js +8 -3
  74. package/features/contentEntry/UpdateEntry/UpdateEntryRepository.js.map +1 -1
  75. package/features/contentEntry/UpdateRevision/UpdateRevisionRepository.d.ts +14 -0
  76. package/features/contentEntry/UpdateRevision/UpdateRevisionRepository.js +34 -0
  77. package/features/contentEntry/UpdateRevision/UpdateRevisionRepository.js.map +1 -0
  78. package/features/contentEntry/UpdateRevision/abstractions.d.ts +10 -0
  79. package/features/contentEntry/UpdateRevision/abstractions.js +5 -0
  80. package/features/contentEntry/UpdateRevision/abstractions.js.map +1 -0
  81. package/features/contentEntry/UpdateRevision/feature.d.ts +4 -0
  82. package/features/contentEntry/UpdateRevision/feature.js +11 -0
  83. package/features/contentEntry/UpdateRevision/feature.js.map +1 -0
  84. package/features/contentEntry/UpdateRevision/index.d.ts +1 -0
  85. package/features/contentEntry/UpdateRevision/index.js +1 -0
  86. package/features/contentEntry/UpdateRevisionDescription/UpdateRevisionDescriptionUseCase.d.ts +2 -2
  87. package/features/contentEntry/UpdateRevisionDescription/UpdateRevisionDescriptionUseCase.js +2 -2
  88. package/features/contentEntry/UpdateRevisionDescription/UpdateRevisionDescriptionUseCase.js.map +1 -1
  89. package/features/contentEntry/ensureItemIds.d.ts +13 -0
  90. package/features/contentEntry/ensureItemIds.js +22 -0
  91. package/features/contentEntry/ensureItemIds.js.map +1 -0
  92. package/features/contentEntry/entryDataFactories/CreateEntryDataFactory/CreateEntryDataFactory.d.ts +3 -1
  93. package/features/contentEntry/entryDataFactories/CreateEntryDataFactory/CreateEntryDataFactory.js +8 -2
  94. package/features/contentEntry/entryDataFactories/CreateEntryDataFactory/CreateEntryDataFactory.js.map +1 -1
  95. package/features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/CreateEntryRevisionFromDataFactory.d.ts +3 -1
  96. package/features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/CreateEntryRevisionFromDataFactory.js +8 -2
  97. package/features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/CreateEntryRevisionFromDataFactory.js.map +1 -1
  98. package/features/contentEntry/entryDataFactories/UpdateEntryDataFactory/UpdateEntryDataFactory.d.ts +3 -1
  99. package/features/contentEntry/entryDataFactories/UpdateEntryDataFactory/UpdateEntryDataFactory.js +8 -2
  100. package/features/contentEntry/entryDataFactories/UpdateEntryDataFactory/UpdateEntryDataFactory.js.map +1 -1
  101. package/features/contentModel/CreateModel/CreateModelRepository.d.ts +4 -2
  102. package/features/contentModel/CreateModel/CreateModelRepository.js +8 -4
  103. package/features/contentModel/CreateModel/CreateModelRepository.js.map +1 -1
  104. package/features/contentModel/CreateModel/CreateModelUseCase.js +2 -2
  105. package/features/contentModel/CreateModel/CreateModelUseCase.js.map +1 -1
  106. package/features/contentModel/CreateModel/abstractions.d.ts +1 -1
  107. package/features/contentModel/CreateModel/abstractions.js.map +1 -1
  108. package/features/contentModel/CreateModelFrom/CreateModelFromRepository.d.ts +4 -2
  109. package/features/contentModel/CreateModelFrom/CreateModelFromRepository.js +8 -4
  110. package/features/contentModel/CreateModelFrom/CreateModelFromRepository.js.map +1 -1
  111. package/features/contentModel/CreateModelFrom/CreateModelFromUseCase.js +2 -2
  112. package/features/contentModel/CreateModelFrom/CreateModelFromUseCase.js.map +1 -1
  113. package/features/contentModel/CreateModelFrom/abstractions.d.ts +1 -1
  114. package/features/contentModel/CreateModelFrom/abstractions.js.map +1 -1
  115. package/features/contentModel/DeleteModel/DeleteModelRepository.d.ts +4 -2
  116. package/features/contentModel/DeleteModel/DeleteModelRepository.js +7 -3
  117. package/features/contentModel/DeleteModel/DeleteModelRepository.js.map +1 -1
  118. package/features/contentModel/UpdateModel/UpdateModelRepository.d.ts +4 -2
  119. package/features/contentModel/UpdateModel/UpdateModelRepository.js +8 -4
  120. package/features/contentModel/UpdateModel/UpdateModelRepository.js.map +1 -1
  121. package/features/contentModel/UpdateModel/UpdateModelUseCase.js +2 -2
  122. package/features/contentModel/UpdateModel/UpdateModelUseCase.js.map +1 -1
  123. package/features/contentModel/UpdateModel/abstractions.d.ts +1 -1
  124. package/features/contentModel/UpdateModel/abstractions.js.map +1 -1
  125. package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js +3 -2
  126. package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js.map +1 -1
  127. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.d.ts +4 -2
  128. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.js +8 -4
  129. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.js.map +1 -1
  130. package/features/contentModelGroup/CreateGroup/CreateGroupUseCase.d.ts +1 -3
  131. package/features/contentModelGroup/CreateGroup/CreateGroupUseCase.js +5 -7
  132. package/features/contentModelGroup/CreateGroup/CreateGroupUseCase.js.map +1 -1
  133. package/features/contentModelGroup/CreateGroup/abstractions.d.ts +1 -1
  134. package/features/contentModelGroup/CreateGroup/abstractions.js.map +1 -1
  135. package/features/contentModelGroup/DeleteGroup/DeleteGroupRepository.d.ts +4 -2
  136. package/features/contentModelGroup/DeleteGroup/DeleteGroupRepository.js +7 -3
  137. package/features/contentModelGroup/DeleteGroup/DeleteGroupRepository.js.map +1 -1
  138. package/features/contentModelGroup/UpdateGroup/UpdateGroupRepository.d.ts +4 -2
  139. package/features/contentModelGroup/UpdateGroup/UpdateGroupRepository.js +8 -4
  140. package/features/contentModelGroup/UpdateGroup/UpdateGroupRepository.js.map +1 -1
  141. package/features/contentModelGroup/UpdateGroup/UpdateGroupUseCase.js +2 -2
  142. package/features/contentModelGroup/UpdateGroup/UpdateGroupUseCase.js.map +1 -1
  143. package/features/contentModelGroup/UpdateGroup/abstractions.d.ts +1 -1
  144. package/features/contentModelGroup/UpdateGroup/abstractions.js.map +1 -1
  145. package/features/graphql/fields/base/DynamicZoneToGraphQL.js +7 -1
  146. package/features/graphql/fields/base/DynamicZoneToGraphQL.js.map +1 -1
  147. package/features/graphql/fields/base/ObjectToGraphQL.js +6 -3
  148. package/features/graphql/fields/base/ObjectToGraphQL.js.map +1 -1
  149. package/features/graphql/fields/base/RefToGraphQL.js +17 -7
  150. package/features/graphql/fields/base/RefToGraphQL.js.map +1 -1
  151. package/features/modelBuilder/abstractions.d.ts +1 -2
  152. package/features/modelBuilder/abstractions.js.map +1 -1
  153. package/features/runtimeTenant/RuntimeTenant.d.ts +13 -0
  154. package/features/runtimeTenant/RuntimeTenant.js +22 -0
  155. package/features/runtimeTenant/RuntimeTenant.js.map +1 -0
  156. package/features/runtimeTenant/abstractions.d.ts +11 -0
  157. package/features/runtimeTenant/abstractions.js +5 -0
  158. package/features/runtimeTenant/abstractions.js.map +1 -0
  159. package/features/runtimeTenant/index.d.ts +2 -0
  160. package/features/runtimeTenant/index.js +2 -0
  161. package/features/sortMapper/SortMapper.js +2 -5
  162. package/features/sortMapper/SortMapper.js.map +1 -1
  163. package/features/storage/fields/ObjectStorageTransform.js +27 -7
  164. package/features/storage/fields/ObjectStorageTransform.js.map +1 -1
  165. package/features/validation/validators/PatternValidator.js +1 -1
  166. package/features/validation/validators/PatternValidator.js.map +1 -1
  167. package/features/whereMapper/WhereMapper.js +7 -5
  168. package/features/whereMapper/WhereMapper.js.map +1 -1
  169. package/fieldConverters/CmsModelDynamicZoneFieldConverterPlugin.js +15 -5
  170. package/fieldConverters/CmsModelDynamicZoneFieldConverterPlugin.js.map +1 -1
  171. package/fieldConverters/CmsModelObjectFieldConverterPlugin.js +8 -2
  172. package/fieldConverters/CmsModelObjectFieldConverterPlugin.js.map +1 -1
  173. package/package.json +18 -18
  174. package/types/types.d.ts +4 -0
  175. package/types/types.js.map +1 -1
@@ -14,6 +14,8 @@ import { getIdentity } from "../../../../utils/identity.js";
14
14
  import { NotAuthorizedError } from "../../../../utils/errors.js";
15
15
  import { getSystem } from "../system.js";
16
16
  import { getExpiresAt } from "../expiresAt.js";
17
+ import { ModelToAstConverter } from "../../../contentModel/ModelToAstConverter/abstractions.js";
18
+ import { ensureItemIds } from "../../ensureItemIds.js";
17
19
  const convertDefaultValue = (field, value)=>{
18
20
  switch(field.type){
19
21
  case "boolean":
@@ -64,14 +66,17 @@ const createEntryId = (input)=>{
64
66
  };
65
67
  };
66
68
  class CreateEntryDataFactoryImpl {
67
- constructor(cmsContext, identityContext, tenantContext, accessControl){
69
+ constructor(cmsContext, identityContext, tenantContext, accessControl, modelToAstConverter){
68
70
  this.cmsContext = cmsContext;
69
71
  this.identityContext = identityContext;
70
72
  this.tenantContext = tenantContext;
71
73
  this.accessControl = accessControl;
74
+ this.modelToAstConverter = modelToAstConverter;
72
75
  }
73
76
  async create(model, rawInput, options) {
74
77
  const initialValues = cleanInputValues(model, rawInput.values || {});
78
+ const modelAst = this.modelToAstConverter.toAst(model);
79
+ await ensureItemIds(modelAst, initialValues);
75
80
  await validateModelEntryDataOrThrow({
76
81
  context: this.cmsContext,
77
82
  model,
@@ -208,7 +213,8 @@ const CreateEntryDataFactory_CreateEntryDataFactory = createImplementation({
208
213
  CmsContext,
209
214
  IdentityContext,
210
215
  TenantContext,
211
- AccessControl
216
+ AccessControl,
217
+ ModelToAstConverter
212
218
  ]
213
219
  });
214
220
  export { CreateEntryDataFactory_CreateEntryDataFactory as CreateEntryDataFactory };
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentEntry/entryDataFactories/CreateEntryDataFactory/CreateEntryDataFactory.js","sources":["../../../../../src/features/contentEntry/entryDataFactories/CreateEntryDataFactory/CreateEntryDataFactory.ts"],"sourcesContent":["import { createImplementation } from \"@webiny/feature/api\";\nimport {\n CreateEntryDataFactory as FactoryAbstraction,\n type ICreateEntryDataFactory,\n type ICreateEntryDataResponse\n} from \"./abstractions.js\";\nimport { AccessControl, CmsContext } from \"~/features/shared/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport type {\n CmsEntry,\n CmsEntryValues,\n CmsModel,\n CmsModelField,\n CreateCmsEntryInput,\n CreateCmsEntryOptionsInput\n} from \"~/types/index.js\";\nimport { getDate } from \"~/utils/date.js\";\nimport { ROOT_FOLDER } from \"~/constants.js\";\nimport WebinyError from \"@webiny/error\";\nimport { validateModelEntryDataOrThrow } from \"~/crud/contentEntry/entryDataValidation.js\";\nimport { referenceFieldsMapping } from \"~/crud/contentEntry/referenceFieldsMapping.js\";\nimport { createIdentifier, mdbid } from \"@webiny/utils\";\nimport { STATUS_DRAFT, STATUS_PUBLISHED, STATUS_UNPUBLISHED } from \"../statuses.js\";\nimport { getIdentity } from \"~/utils/identity.js\";\nimport { NotAuthorizedError } from \"~/utils/errors.js\";\nimport { getSystem } from \"../system.js\";\nimport { getExpiresAt } from \"../expiresAt.js\";\n\ntype DefaultValue = boolean | number | string | null;\n\nconst convertDefaultValue = (field: CmsModelField, value: DefaultValue): DefaultValue => {\n switch (field.type) {\n case \"boolean\":\n return Boolean(value);\n case \"number\":\n return Number(value);\n default:\n return value;\n }\n};\n\nconst getDefaultValue = (field: CmsModelField): (DefaultValue | DefaultValue[]) | undefined => {\n const { settings, list } = field;\n if (settings && settings.defaultValue !== undefined) {\n return convertDefaultValue(field, settings.defaultValue);\n }\n const { predefinedValues } = field;\n if (\n !predefinedValues ||\n !predefinedValues.enabled ||\n Array.isArray(predefinedValues.values) === false\n ) {\n return undefined;\n }\n if (!list) {\n const selectedValue = predefinedValues.values.find(value => {\n return !!value.selected;\n });\n if (selectedValue) {\n return convertDefaultValue(field, selectedValue.value);\n }\n return undefined;\n }\n return predefinedValues.values\n .filter(({ selected }) => !!selected)\n .map(({ value }) => {\n return convertDefaultValue(field, value);\n });\n};\n\nconst cleanInputValues = <TValues extends CmsEntryValues = CmsEntryValues>(\n model: CmsModel,\n input: TValues\n) => {\n return model.fields.reduce<TValues>((acc, field) => {\n if (!field.fieldId) {\n throw new WebinyError(\"Field does not have an fieldId.\", \"MISSING_FIELD_ID\", {\n field\n });\n }\n const key = field.fieldId as keyof TValues;\n const value = input[key] as TValues[keyof TValues];\n acc[key] = value === undefined ? (getDefaultValue(field) as TValues[keyof TValues]) : value;\n return acc;\n }, {} as TValues);\n};\n\nconst createEntryId = (input: CreateCmsEntryInput) => {\n let entryId = mdbid();\n if (input.id) {\n if (input.id.match(/^([a-zA-Z0-9])([a-zA-Z0-9-]+)([a-zA-Z0-9])$/) === null) {\n throw new WebinyError(\n \"The provided ID is not valid. It must be a string which can be A-Z, a-z, 0-9, - and it cannot start or end with a -.\",\n \"INVALID_ID\",\n {\n id: input.id\n }\n );\n }\n entryId = input.id;\n }\n const version = 1;\n return {\n entryId,\n version,\n id: createIdentifier({\n id: entryId,\n version\n })\n };\n};\n\nclass CreateEntryDataFactoryImpl implements ICreateEntryDataFactory {\n public constructor(\n private readonly cmsContext: CmsContext.Interface,\n private readonly identityContext: IdentityContext.Interface,\n private readonly tenantContext: TenantContext.Interface,\n private readonly accessControl: AccessControl.Interface\n ) {}\n\n public async create<TValues extends CmsEntryValues = CmsEntryValues>(\n model: CmsModel,\n rawInput: CreateCmsEntryInput<TValues>,\n options?: CreateCmsEntryOptionsInput\n ): Promise<ICreateEntryDataResponse<TValues>> {\n const initialValues = cleanInputValues<TValues>(model, rawInput.values || ({} as TValues));\n\n await validateModelEntryDataOrThrow({\n context: this.cmsContext,\n model,\n values: initialValues,\n skipValidation: options?.skipValidation\n });\n\n const values = await referenceFieldsMapping<TValues>({\n context: this.cmsContext,\n model,\n values: initialValues,\n validateEntries: true\n });\n\n const { id, entryId, version } = createEntryId(rawInput);\n\n const currentIdentity = this.identityContext.getIdentity();\n const currentDateTime = new Date();\n\n const status = rawInput.status || STATUS_DRAFT;\n if (status !== STATUS_DRAFT) {\n if (status === STATUS_PUBLISHED) {\n const canPublish = await this.accessControl.canAccessEntry({ model, pw: \"p\" });\n if (!canPublish) {\n throw new NotAuthorizedError(\n `Not allowed to access \"${model.modelId}\" entries.`\n );\n }\n } else if (status === STATUS_UNPUBLISHED) {\n const canUnpublish = await this.accessControl.canAccessEntry({ model, pw: \"u\" });\n if (!canUnpublish) {\n throw new NotAuthorizedError(\n `Not allowed to access \"${model.modelId}\" entries.`\n );\n }\n }\n }\n\n const locked = status !== STATUS_DRAFT;\n\n let revisionLevelPublishingMetaFields: Pick<\n CmsEntry,\n | \"revisionFirstPublishedOn\"\n | \"revisionLastPublishedOn\"\n | \"revisionFirstPublishedBy\"\n | \"revisionLastPublishedBy\"\n > = {\n revisionFirstPublishedOn: null,\n revisionLastPublishedOn: null,\n revisionFirstPublishedBy: null,\n revisionLastPublishedBy: null\n };\n\n let entryLevelPublishingMetaFields: Pick<\n CmsEntry,\n \"firstPublishedOn\" | \"lastPublishedOn\" | \"firstPublishedBy\" | \"lastPublishedBy\"\n > = {\n firstPublishedOn: null,\n lastPublishedOn: null,\n firstPublishedBy: null,\n lastPublishedBy: null\n };\n\n if (status === STATUS_PUBLISHED) {\n revisionLevelPublishingMetaFields = {\n revisionFirstPublishedOn: getDate(\n rawInput.revisionFirstPublishedOn,\n currentDateTime\n ),\n revisionLastPublishedOn: getDate(rawInput.revisionLastPublishedOn, currentDateTime),\n revisionFirstPublishedBy: getIdentity(\n rawInput.revisionFirstPublishedBy,\n currentIdentity\n ),\n revisionLastPublishedBy: getIdentity(\n rawInput.revisionLastPublishedBy,\n currentIdentity\n )\n };\n\n entryLevelPublishingMetaFields = {\n firstPublishedOn: getDate(rawInput.firstPublishedOn, currentDateTime),\n lastPublishedOn: getDate(rawInput.lastPublishedOn, currentDateTime),\n firstPublishedBy: getIdentity(rawInput.firstPublishedBy, currentIdentity),\n lastPublishedBy: getIdentity(rawInput.lastPublishedBy, currentIdentity)\n };\n }\n\n const entry: CmsEntry<TValues> = {\n tenant: this.tenantContext.getTenant().id,\n entryId,\n id,\n modelId: model.modelId,\n createdOn: getDate(rawInput.createdOn, currentDateTime),\n modifiedOn: getDate(rawInput.modifiedOn, null),\n savedOn: getDate(rawInput.savedOn, currentDateTime),\n deletedOn: getDate(rawInput.deletedOn, null),\n restoredOn: getDate(rawInput.restoredOn, null),\n createdBy: getIdentity(rawInput.createdBy, currentIdentity)!,\n modifiedBy: getIdentity(rawInput.modifiedBy, null),\n savedBy: getIdentity(rawInput.savedBy, currentIdentity)!,\n deletedBy: getIdentity(rawInput.deletedBy, null),\n restoredBy: getIdentity(rawInput.restoredBy, null),\n ...entryLevelPublishingMetaFields,\n revisionCreatedOn: getDate(rawInput.revisionCreatedOn, currentDateTime),\n revisionModifiedOn: getDate(rawInput.revisionModifiedOn, null),\n revisionSavedOn: getDate(rawInput.revisionSavedOn, currentDateTime),\n revisionDeletedOn: getDate(rawInput.revisionDeletedOn, null),\n revisionRestoredOn: getDate(rawInput.revisionRestoredOn, null),\n revisionCreatedBy: getIdentity(rawInput.revisionCreatedBy, currentIdentity)!,\n revisionModifiedBy: getIdentity(rawInput.revisionModifiedBy, null),\n revisionSavedBy: getIdentity(rawInput.revisionSavedBy, currentIdentity)!,\n revisionDeletedBy: getIdentity(rawInput.revisionDeletedBy, null),\n revisionRestoredBy: getIdentity(rawInput.revisionRestoredBy, null),\n ...revisionLevelPublishingMetaFields,\n version,\n status,\n locked,\n values,\n location: {\n folderId:\n rawInput.location?.folderId || rawInput.wbyAco_location?.folderId || ROOT_FOLDER\n },\n system: getSystem({\n input: rawInput\n }),\n live:\n status === STATUS_PUBLISHED\n ? {\n version\n }\n : null,\n revisionDescription: \"\",\n expiresAt: getExpiresAt({ expiresAt: rawInput.expiresAt })\n };\n\n if (status !== STATUS_DRAFT) {\n if (status === STATUS_PUBLISHED) {\n const canPublish = await this.accessControl.canAccessEntry({\n model,\n entry,\n pw: \"p\"\n });\n if (!canPublish) {\n throw new NotAuthorizedError(`Not allowed to access entry \"${entry.entryId}\".`);\n }\n } else if (status === STATUS_UNPUBLISHED) {\n const canUnpublish = await this.accessControl.canAccessEntry({\n model,\n entry,\n pw: \"u\"\n });\n if (!canUnpublish) {\n throw new NotAuthorizedError(`Not allowed to access entry \"${entry.entryId}\".`);\n }\n }\n }\n\n return {\n entry,\n input: {\n ...rawInput,\n values: structuredClone(values)\n }\n };\n }\n}\n\nexport const CreateEntryDataFactory = createImplementation({\n abstraction: FactoryAbstraction,\n implementation: CreateEntryDataFactoryImpl,\n dependencies: [CmsContext, IdentityContext, TenantContext, AccessControl]\n});\n"],"names":["convertDefaultValue","field","value","Boolean","Number","getDefaultValue","settings","list","undefined","predefinedValues","Array","selectedValue","selected","cleanInputValues","model","input","acc","WebinyError","key","createEntryId","entryId","mdbid","version","createIdentifier","CreateEntryDataFactoryImpl","cmsContext","identityContext","tenantContext","accessControl","rawInput","options","initialValues","validateModelEntryDataOrThrow","values","referenceFieldsMapping","id","currentIdentity","currentDateTime","Date","status","STATUS_DRAFT","STATUS_PUBLISHED","canPublish","NotAuthorizedError","STATUS_UNPUBLISHED","canUnpublish","locked","revisionLevelPublishingMetaFields","entryLevelPublishingMetaFields","getDate","getIdentity","entry","ROOT_FOLDER","getSystem","getExpiresAt","structuredClone","CreateEntryDataFactory","createImplementation","FactoryAbstraction","CmsContext","IdentityContext","TenantContext","AccessControl"],"mappings":";;;;;;;;;;;;;;;;AA+BA,MAAMA,sBAAsB,CAACC,OAAsBC;IAC/C,OAAQD,MAAM,IAAI;QACd,KAAK;YACD,OAAOE,QAAQD;QACnB,KAAK;YACD,OAAOE,OAAOF;QAClB;YACI,OAAOA;IACf;AACJ;AAEA,MAAMG,kBAAkB,CAACJ;IACrB,MAAM,EAAEK,QAAQ,EAAEC,IAAI,EAAE,GAAGN;IAC3B,IAAIK,YAAYA,AAA0BE,WAA1BF,SAAS,YAAY,EACjC,OAAON,oBAAoBC,OAAOK,SAAS,YAAY;IAE3D,MAAM,EAAEG,gBAAgB,EAAE,GAAGR;IAC7B,IACI,CAACQ,oBACD,CAACA,iBAAiB,OAAO,IACzBC,AAA2C,UAA3CA,MAAM,OAAO,CAACD,iBAAiB,MAAM,GAErC;IAEJ,IAAI,CAACF,MAAM;QACP,MAAMI,gBAAgBF,iBAAiB,MAAM,CAAC,IAAI,CAACP,CAAAA,QACxC,CAAC,CAACA,MAAM,QAAQ;QAE3B,IAAIS,eACA,OAAOX,oBAAoBC,OAAOU,cAAc,KAAK;QAEzD;IACJ;IACA,OAAOF,iBAAiB,MAAM,CACzB,MAAM,CAAC,CAAC,EAAEG,QAAQ,EAAE,GAAK,CAAC,CAACA,UAC3B,GAAG,CAAC,CAAC,EAAEV,KAAK,EAAE,GACJF,oBAAoBC,OAAOC;AAE9C;AAEA,MAAMW,mBAAmB,CACrBC,OACAC,QAEOD,MAAM,MAAM,CAAC,MAAM,CAAU,CAACE,KAAKf;QACtC,IAAI,CAACA,MAAM,OAAO,EACd,MAAM,IAAIgB,MAAY,mCAAmC,oBAAoB;YACzEhB;QACJ;QAEJ,MAAMiB,MAAMjB,MAAM,OAAO;QACzB,MAAMC,QAAQa,KAAK,CAACG,IAAI;QACxBF,GAAG,CAACE,IAAI,GAAGhB,AAAUM,WAAVN,QAAuBG,gBAAgBJ,SAAoCC;QACtF,OAAOc;IACX,GAAG,CAAC;AAGR,MAAMG,gBAAgB,CAACJ;IACnB,IAAIK,UAAUC;IACd,IAAIN,MAAM,EAAE,EAAE;QACV,IAAIA,AAAkE,SAAlEA,MAAM,EAAE,CAAC,KAAK,CAAC,gDACf,MAAM,IAAIE,MACN,wHACA,cACA;YACI,IAAIF,MAAM,EAAE;QAChB;QAGRK,UAAUL,MAAM,EAAE;IACtB;IACA,MAAMO,UAAU;IAChB,OAAO;QACHF;QACAE;QACA,IAAIC,iBAAiB;YACjB,IAAIH;YACJE;QACJ;IACJ;AACJ;AAEA,MAAME;IACF,YACqBC,UAAgC,EAChCC,eAA0C,EAC1CC,aAAsC,EACtCC,aAAsC,CACzD;aAJmBH,UAAU,GAAVA;aACAC,eAAe,GAAfA;aACAC,aAAa,GAAbA;aACAC,aAAa,GAAbA;IAClB;IAEH,MAAa,OACTd,KAAe,EACfe,QAAsC,EACtCC,OAAoC,EACM;QAC1C,MAAMC,gBAAgBlB,iBAA0BC,OAAOe,SAAS,MAAM,IAAK,CAAC;QAE5E,MAAMG,8BAA8B;YAChC,SAAS,IAAI,CAAC,UAAU;YACxBlB;YACA,QAAQiB;YACR,gBAAgBD,SAAS;QAC7B;QAEA,MAAMG,SAAS,MAAMC,uBAAgC;YACjD,SAAS,IAAI,CAAC,UAAU;YACxBpB;YACA,QAAQiB;YACR,iBAAiB;QACrB;QAEA,MAAM,EAAEI,EAAE,EAAEf,OAAO,EAAEE,OAAO,EAAE,GAAGH,cAAcU;QAE/C,MAAMO,kBAAkB,IAAI,CAAC,eAAe,CAAC,WAAW;QACxD,MAAMC,kBAAkB,IAAIC;QAE5B,MAAMC,SAASV,SAAS,MAAM,IAAIW;QAClC,IAAID,WAAWC,cACX;YAAA,IAAID,WAAWE,kBAAkB;gBAC7B,MAAMC,aAAa,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;oBAAE5B;oBAAO,IAAI;gBAAI;gBAC5E,IAAI,CAAC4B,YACD,MAAM,IAAIC,mBACN,CAAC,uBAAuB,EAAE7B,MAAM,OAAO,CAAC,UAAU,CAAC;YAG/D,OAAO,IAAIyB,WAAWK,oBAAoB;gBACtC,MAAMC,eAAe,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;oBAAE/B;oBAAO,IAAI;gBAAI;gBAC9E,IAAI,CAAC+B,cACD,MAAM,IAAIF,mBACN,CAAC,uBAAuB,EAAE7B,MAAM,OAAO,CAAC,UAAU,CAAC;YAG/D;QAAA;QAGJ,MAAMgC,SAASP,WAAWC;QAE1B,IAAIO,oCAMA;YACA,0BAA0B;YAC1B,yBAAyB;YACzB,0BAA0B;YAC1B,yBAAyB;QAC7B;QAEA,IAAIC,iCAGA;YACA,kBAAkB;YAClB,iBAAiB;YACjB,kBAAkB;YAClB,iBAAiB;QACrB;QAEA,IAAIT,WAAWE,kBAAkB;YAC7BM,oCAAoC;gBAChC,0BAA0BE,QACtBpB,SAAS,wBAAwB,EACjCQ;gBAEJ,yBAAyBY,QAAQpB,SAAS,uBAAuB,EAAEQ;gBACnE,0BAA0Ba,YACtBrB,SAAS,wBAAwB,EACjCO;gBAEJ,yBAAyBc,YACrBrB,SAAS,uBAAuB,EAChCO;YAER;YAEAY,iCAAiC;gBAC7B,kBAAkBC,QAAQpB,SAAS,gBAAgB,EAAEQ;gBACrD,iBAAiBY,QAAQpB,SAAS,eAAe,EAAEQ;gBACnD,kBAAkBa,YAAYrB,SAAS,gBAAgB,EAAEO;gBACzD,iBAAiBc,YAAYrB,SAAS,eAAe,EAAEO;YAC3D;QACJ;QAEA,MAAMe,QAA2B;YAC7B,QAAQ,IAAI,CAAC,aAAa,CAAC,SAAS,GAAG,EAAE;YACzC/B;YACAe;YACA,SAASrB,MAAM,OAAO;YACtB,WAAWmC,QAAQpB,SAAS,SAAS,EAAEQ;YACvC,YAAYY,QAAQpB,SAAS,UAAU,EAAE;YACzC,SAASoB,QAAQpB,SAAS,OAAO,EAAEQ;YACnC,WAAWY,QAAQpB,SAAS,SAAS,EAAE;YACvC,YAAYoB,QAAQpB,SAAS,UAAU,EAAE;YACzC,WAAWqB,YAAYrB,SAAS,SAAS,EAAEO;YAC3C,YAAYc,YAAYrB,SAAS,UAAU,EAAE;YAC7C,SAASqB,YAAYrB,SAAS,OAAO,EAAEO;YACvC,WAAWc,YAAYrB,SAAS,SAAS,EAAE;YAC3C,YAAYqB,YAAYrB,SAAS,UAAU,EAAE;YAC7C,GAAGmB,8BAA8B;YACjC,mBAAmBC,QAAQpB,SAAS,iBAAiB,EAAEQ;YACvD,oBAAoBY,QAAQpB,SAAS,kBAAkB,EAAE;YACzD,iBAAiBoB,QAAQpB,SAAS,eAAe,EAAEQ;YACnD,mBAAmBY,QAAQpB,SAAS,iBAAiB,EAAE;YACvD,oBAAoBoB,QAAQpB,SAAS,kBAAkB,EAAE;YACzD,mBAAmBqB,YAAYrB,SAAS,iBAAiB,EAAEO;YAC3D,oBAAoBc,YAAYrB,SAAS,kBAAkB,EAAE;YAC7D,iBAAiBqB,YAAYrB,SAAS,eAAe,EAAEO;YACvD,mBAAmBc,YAAYrB,SAAS,iBAAiB,EAAE;YAC3D,oBAAoBqB,YAAYrB,SAAS,kBAAkB,EAAE;YAC7D,GAAGkB,iCAAiC;YACpCzB;YACAiB;YACAO;YACAb;YACA,UAAU;gBACN,UACIJ,SAAS,QAAQ,EAAE,YAAYA,SAAS,eAAe,EAAE,YAAYuB;YAC7E;YACA,QAAQC,UAAU;gBACd,OAAOxB;YACX;YACA,MACIU,WAAWE,mBACL;gBACInB;YACJ,IACA;YACV,qBAAqB;YACrB,WAAWgC,aAAa;gBAAE,WAAWzB,SAAS,SAAS;YAAC;QAC5D;QAEA,IAAIU,WAAWC,cACX;YAAA,IAAID,WAAWE,kBAAkB;gBAC7B,MAAMC,aAAa,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;oBACvD5B;oBACAqC;oBACA,IAAI;gBACR;gBACA,IAAI,CAACT,YACD,MAAM,IAAIC,mBAAmB,CAAC,6BAA6B,EAAEQ,MAAM,OAAO,CAAC,EAAE,CAAC;YAEtF,OAAO,IAAIZ,WAAWK,oBAAoB;gBACtC,MAAMC,eAAe,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;oBACzD/B;oBACAqC;oBACA,IAAI;gBACR;gBACA,IAAI,CAACN,cACD,MAAM,IAAIF,mBAAmB,CAAC,6BAA6B,EAAEQ,MAAM,OAAO,CAAC,EAAE,CAAC;YAEtF;QAAA;QAGJ,OAAO;YACHA;YACA,OAAO;gBACH,GAAGtB,QAAQ;gBACX,QAAQ0B,gBAAgBtB;YAC5B;QACJ;IACJ;AACJ;AAEO,MAAMuB,gDAAyBC,qBAAqB;IACvD,aAAaC;IACb,gBAAgBlC;IAChB,cAAc;QAACmC;QAAYC;QAAiBC;QAAeC;KAAc;AAC7E"}
1
+ {"version":3,"file":"features/contentEntry/entryDataFactories/CreateEntryDataFactory/CreateEntryDataFactory.js","sources":["../../../../../src/features/contentEntry/entryDataFactories/CreateEntryDataFactory/CreateEntryDataFactory.ts"],"sourcesContent":["import { createImplementation } from \"@webiny/feature/api\";\nimport {\n CreateEntryDataFactory as FactoryAbstraction,\n type ICreateEntryDataFactory,\n type ICreateEntryDataResponse\n} from \"./abstractions.js\";\nimport { AccessControl, CmsContext } from \"~/features/shared/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport type {\n CmsEntry,\n CmsEntryValues,\n CmsModel,\n CmsModelField,\n CreateCmsEntryInput,\n CreateCmsEntryOptionsInput\n} from \"~/types/index.js\";\nimport { getDate } from \"~/utils/date.js\";\nimport { ROOT_FOLDER } from \"~/constants.js\";\nimport WebinyError from \"@webiny/error\";\nimport { validateModelEntryDataOrThrow } from \"~/crud/contentEntry/entryDataValidation.js\";\nimport { referenceFieldsMapping } from \"~/crud/contentEntry/referenceFieldsMapping.js\";\nimport { createIdentifier, mdbid } from \"@webiny/utils\";\nimport { STATUS_DRAFT, STATUS_PUBLISHED, STATUS_UNPUBLISHED } from \"../statuses.js\";\nimport { getIdentity } from \"~/utils/identity.js\";\nimport { NotAuthorizedError } from \"~/utils/errors.js\";\nimport { getSystem } from \"../system.js\";\nimport { getExpiresAt } from \"../expiresAt.js\";\nimport { ModelToAstConverter } from \"~/features/contentModel/ModelToAstConverter/abstractions.js\";\nimport { ensureItemIds } from \"../../ensureItemIds.js\";\n\ntype DefaultValue = boolean | number | string | null;\n\nconst convertDefaultValue = (field: CmsModelField, value: DefaultValue): DefaultValue => {\n switch (field.type) {\n case \"boolean\":\n return Boolean(value);\n case \"number\":\n return Number(value);\n default:\n return value;\n }\n};\n\nconst getDefaultValue = (field: CmsModelField): (DefaultValue | DefaultValue[]) | undefined => {\n const { settings, list } = field;\n if (settings && settings.defaultValue !== undefined) {\n return convertDefaultValue(field, settings.defaultValue);\n }\n const { predefinedValues } = field;\n if (\n !predefinedValues ||\n !predefinedValues.enabled ||\n Array.isArray(predefinedValues.values) === false\n ) {\n return undefined;\n }\n if (!list) {\n const selectedValue = predefinedValues.values.find(value => {\n return !!value.selected;\n });\n if (selectedValue) {\n return convertDefaultValue(field, selectedValue.value);\n }\n return undefined;\n }\n return predefinedValues.values\n .filter(({ selected }) => !!selected)\n .map(({ value }) => {\n return convertDefaultValue(field, value);\n });\n};\n\nconst cleanInputValues = <TValues extends CmsEntryValues = CmsEntryValues>(\n model: CmsModel,\n input: TValues\n) => {\n return model.fields.reduce<TValues>((acc, field) => {\n if (!field.fieldId) {\n throw new WebinyError(\"Field does not have an fieldId.\", \"MISSING_FIELD_ID\", {\n field\n });\n }\n const key = field.fieldId as keyof TValues;\n const value = input[key] as TValues[keyof TValues];\n acc[key] = value === undefined ? (getDefaultValue(field) as TValues[keyof TValues]) : value;\n return acc;\n }, {} as TValues);\n};\n\nconst createEntryId = (input: CreateCmsEntryInput) => {\n let entryId = mdbid();\n if (input.id) {\n if (input.id.match(/^([a-zA-Z0-9])([a-zA-Z0-9-]+)([a-zA-Z0-9])$/) === null) {\n throw new WebinyError(\n \"The provided ID is not valid. It must be a string which can be A-Z, a-z, 0-9, - and it cannot start or end with a -.\",\n \"INVALID_ID\",\n {\n id: input.id\n }\n );\n }\n entryId = input.id;\n }\n const version = 1;\n return {\n entryId,\n version,\n id: createIdentifier({\n id: entryId,\n version\n })\n };\n};\n\nclass CreateEntryDataFactoryImpl implements ICreateEntryDataFactory {\n public constructor(\n private readonly cmsContext: CmsContext.Interface,\n private readonly identityContext: IdentityContext.Interface,\n private readonly tenantContext: TenantContext.Interface,\n private readonly accessControl: AccessControl.Interface,\n private readonly modelToAstConverter: ModelToAstConverter.Interface\n ) {}\n\n public async create<TValues extends CmsEntryValues = CmsEntryValues>(\n model: CmsModel,\n rawInput: CreateCmsEntryInput<TValues>,\n options?: CreateCmsEntryOptionsInput\n ): Promise<ICreateEntryDataResponse<TValues>> {\n const initialValues = cleanInputValues<TValues>(model, rawInput.values || ({} as TValues));\n\n const modelAst = this.modelToAstConverter.toAst(model);\n await ensureItemIds(modelAst, initialValues);\n\n await validateModelEntryDataOrThrow({\n context: this.cmsContext,\n model,\n values: initialValues,\n skipValidation: options?.skipValidation\n });\n\n const values = await referenceFieldsMapping<TValues>({\n context: this.cmsContext,\n model,\n values: initialValues,\n validateEntries: true\n });\n\n const { id, entryId, version } = createEntryId(rawInput);\n\n const currentIdentity = this.identityContext.getIdentity();\n const currentDateTime = new Date();\n\n const status = rawInput.status || STATUS_DRAFT;\n if (status !== STATUS_DRAFT) {\n if (status === STATUS_PUBLISHED) {\n const canPublish = await this.accessControl.canAccessEntry({ model, pw: \"p\" });\n if (!canPublish) {\n throw new NotAuthorizedError(\n `Not allowed to access \"${model.modelId}\" entries.`\n );\n }\n } else if (status === STATUS_UNPUBLISHED) {\n const canUnpublish = await this.accessControl.canAccessEntry({ model, pw: \"u\" });\n if (!canUnpublish) {\n throw new NotAuthorizedError(\n `Not allowed to access \"${model.modelId}\" entries.`\n );\n }\n }\n }\n\n const locked = status !== STATUS_DRAFT;\n\n let revisionLevelPublishingMetaFields: Pick<\n CmsEntry,\n | \"revisionFirstPublishedOn\"\n | \"revisionLastPublishedOn\"\n | \"revisionFirstPublishedBy\"\n | \"revisionLastPublishedBy\"\n > = {\n revisionFirstPublishedOn: null,\n revisionLastPublishedOn: null,\n revisionFirstPublishedBy: null,\n revisionLastPublishedBy: null\n };\n\n let entryLevelPublishingMetaFields: Pick<\n CmsEntry,\n \"firstPublishedOn\" | \"lastPublishedOn\" | \"firstPublishedBy\" | \"lastPublishedBy\"\n > = {\n firstPublishedOn: null,\n lastPublishedOn: null,\n firstPublishedBy: null,\n lastPublishedBy: null\n };\n\n if (status === STATUS_PUBLISHED) {\n revisionLevelPublishingMetaFields = {\n revisionFirstPublishedOn: getDate(\n rawInput.revisionFirstPublishedOn,\n currentDateTime\n ),\n revisionLastPublishedOn: getDate(rawInput.revisionLastPublishedOn, currentDateTime),\n revisionFirstPublishedBy: getIdentity(\n rawInput.revisionFirstPublishedBy,\n currentIdentity\n ),\n revisionLastPublishedBy: getIdentity(\n rawInput.revisionLastPublishedBy,\n currentIdentity\n )\n };\n\n entryLevelPublishingMetaFields = {\n firstPublishedOn: getDate(rawInput.firstPublishedOn, currentDateTime),\n lastPublishedOn: getDate(rawInput.lastPublishedOn, currentDateTime),\n firstPublishedBy: getIdentity(rawInput.firstPublishedBy, currentIdentity),\n lastPublishedBy: getIdentity(rawInput.lastPublishedBy, currentIdentity)\n };\n }\n\n const entry: CmsEntry<TValues> = {\n tenant: this.tenantContext.getTenant().id,\n entryId,\n id,\n modelId: model.modelId,\n createdOn: getDate(rawInput.createdOn, currentDateTime),\n modifiedOn: getDate(rawInput.modifiedOn, null),\n savedOn: getDate(rawInput.savedOn, currentDateTime),\n deletedOn: getDate(rawInput.deletedOn, null),\n restoredOn: getDate(rawInput.restoredOn, null),\n createdBy: getIdentity(rawInput.createdBy, currentIdentity)!,\n modifiedBy: getIdentity(rawInput.modifiedBy, null),\n savedBy: getIdentity(rawInput.savedBy, currentIdentity)!,\n deletedBy: getIdentity(rawInput.deletedBy, null),\n restoredBy: getIdentity(rawInput.restoredBy, null),\n ...entryLevelPublishingMetaFields,\n revisionCreatedOn: getDate(rawInput.revisionCreatedOn, currentDateTime),\n revisionModifiedOn: getDate(rawInput.revisionModifiedOn, null),\n revisionSavedOn: getDate(rawInput.revisionSavedOn, currentDateTime),\n revisionDeletedOn: getDate(rawInput.revisionDeletedOn, null),\n revisionRestoredOn: getDate(rawInput.revisionRestoredOn, null),\n revisionCreatedBy: getIdentity(rawInput.revisionCreatedBy, currentIdentity)!,\n revisionModifiedBy: getIdentity(rawInput.revisionModifiedBy, null),\n revisionSavedBy: getIdentity(rawInput.revisionSavedBy, currentIdentity)!,\n revisionDeletedBy: getIdentity(rawInput.revisionDeletedBy, null),\n revisionRestoredBy: getIdentity(rawInput.revisionRestoredBy, null),\n ...revisionLevelPublishingMetaFields,\n version,\n status,\n locked,\n values,\n location: {\n folderId:\n rawInput.location?.folderId || rawInput.wbyAco_location?.folderId || ROOT_FOLDER\n },\n system: getSystem({\n input: rawInput\n }),\n live:\n status === STATUS_PUBLISHED\n ? {\n version\n }\n : null,\n revisionDescription: \"\",\n expiresAt: getExpiresAt({ expiresAt: rawInput.expiresAt })\n };\n\n if (status !== STATUS_DRAFT) {\n if (status === STATUS_PUBLISHED) {\n const canPublish = await this.accessControl.canAccessEntry({\n model,\n entry,\n pw: \"p\"\n });\n if (!canPublish) {\n throw new NotAuthorizedError(`Not allowed to access entry \"${entry.entryId}\".`);\n }\n } else if (status === STATUS_UNPUBLISHED) {\n const canUnpublish = await this.accessControl.canAccessEntry({\n model,\n entry,\n pw: \"u\"\n });\n if (!canUnpublish) {\n throw new NotAuthorizedError(`Not allowed to access entry \"${entry.entryId}\".`);\n }\n }\n }\n\n return {\n entry,\n input: {\n ...rawInput,\n values: structuredClone(values)\n }\n };\n }\n}\n\nexport const CreateEntryDataFactory = createImplementation({\n abstraction: FactoryAbstraction,\n implementation: CreateEntryDataFactoryImpl,\n dependencies: [CmsContext, IdentityContext, TenantContext, AccessControl, ModelToAstConverter]\n});\n"],"names":["convertDefaultValue","field","value","Boolean","Number","getDefaultValue","settings","list","undefined","predefinedValues","Array","selectedValue","selected","cleanInputValues","model","input","acc","WebinyError","key","createEntryId","entryId","mdbid","version","createIdentifier","CreateEntryDataFactoryImpl","cmsContext","identityContext","tenantContext","accessControl","modelToAstConverter","rawInput","options","initialValues","modelAst","ensureItemIds","validateModelEntryDataOrThrow","values","referenceFieldsMapping","id","currentIdentity","currentDateTime","Date","status","STATUS_DRAFT","STATUS_PUBLISHED","canPublish","NotAuthorizedError","STATUS_UNPUBLISHED","canUnpublish","locked","revisionLevelPublishingMetaFields","entryLevelPublishingMetaFields","getDate","getIdentity","entry","ROOT_FOLDER","getSystem","getExpiresAt","structuredClone","CreateEntryDataFactory","createImplementation","FactoryAbstraction","CmsContext","IdentityContext","TenantContext","AccessControl","ModelToAstConverter"],"mappings":"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"}
@@ -2,11 +2,13 @@ import { type ICreateEntryRevisionFromDataFactory, type ICreateEntryRevisionFrom
2
2
  import { AccessControl, CmsContext } from "../../../../features/shared/abstractions.js";
3
3
  import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
4
4
  import type { CmsEntry, CmsEntryValues, CmsModel, CreateCmsEntryInput, CreateCmsEntryOptionsInput } from "../../../../types/index.js";
5
+ import { ModelToAstConverter } from "../../../../features/contentModel/ModelToAstConverter/abstractions.js";
5
6
  declare class CreateEntryRevisionFromDataFactoryImpl implements ICreateEntryRevisionFromDataFactory {
6
7
  private readonly cmsContext;
7
8
  private readonly identityContext;
8
9
  private readonly accessControl;
9
- constructor(cmsContext: CmsContext.Interface, identityContext: IdentityContext.Interface, accessControl: AccessControl.Interface);
10
+ private readonly modelToAstConverter;
11
+ constructor(cmsContext: CmsContext.Interface, identityContext: IdentityContext.Interface, accessControl: AccessControl.Interface, modelToAstConverter: ModelToAstConverter.Interface);
10
12
  create<TValues extends CmsEntryValues = CmsEntryValues>(sourceId: string, model: CmsModel, rawInput: CreateCmsEntryInput<TValues>, originalEntry: CmsEntry<TValues>, latestStorageEntry: CmsEntry<TValues>, options?: CreateCmsEntryOptionsInput): Promise<ICreateEntryRevisionFromDataResponse<TValues>>;
11
13
  }
12
14
  export declare const CreateEntryRevisionFromDataFactory: import("@webiny/di").Implementation<typeof CreateEntryRevisionFromDataFactoryImpl>;
@@ -12,6 +12,8 @@ import error from "@webiny/error";
12
12
  import { STATUS_DRAFT, STATUS_PUBLISHED, STATUS_UNPUBLISHED } from "../statuses.js";
13
13
  import { NotAuthorizedError } from "../../../../utils/errors.js";
14
14
  import { getSystem } from "../system.js";
15
+ import { ModelToAstConverter } from "../../../contentModel/ModelToAstConverter/abstractions.js";
16
+ import { ensureItemIds } from "../../ensureItemIds.js";
15
17
  const increaseEntryIdVersion = (id)=>{
16
18
  const { id: entryId, version } = parseIdentifier(id);
17
19
  if (!version) throw new error("Cannot increase version on the ID without the version part.", "WRONG_ID", {
@@ -27,16 +29,19 @@ const increaseEntryIdVersion = (id)=>{
27
29
  };
28
30
  };
29
31
  class CreateEntryRevisionFromDataFactoryImpl {
30
- constructor(cmsContext, identityContext, accessControl){
32
+ constructor(cmsContext, identityContext, accessControl, modelToAstConverter){
31
33
  this.cmsContext = cmsContext;
32
34
  this.identityContext = identityContext;
33
35
  this.accessControl = accessControl;
36
+ this.modelToAstConverter = modelToAstConverter;
34
37
  }
35
38
  async create(sourceId, model, rawInput, originalEntry, latestStorageEntry, options) {
36
39
  const initialValues = {
37
40
  ...originalEntry.values,
38
41
  ...mapAndCleanUpdatedInputData(model, rawInput.values)
39
42
  };
43
+ const modelAst = this.modelToAstConverter.toAst(model);
44
+ await ensureItemIds(modelAst, initialValues);
40
45
  await validateModelEntryDataOrThrow({
41
46
  context: this.cmsContext,
42
47
  model,
@@ -141,7 +146,8 @@ const CreateEntryRevisionFromDataFactory_CreateEntryRevisionFromDataFactory = cr
141
146
  dependencies: [
142
147
  CmsContext,
143
148
  IdentityContext,
144
- AccessControl
149
+ AccessControl,
150
+ ModelToAstConverter
145
151
  ]
146
152
  });
147
153
  export { CreateEntryRevisionFromDataFactory_CreateEntryRevisionFromDataFactory as CreateEntryRevisionFromDataFactory };
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/CreateEntryRevisionFromDataFactory.js","sources":["../../../../../src/features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/CreateEntryRevisionFromDataFactory.ts"],"sourcesContent":["import { createImplementation } from \"@webiny/feature/api\";\nimport {\n CreateEntryRevisionFromDataFactory as FactoryAbstraction,\n type ICreateEntryRevisionFromDataFactory,\n type ICreateEntryRevisionFromDataResponse\n} from \"./abstractions.js\";\nimport { AccessControl, CmsContext } from \"~/features/shared/abstractions.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport type {\n CmsEntry,\n CmsEntryValues,\n CmsModel,\n CreateCmsEntryInput,\n CreateCmsEntryOptionsInput\n} from \"~/types/index.js\";\nimport { getDate } from \"~/utils/date.js\";\nimport { getIdentity } from \"~/utils/identity.js\";\nimport { mapAndCleanUpdatedInputData } from \"../mapAndCleanUpdatedInputData.js\";\nimport { validateModelEntryDataOrThrow } from \"~/crud/contentEntry/entryDataValidation.js\";\nimport { referenceFieldsMapping } from \"~/crud/contentEntry/referenceFieldsMapping.js\";\nimport { createIdentifier, parseIdentifier } from \"@webiny/utils\";\nimport WebinyError from \"@webiny/error\";\nimport { STATUS_DRAFT, STATUS_PUBLISHED, STATUS_UNPUBLISHED } from \"../statuses.js\";\nimport { NotAuthorizedError } from \"~/utils/errors.js\";\nimport { getSystem } from \"../system.js\";\n\nconst increaseEntryIdVersion = (id: string) => {\n const { id: entryId, version } = parseIdentifier(id);\n if (!version) {\n throw new WebinyError(\n \"Cannot increase version on the ID without the version part.\",\n \"WRONG_ID\",\n {\n id\n }\n );\n }\n return {\n entryId,\n version: version + 1,\n id: createIdentifier({\n id: entryId,\n version: version + 1\n })\n };\n};\n\nclass CreateEntryRevisionFromDataFactoryImpl implements ICreateEntryRevisionFromDataFactory {\n public constructor(\n private readonly cmsContext: CmsContext.Interface,\n private readonly identityContext: IdentityContext.Interface,\n private readonly accessControl: AccessControl.Interface\n ) {}\n\n public async create<TValues extends CmsEntryValues = CmsEntryValues>(\n sourceId: string,\n model: CmsModel,\n rawInput: CreateCmsEntryInput<TValues>,\n originalEntry: CmsEntry<TValues>,\n latestStorageEntry: CmsEntry<TValues>,\n options?: CreateCmsEntryOptionsInput\n ): Promise<ICreateEntryRevisionFromDataResponse<TValues>> {\n const initialValues = {\n ...originalEntry.values,\n ...mapAndCleanUpdatedInputData<TValues>(model, rawInput.values)\n };\n\n await validateModelEntryDataOrThrow({\n context: this.cmsContext,\n model,\n values: initialValues,\n entry: originalEntry,\n skipValidation: options?.skipValidation\n });\n\n const values = await referenceFieldsMapping<TValues>({\n context: this.cmsContext,\n model,\n values: initialValues,\n validateEntries: false\n });\n\n const latestId = latestStorageEntry ? latestStorageEntry.id : sourceId;\n const { id, version: nextVersion } = increaseEntryIdVersion(latestId);\n\n const currentIdentity = this.identityContext.getIdentity();\n const currentDateTime = new Date();\n\n const status = rawInput.status || STATUS_DRAFT;\n if (status !== STATUS_DRAFT) {\n if (status === STATUS_PUBLISHED) {\n const canPublish = await this.accessControl.canAccessEntry({ model, pw: \"p\" });\n if (!canPublish) {\n throw new NotAuthorizedError(\n `Not allowed to access \"${model.modelId}\" entries.`\n );\n }\n } else if (status === STATUS_UNPUBLISHED) {\n const canUnpublish = await this.accessControl.canAccessEntry({ model, pw: \"u\" });\n if (!canUnpublish) {\n throw new NotAuthorizedError(\n `Not allowed to access \"${model.modelId}\" entries.`\n );\n }\n }\n }\n\n const locked = status !== STATUS_DRAFT;\n\n let revisionLevelPublishingMetaFields: Pick<\n CmsEntry,\n | \"revisionFirstPublishedOn\"\n | \"revisionLastPublishedOn\"\n | \"revisionFirstPublishedBy\"\n | \"revisionLastPublishedBy\"\n > = {\n revisionFirstPublishedOn: getDate(rawInput.revisionFirstPublishedOn, null),\n revisionLastPublishedOn: getDate(rawInput.revisionLastPublishedOn, null),\n revisionFirstPublishedBy: getIdentity(rawInput.revisionFirstPublishedBy, null),\n revisionLastPublishedBy: getIdentity(rawInput.revisionLastPublishedBy, null)\n };\n\n let entryLevelPublishingMetaFields: Pick<\n CmsEntry,\n \"firstPublishedOn\" | \"lastPublishedOn\" | \"firstPublishedBy\" | \"lastPublishedBy\"\n > = {\n firstPublishedOn: getDate(\n rawInput.firstPublishedOn,\n latestStorageEntry.firstPublishedOn\n ),\n lastPublishedOn: getDate(rawInput.lastPublishedOn, latestStorageEntry.lastPublishedOn),\n firstPublishedBy: getIdentity(\n rawInput.firstPublishedBy,\n latestStorageEntry.firstPublishedBy\n ),\n lastPublishedBy: getIdentity(\n rawInput.lastPublishedBy,\n latestStorageEntry.lastPublishedBy\n )\n };\n\n if (status === STATUS_PUBLISHED) {\n revisionLevelPublishingMetaFields = {\n revisionFirstPublishedOn: getDate(\n rawInput.revisionFirstPublishedOn,\n currentDateTime\n ),\n revisionLastPublishedOn: getDate(rawInput.revisionLastPublishedOn, currentDateTime),\n revisionFirstPublishedBy: getIdentity(\n rawInput.revisionFirstPublishedBy,\n currentIdentity\n ),\n revisionLastPublishedBy: getIdentity(\n rawInput.revisionLastPublishedBy,\n currentIdentity\n )\n };\n\n entryLevelPublishingMetaFields = {\n firstPublishedOn: getDate(\n rawInput.firstPublishedOn,\n latestStorageEntry.firstPublishedOn\n ),\n lastPublishedOn: getDate(rawInput.lastPublishedOn, currentDateTime),\n firstPublishedBy: getIdentity(\n rawInput.firstPublishedBy,\n latestStorageEntry.firstPublishedBy\n ),\n lastPublishedBy: getIdentity(rawInput.lastPublishedBy, currentIdentity)\n };\n }\n\n const entry: CmsEntry<TValues> = {\n ...originalEntry,\n id,\n version: nextVersion,\n createdOn: getDate(rawInput.createdOn, latestStorageEntry.createdOn),\n savedOn: getDate(rawInput.savedOn, currentDateTime),\n modifiedOn: getDate(rawInput.modifiedOn, currentDateTime),\n createdBy: getIdentity(rawInput.createdBy, latestStorageEntry.createdBy)!,\n savedBy: getIdentity(rawInput.savedBy, currentIdentity)!,\n modifiedBy: getIdentity(rawInput.modifiedBy, currentIdentity),\n ...entryLevelPublishingMetaFields,\n revisionCreatedOn: getDate(rawInput.revisionCreatedOn, currentDateTime),\n revisionSavedOn: getDate(rawInput.revisionSavedOn, currentDateTime),\n revisionModifiedOn: getDate(rawInput.revisionModifiedOn, null),\n revisionCreatedBy: getIdentity(rawInput.revisionCreatedBy, currentIdentity)!,\n revisionSavedBy: getIdentity(rawInput.revisionSavedBy, currentIdentity)!,\n revisionModifiedBy: getIdentity(rawInput.revisionModifiedBy, null),\n revisionDescription: undefined,\n ...revisionLevelPublishingMetaFields,\n locked,\n status,\n values,\n system: getSystem({\n input: rawInput,\n original: originalEntry\n }),\n live: originalEntry.live,\n expiresAt: null\n };\n\n return {\n entry,\n input: {\n ...rawInput,\n values: structuredClone(values)\n }\n };\n }\n}\n\nexport const CreateEntryRevisionFromDataFactory = createImplementation({\n abstraction: FactoryAbstraction,\n implementation: CreateEntryRevisionFromDataFactoryImpl,\n dependencies: [CmsContext, IdentityContext, AccessControl]\n});\n"],"names":["increaseEntryIdVersion","id","entryId","version","parseIdentifier","WebinyError","createIdentifier","CreateEntryRevisionFromDataFactoryImpl","cmsContext","identityContext","accessControl","sourceId","model","rawInput","originalEntry","latestStorageEntry","options","initialValues","mapAndCleanUpdatedInputData","validateModelEntryDataOrThrow","values","referenceFieldsMapping","latestId","nextVersion","currentIdentity","currentDateTime","Date","status","STATUS_DRAFT","STATUS_PUBLISHED","canPublish","NotAuthorizedError","STATUS_UNPUBLISHED","canUnpublish","locked","revisionLevelPublishingMetaFields","getDate","getIdentity","entryLevelPublishingMetaFields","entry","undefined","getSystem","structuredClone","CreateEntryRevisionFromDataFactory","createImplementation","FactoryAbstraction","CmsContext","IdentityContext","AccessControl"],"mappings":"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"}
1
+ {"version":3,"file":"features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/CreateEntryRevisionFromDataFactory.js","sources":["../../../../../src/features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/CreateEntryRevisionFromDataFactory.ts"],"sourcesContent":["import { createImplementation } from \"@webiny/feature/api\";\nimport {\n CreateEntryRevisionFromDataFactory as FactoryAbstraction,\n type ICreateEntryRevisionFromDataFactory,\n type ICreateEntryRevisionFromDataResponse\n} from \"./abstractions.js\";\nimport { AccessControl, CmsContext } from \"~/features/shared/abstractions.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport type {\n CmsEntry,\n CmsEntryValues,\n CmsModel,\n CreateCmsEntryInput,\n CreateCmsEntryOptionsInput\n} from \"~/types/index.js\";\nimport { getDate } from \"~/utils/date.js\";\nimport { getIdentity } from \"~/utils/identity.js\";\nimport { mapAndCleanUpdatedInputData } from \"../mapAndCleanUpdatedInputData.js\";\nimport { validateModelEntryDataOrThrow } from \"~/crud/contentEntry/entryDataValidation.js\";\nimport { referenceFieldsMapping } from \"~/crud/contentEntry/referenceFieldsMapping.js\";\nimport { createIdentifier, parseIdentifier } from \"@webiny/utils\";\nimport WebinyError from \"@webiny/error\";\nimport { STATUS_DRAFT, STATUS_PUBLISHED, STATUS_UNPUBLISHED } from \"../statuses.js\";\nimport { NotAuthorizedError } from \"~/utils/errors.js\";\nimport { getSystem } from \"../system.js\";\nimport { ModelToAstConverter } from \"~/features/contentModel/ModelToAstConverter/abstractions.js\";\nimport { ensureItemIds } from \"../../ensureItemIds.js\";\n\nconst increaseEntryIdVersion = (id: string) => {\n const { id: entryId, version } = parseIdentifier(id);\n if (!version) {\n throw new WebinyError(\n \"Cannot increase version on the ID without the version part.\",\n \"WRONG_ID\",\n {\n id\n }\n );\n }\n return {\n entryId,\n version: version + 1,\n id: createIdentifier({\n id: entryId,\n version: version + 1\n })\n };\n};\n\nclass CreateEntryRevisionFromDataFactoryImpl implements ICreateEntryRevisionFromDataFactory {\n public constructor(\n private readonly cmsContext: CmsContext.Interface,\n private readonly identityContext: IdentityContext.Interface,\n private readonly accessControl: AccessControl.Interface,\n private readonly modelToAstConverter: ModelToAstConverter.Interface\n ) {}\n\n public async create<TValues extends CmsEntryValues = CmsEntryValues>(\n sourceId: string,\n model: CmsModel,\n rawInput: CreateCmsEntryInput<TValues>,\n originalEntry: CmsEntry<TValues>,\n latestStorageEntry: CmsEntry<TValues>,\n options?: CreateCmsEntryOptionsInput\n ): Promise<ICreateEntryRevisionFromDataResponse<TValues>> {\n const initialValues = {\n ...originalEntry.values,\n ...mapAndCleanUpdatedInputData<TValues>(model, rawInput.values)\n };\n\n const modelAst = this.modelToAstConverter.toAst(model);\n await ensureItemIds(modelAst, initialValues);\n\n await validateModelEntryDataOrThrow({\n context: this.cmsContext,\n model,\n values: initialValues,\n entry: originalEntry,\n skipValidation: options?.skipValidation\n });\n\n const values = await referenceFieldsMapping<TValues>({\n context: this.cmsContext,\n model,\n values: initialValues,\n validateEntries: false\n });\n\n const latestId = latestStorageEntry ? latestStorageEntry.id : sourceId;\n const { id, version: nextVersion } = increaseEntryIdVersion(latestId);\n\n const currentIdentity = this.identityContext.getIdentity();\n const currentDateTime = new Date();\n\n const status = rawInput.status || STATUS_DRAFT;\n if (status !== STATUS_DRAFT) {\n if (status === STATUS_PUBLISHED) {\n const canPublish = await this.accessControl.canAccessEntry({ model, pw: \"p\" });\n if (!canPublish) {\n throw new NotAuthorizedError(\n `Not allowed to access \"${model.modelId}\" entries.`\n );\n }\n } else if (status === STATUS_UNPUBLISHED) {\n const canUnpublish = await this.accessControl.canAccessEntry({ model, pw: \"u\" });\n if (!canUnpublish) {\n throw new NotAuthorizedError(\n `Not allowed to access \"${model.modelId}\" entries.`\n );\n }\n }\n }\n\n const locked = status !== STATUS_DRAFT;\n\n let revisionLevelPublishingMetaFields: Pick<\n CmsEntry,\n | \"revisionFirstPublishedOn\"\n | \"revisionLastPublishedOn\"\n | \"revisionFirstPublishedBy\"\n | \"revisionLastPublishedBy\"\n > = {\n revisionFirstPublishedOn: getDate(rawInput.revisionFirstPublishedOn, null),\n revisionLastPublishedOn: getDate(rawInput.revisionLastPublishedOn, null),\n revisionFirstPublishedBy: getIdentity(rawInput.revisionFirstPublishedBy, null),\n revisionLastPublishedBy: getIdentity(rawInput.revisionLastPublishedBy, null)\n };\n\n let entryLevelPublishingMetaFields: Pick<\n CmsEntry,\n \"firstPublishedOn\" | \"lastPublishedOn\" | \"firstPublishedBy\" | \"lastPublishedBy\"\n > = {\n firstPublishedOn: getDate(\n rawInput.firstPublishedOn,\n latestStorageEntry.firstPublishedOn\n ),\n lastPublishedOn: getDate(rawInput.lastPublishedOn, latestStorageEntry.lastPublishedOn),\n firstPublishedBy: getIdentity(\n rawInput.firstPublishedBy,\n latestStorageEntry.firstPublishedBy\n ),\n lastPublishedBy: getIdentity(\n rawInput.lastPublishedBy,\n latestStorageEntry.lastPublishedBy\n )\n };\n\n if (status === STATUS_PUBLISHED) {\n revisionLevelPublishingMetaFields = {\n revisionFirstPublishedOn: getDate(\n rawInput.revisionFirstPublishedOn,\n currentDateTime\n ),\n revisionLastPublishedOn: getDate(rawInput.revisionLastPublishedOn, currentDateTime),\n revisionFirstPublishedBy: getIdentity(\n rawInput.revisionFirstPublishedBy,\n currentIdentity\n ),\n revisionLastPublishedBy: getIdentity(\n rawInput.revisionLastPublishedBy,\n currentIdentity\n )\n };\n\n entryLevelPublishingMetaFields = {\n firstPublishedOn: getDate(\n rawInput.firstPublishedOn,\n latestStorageEntry.firstPublishedOn\n ),\n lastPublishedOn: getDate(rawInput.lastPublishedOn, currentDateTime),\n firstPublishedBy: getIdentity(\n rawInput.firstPublishedBy,\n latestStorageEntry.firstPublishedBy\n ),\n lastPublishedBy: getIdentity(rawInput.lastPublishedBy, currentIdentity)\n };\n }\n\n const entry: CmsEntry<TValues> = {\n ...originalEntry,\n id,\n version: nextVersion,\n createdOn: getDate(rawInput.createdOn, latestStorageEntry.createdOn),\n savedOn: getDate(rawInput.savedOn, currentDateTime),\n modifiedOn: getDate(rawInput.modifiedOn, currentDateTime),\n createdBy: getIdentity(rawInput.createdBy, latestStorageEntry.createdBy)!,\n savedBy: getIdentity(rawInput.savedBy, currentIdentity)!,\n modifiedBy: getIdentity(rawInput.modifiedBy, currentIdentity),\n ...entryLevelPublishingMetaFields,\n revisionCreatedOn: getDate(rawInput.revisionCreatedOn, currentDateTime),\n revisionSavedOn: getDate(rawInput.revisionSavedOn, currentDateTime),\n revisionModifiedOn: getDate(rawInput.revisionModifiedOn, null),\n revisionCreatedBy: getIdentity(rawInput.revisionCreatedBy, currentIdentity)!,\n revisionSavedBy: getIdentity(rawInput.revisionSavedBy, currentIdentity)!,\n revisionModifiedBy: getIdentity(rawInput.revisionModifiedBy, null),\n revisionDescription: undefined,\n ...revisionLevelPublishingMetaFields,\n locked,\n status,\n values,\n system: getSystem({\n input: rawInput,\n original: originalEntry\n }),\n live: originalEntry.live,\n expiresAt: null\n };\n\n return {\n entry,\n input: {\n ...rawInput,\n values: structuredClone(values)\n }\n };\n }\n}\n\nexport const CreateEntryRevisionFromDataFactory = createImplementation({\n abstraction: FactoryAbstraction,\n implementation: CreateEntryRevisionFromDataFactoryImpl,\n dependencies: [CmsContext, IdentityContext, AccessControl, ModelToAstConverter]\n});\n"],"names":["increaseEntryIdVersion","id","entryId","version","parseIdentifier","WebinyError","createIdentifier","CreateEntryRevisionFromDataFactoryImpl","cmsContext","identityContext","accessControl","modelToAstConverter","sourceId","model","rawInput","originalEntry","latestStorageEntry","options","initialValues","mapAndCleanUpdatedInputData","modelAst","ensureItemIds","validateModelEntryDataOrThrow","values","referenceFieldsMapping","latestId","nextVersion","currentIdentity","currentDateTime","Date","status","STATUS_DRAFT","STATUS_PUBLISHED","canPublish","NotAuthorizedError","STATUS_UNPUBLISHED","canUnpublish","locked","revisionLevelPublishingMetaFields","getDate","getIdentity","entryLevelPublishingMetaFields","entry","undefined","getSystem","structuredClone","CreateEntryRevisionFromDataFactory","createImplementation","FactoryAbstraction","CmsContext","IdentityContext","AccessControl","ModelToAstConverter"],"mappings":";;;;;;;;;;;;;;;;AA4BA,MAAMA,yBAAyB,CAACC;IAC5B,MAAM,EAAE,IAAIC,OAAO,EAAEC,OAAO,EAAE,GAAGC,gBAAgBH;IACjD,IAAI,CAACE,SACD,MAAM,IAAIE,MACN,+DACA,YACA;QACIJ;IACJ;IAGR,OAAO;QACHC;QACA,SAASC,UAAU;QACnB,IAAIG,iBAAiB;YACjB,IAAIJ;YACJ,SAASC,UAAU;QACvB;IACJ;AACJ;AAEA,MAAMI;IACF,YACqBC,UAAgC,EAChCC,eAA0C,EAC1CC,aAAsC,EACtCC,mBAAkD,CACrE;aAJmBH,UAAU,GAAVA;aACAC,eAAe,GAAfA;aACAC,aAAa,GAAbA;aACAC,mBAAmB,GAAnBA;IAClB;IAEH,MAAa,OACTC,QAAgB,EAChBC,KAAe,EACfC,QAAsC,EACtCC,aAAgC,EAChCC,kBAAqC,EACrCC,OAAoC,EACkB;QACtD,MAAMC,gBAAgB;YAClB,GAAGH,cAAc,MAAM;YACvB,GAAGI,4BAAqCN,OAAOC,SAAS,MAAM,CAAC;QACnE;QAEA,MAAMM,WAAW,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAACP;QAChD,MAAMQ,cAAcD,UAAUF;QAE9B,MAAMI,8BAA8B;YAChC,SAAS,IAAI,CAAC,UAAU;YACxBT;YACA,QAAQK;YACR,OAAOH;YACP,gBAAgBE,SAAS;QAC7B;QAEA,MAAMM,SAAS,MAAMC,uBAAgC;YACjD,SAAS,IAAI,CAAC,UAAU;YACxBX;YACA,QAAQK;YACR,iBAAiB;QACrB;QAEA,MAAMO,WAAWT,qBAAqBA,mBAAmB,EAAE,GAAGJ;QAC9D,MAAM,EAAEX,EAAE,EAAE,SAASyB,WAAW,EAAE,GAAG1B,uBAAuByB;QAE5D,MAAME,kBAAkB,IAAI,CAAC,eAAe,CAAC,WAAW;QACxD,MAAMC,kBAAkB,IAAIC;QAE5B,MAAMC,SAAShB,SAAS,MAAM,IAAIiB;QAClC,IAAID,WAAWC,cACX;YAAA,IAAID,WAAWE,kBAAkB;gBAC7B,MAAMC,aAAa,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;oBAAEpB;oBAAO,IAAI;gBAAI;gBAC5E,IAAI,CAACoB,YACD,MAAM,IAAIC,mBACN,CAAC,uBAAuB,EAAErB,MAAM,OAAO,CAAC,UAAU,CAAC;YAG/D,OAAO,IAAIiB,WAAWK,oBAAoB;gBACtC,MAAMC,eAAe,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;oBAAEvB;oBAAO,IAAI;gBAAI;gBAC9E,IAAI,CAACuB,cACD,MAAM,IAAIF,mBACN,CAAC,uBAAuB,EAAErB,MAAM,OAAO,CAAC,UAAU,CAAC;YAG/D;QAAA;QAGJ,MAAMwB,SAASP,WAAWC;QAE1B,IAAIO,oCAMA;YACA,0BAA0BC,QAAQzB,SAAS,wBAAwB,EAAE;YACrE,yBAAyByB,QAAQzB,SAAS,uBAAuB,EAAE;YACnE,0BAA0B0B,YAAY1B,SAAS,wBAAwB,EAAE;YACzE,yBAAyB0B,YAAY1B,SAAS,uBAAuB,EAAE;QAC3E;QAEA,IAAI2B,iCAGA;YACA,kBAAkBF,QACdzB,SAAS,gBAAgB,EACzBE,mBAAmB,gBAAgB;YAEvC,iBAAiBuB,QAAQzB,SAAS,eAAe,EAAEE,mBAAmB,eAAe;YACrF,kBAAkBwB,YACd1B,SAAS,gBAAgB,EACzBE,mBAAmB,gBAAgB;YAEvC,iBAAiBwB,YACb1B,SAAS,eAAe,EACxBE,mBAAmB,eAAe;QAE1C;QAEA,IAAIc,WAAWE,kBAAkB;YAC7BM,oCAAoC;gBAChC,0BAA0BC,QACtBzB,SAAS,wBAAwB,EACjCc;gBAEJ,yBAAyBW,QAAQzB,SAAS,uBAAuB,EAAEc;gBACnE,0BAA0BY,YACtB1B,SAAS,wBAAwB,EACjCa;gBAEJ,yBAAyBa,YACrB1B,SAAS,uBAAuB,EAChCa;YAER;YAEAc,iCAAiC;gBAC7B,kBAAkBF,QACdzB,SAAS,gBAAgB,EACzBE,mBAAmB,gBAAgB;gBAEvC,iBAAiBuB,QAAQzB,SAAS,eAAe,EAAEc;gBACnD,kBAAkBY,YACd1B,SAAS,gBAAgB,EACzBE,mBAAmB,gBAAgB;gBAEvC,iBAAiBwB,YAAY1B,SAAS,eAAe,EAAEa;YAC3D;QACJ;QAEA,MAAMe,QAA2B;YAC7B,GAAG3B,aAAa;YAChBd;YACA,SAASyB;YACT,WAAWa,QAAQzB,SAAS,SAAS,EAAEE,mBAAmB,SAAS;YACnE,SAASuB,QAAQzB,SAAS,OAAO,EAAEc;YACnC,YAAYW,QAAQzB,SAAS,UAAU,EAAEc;YACzC,WAAWY,YAAY1B,SAAS,SAAS,EAAEE,mBAAmB,SAAS;YACvE,SAASwB,YAAY1B,SAAS,OAAO,EAAEa;YACvC,YAAYa,YAAY1B,SAAS,UAAU,EAAEa;YAC7C,GAAGc,8BAA8B;YACjC,mBAAmBF,QAAQzB,SAAS,iBAAiB,EAAEc;YACvD,iBAAiBW,QAAQzB,SAAS,eAAe,EAAEc;YACnD,oBAAoBW,QAAQzB,SAAS,kBAAkB,EAAE;YACzD,mBAAmB0B,YAAY1B,SAAS,iBAAiB,EAAEa;YAC3D,iBAAiBa,YAAY1B,SAAS,eAAe,EAAEa;YACvD,oBAAoBa,YAAY1B,SAAS,kBAAkB,EAAE;YAC7D,qBAAqB6B;YACrB,GAAGL,iCAAiC;YACpCD;YACAP;YACAP;YACA,QAAQqB,UAAU;gBACd,OAAO9B;gBACP,UAAUC;YACd;YACA,MAAMA,cAAc,IAAI;YACxB,WAAW;QACf;QAEA,OAAO;YACH2B;YACA,OAAO;gBACH,GAAG5B,QAAQ;gBACX,QAAQ+B,gBAAgBtB;YAC5B;QACJ;IACJ;AACJ;AAEO,MAAMuB,wEAAqCC,qBAAqB;IACnE,aAAaC;IACb,gBAAgBzC;IAChB,cAAc;QAAC0C;QAAYC;QAAiBC;QAAeC;KAAoB;AACnF"}
@@ -2,10 +2,12 @@ import { type IUpdateEntryDataFactory, type IUpdateEntryDataResponse } from "./a
2
2
  import { CmsContext } from "../../../../features/shared/abstractions.js";
3
3
  import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
4
4
  import type { CmsEntry, CmsEntryValues, CmsModel, UpdateCmsEntryInput, UpdateCmsEntryOptionsInput } from "../../../../types/index.js";
5
+ import { ModelToAstConverter } from "../../../../features/contentModel/ModelToAstConverter/abstractions.js";
5
6
  declare class UpdateEntryDataFactoryImpl implements IUpdateEntryDataFactory {
6
7
  private readonly cmsContext;
7
8
  private readonly identityContext;
8
- constructor(cmsContext: CmsContext.Interface, identityContext: IdentityContext.Interface);
9
+ private readonly modelToAstConverter;
10
+ constructor(cmsContext: CmsContext.Interface, identityContext: IdentityContext.Interface, modelToAstConverter: ModelToAstConverter.Interface);
9
11
  create<TValues extends CmsEntryValues = CmsEntryValues>(model: CmsModel, rawInput: UpdateCmsEntryInput<TValues>, originalEntry: CmsEntry<TValues>, options?: UpdateCmsEntryOptionsInput): Promise<IUpdateEntryDataResponse<TValues>>;
10
12
  }
11
13
  export declare const UpdateEntryDataFactory: import("@webiny/di").Implementation<typeof UpdateEntryDataFactoryImpl>;
@@ -9,6 +9,8 @@ import { referenceFieldsMapping } from "../../../../crud/contentEntry/referenceF
9
9
  import { mapAndCleanUpdatedInputData } from "../mapAndCleanUpdatedInputData.js";
10
10
  import { getSystem } from "../system.js";
11
11
  import { getExpiresAt } from "../expiresAt.js";
12
+ import { ModelToAstConverter } from "../../../contentModel/ModelToAstConverter/abstractions.js";
13
+ import { ensureItemIds } from "../../ensureItemIds.js";
12
14
  const allowedEntryStatus = [
13
15
  "draft",
14
16
  "published",
@@ -16,9 +18,10 @@ const allowedEntryStatus = [
16
18
  ];
17
19
  const transformEntryStatus = (status)=>allowedEntryStatus.includes(status) ? status : "draft";
18
20
  class UpdateEntryDataFactoryImpl {
19
- constructor(cmsContext, identityContext){
21
+ constructor(cmsContext, identityContext, modelToAstConverter){
20
22
  this.cmsContext = cmsContext;
21
23
  this.identityContext = identityContext;
24
+ this.modelToAstConverter = modelToAstConverter;
22
25
  }
23
26
  async create(model, rawInput, originalEntry, options) {
24
27
  const cleanedValues = mapAndCleanUpdatedInputData(model, rawInput?.values || {});
@@ -33,6 +36,8 @@ class UpdateEntryDataFactoryImpl {
33
36
  ...originalEntry.values,
34
37
  ...cleanedValues
35
38
  };
39
+ const modelAst = this.modelToAstConverter.toAst(model);
40
+ await ensureItemIds(modelAst, mergedValues);
36
41
  const values = await referenceFieldsMapping({
37
42
  context: this.cmsContext,
38
43
  model,
@@ -100,7 +105,8 @@ const UpdateEntryDataFactory_UpdateEntryDataFactory = createImplementation({
100
105
  implementation: UpdateEntryDataFactoryImpl,
101
106
  dependencies: [
102
107
  CmsContext,
103
- IdentityContext
108
+ IdentityContext,
109
+ ModelToAstConverter
104
110
  ]
105
111
  });
106
112
  export { UpdateEntryDataFactory_UpdateEntryDataFactory as UpdateEntryDataFactory };
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentEntry/entryDataFactories/UpdateEntryDataFactory/UpdateEntryDataFactory.js","sources":["../../../../../src/features/contentEntry/entryDataFactories/UpdateEntryDataFactory/UpdateEntryDataFactory.ts"],"sourcesContent":["import { createImplementation } from \"@webiny/feature/api\";\nimport {\n type IUpdateEntryDataFactory,\n type IUpdateEntryDataResponse,\n UpdateEntryDataFactory as FactoryAbstraction\n} from \"./abstractions.js\";\nimport { CmsContext } from \"~/features/shared/abstractions.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport type {\n CmsEntry,\n CmsEntryStatus,\n CmsEntryValues,\n CmsModel,\n UpdateCmsEntryInput,\n UpdateCmsEntryOptionsInput\n} from \"~/types/index.js\";\nimport { getDate } from \"~/utils/date.js\";\nimport { getIdentity } from \"~/utils/identity.js\";\nimport { validateModelEntryDataOrThrow } from \"~/crud/contentEntry/entryDataValidation.js\";\nimport { referenceFieldsMapping } from \"~/crud/contentEntry/referenceFieldsMapping.js\";\nimport { mapAndCleanUpdatedInputData } from \"../mapAndCleanUpdatedInputData.js\";\nimport { getSystem } from \"../system.js\";\nimport { getExpiresAt } from \"../expiresAt.js\";\n\nconst allowedEntryStatus: string[] = [\"draft\", \"published\", \"unpublished\"];\n\nconst transformEntryStatus = (status: CmsEntryStatus | string): CmsEntryStatus => {\n return allowedEntryStatus.includes(status) ? (status as CmsEntryStatus) : \"draft\";\n};\n\nclass UpdateEntryDataFactoryImpl implements IUpdateEntryDataFactory {\n public constructor(\n private readonly cmsContext: CmsContext.Interface,\n private readonly identityContext: IdentityContext.Interface\n ) {}\n\n public async create<TValues extends CmsEntryValues = CmsEntryValues>(\n model: CmsModel,\n rawInput: UpdateCmsEntryInput<TValues>,\n originalEntry: CmsEntry<TValues>,\n options?: UpdateCmsEntryOptionsInput\n ): Promise<IUpdateEntryDataResponse<TValues>> {\n const cleanedValues = mapAndCleanUpdatedInputData<TValues>(\n model,\n rawInput?.values || ({} as TValues)\n );\n\n await validateModelEntryDataOrThrow({\n context: this.cmsContext,\n model,\n values: cleanedValues,\n entry: originalEntry,\n skipValidation: options?.skipValidation\n });\n\n const mergedValues: TValues = {\n ...originalEntry.values,\n ...cleanedValues\n };\n\n const values = await referenceFieldsMapping<TValues>({\n context: this.cmsContext,\n model,\n values: mergedValues,\n validateEntries: false\n });\n\n const currentIdentity = this.identityContext.getIdentity();\n const currentDateTime = new Date();\n\n const entry: CmsEntry<TValues> = {\n ...originalEntry,\n revisionCreatedOn: getDate(rawInput.revisionCreatedOn, originalEntry.revisionCreatedOn),\n revisionModifiedOn: getDate(rawInput.revisionModifiedOn, currentDateTime),\n revisionSavedOn: getDate(rawInput.revisionSavedOn, currentDateTime),\n revisionDeletedOn: getDate(rawInput.revisionDeletedOn, null),\n revisionRestoredOn: getDate(rawInput.revisionRestoredOn, null),\n revisionFirstPublishedOn: getDate(\n rawInput.revisionFirstPublishedOn,\n originalEntry.revisionFirstPublishedOn\n ),\n revisionLastPublishedOn: getDate(\n rawInput.revisionLastPublishedOn,\n originalEntry.revisionLastPublishedOn\n ),\n revisionCreatedBy: getIdentity(\n rawInput.revisionCreatedBy,\n originalEntry.revisionCreatedBy\n )!,\n revisionModifiedBy: getIdentity(rawInput.revisionModifiedBy, currentIdentity),\n revisionSavedBy: getIdentity(rawInput.revisionSavedBy, currentIdentity)!,\n revisionDeletedBy: getIdentity(rawInput.revisionSavedBy, null),\n revisionRestoredBy: getIdentity(rawInput.revisionRestoredBy, null),\n revisionFirstPublishedBy: getIdentity(\n rawInput.revisionFirstPublishedBy,\n originalEntry.revisionFirstPublishedBy\n ),\n revisionLastPublishedBy: getIdentity(\n rawInput.revisionLastPublishedBy,\n originalEntry.revisionLastPublishedBy\n ),\n createdOn: getDate(rawInput.createdOn, originalEntry.createdOn),\n savedOn: getDate(rawInput.savedOn, currentDateTime),\n modifiedOn: getDate(rawInput.modifiedOn, currentDateTime),\n deletedOn: getDate(rawInput.deletedOn, null),\n restoredOn: getDate(rawInput.restoredOn, null),\n firstPublishedOn: getDate(rawInput.firstPublishedOn, originalEntry.firstPublishedOn),\n lastPublishedOn: getDate(rawInput.lastPublishedOn, originalEntry.lastPublishedOn),\n createdBy: getIdentity(rawInput.createdBy, originalEntry.createdBy)!,\n savedBy: getIdentity(rawInput.savedBy, currentIdentity)!,\n modifiedBy: getIdentity(rawInput.modifiedBy, currentIdentity),\n deletedBy: getIdentity(rawInput.deletedBy, null),\n restoredBy: getIdentity(rawInput.restoredBy, null),\n firstPublishedBy: getIdentity(\n rawInput.firstPublishedBy,\n originalEntry.firstPublishedBy\n ),\n lastPublishedBy: getIdentity(rawInput.lastPublishedBy, originalEntry.lastPublishedBy),\n values,\n status: transformEntryStatus(originalEntry.status),\n system: getSystem({\n input: rawInput,\n original: originalEntry\n }),\n live: originalEntry.live,\n expiresAt: getExpiresAt({ expiresAt: rawInput.expiresAt }, originalEntry)\n };\n\n const folderId = rawInput.wbyAco_location?.folderId;\n if (folderId) {\n entry.location = {\n folderId\n };\n }\n\n return {\n entry,\n input: {\n ...rawInput,\n values: structuredClone(values)\n }\n };\n }\n}\n\nexport const UpdateEntryDataFactory = createImplementation({\n abstraction: FactoryAbstraction,\n implementation: UpdateEntryDataFactoryImpl,\n dependencies: [CmsContext, IdentityContext]\n});\n"],"names":["allowedEntryStatus","transformEntryStatus","status","UpdateEntryDataFactoryImpl","cmsContext","identityContext","model","rawInput","originalEntry","options","cleanedValues","mapAndCleanUpdatedInputData","validateModelEntryDataOrThrow","mergedValues","values","referenceFieldsMapping","currentIdentity","currentDateTime","Date","entry","getDate","getIdentity","getSystem","getExpiresAt","folderId","structuredClone","UpdateEntryDataFactory","createImplementation","FactoryAbstraction","CmsContext","IdentityContext"],"mappings":"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"}
1
+ {"version":3,"file":"features/contentEntry/entryDataFactories/UpdateEntryDataFactory/UpdateEntryDataFactory.js","sources":["../../../../../src/features/contentEntry/entryDataFactories/UpdateEntryDataFactory/UpdateEntryDataFactory.ts"],"sourcesContent":["import { createImplementation } from \"@webiny/feature/api\";\nimport {\n type IUpdateEntryDataFactory,\n type IUpdateEntryDataResponse,\n UpdateEntryDataFactory as FactoryAbstraction\n} from \"./abstractions.js\";\nimport { CmsContext } from \"~/features/shared/abstractions.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport type {\n CmsEntry,\n CmsEntryStatus,\n CmsEntryValues,\n CmsModel,\n UpdateCmsEntryInput,\n UpdateCmsEntryOptionsInput\n} from \"~/types/index.js\";\nimport { getDate } from \"~/utils/date.js\";\nimport { getIdentity } from \"~/utils/identity.js\";\nimport { validateModelEntryDataOrThrow } from \"~/crud/contentEntry/entryDataValidation.js\";\nimport { referenceFieldsMapping } from \"~/crud/contentEntry/referenceFieldsMapping.js\";\nimport { mapAndCleanUpdatedInputData } from \"../mapAndCleanUpdatedInputData.js\";\nimport { getSystem } from \"../system.js\";\nimport { getExpiresAt } from \"../expiresAt.js\";\nimport { ModelToAstConverter } from \"~/features/contentModel/ModelToAstConverter/abstractions.js\";\nimport { ensureItemIds } from \"../../ensureItemIds.js\";\n\nconst allowedEntryStatus: string[] = [\"draft\", \"published\", \"unpublished\"];\n\nconst transformEntryStatus = (status: CmsEntryStatus | string): CmsEntryStatus => {\n return allowedEntryStatus.includes(status) ? (status as CmsEntryStatus) : \"draft\";\n};\n\nclass UpdateEntryDataFactoryImpl implements IUpdateEntryDataFactory {\n public constructor(\n private readonly cmsContext: CmsContext.Interface,\n private readonly identityContext: IdentityContext.Interface,\n private readonly modelToAstConverter: ModelToAstConverter.Interface\n ) {}\n\n public async create<TValues extends CmsEntryValues = CmsEntryValues>(\n model: CmsModel,\n rawInput: UpdateCmsEntryInput<TValues>,\n originalEntry: CmsEntry<TValues>,\n options?: UpdateCmsEntryOptionsInput\n ): Promise<IUpdateEntryDataResponse<TValues>> {\n const cleanedValues = mapAndCleanUpdatedInputData<TValues>(\n model,\n rawInput?.values || ({} as TValues)\n );\n\n await validateModelEntryDataOrThrow({\n context: this.cmsContext,\n model,\n values: cleanedValues,\n entry: originalEntry,\n skipValidation: options?.skipValidation\n });\n\n const mergedValues: TValues = {\n ...originalEntry.values,\n ...cleanedValues\n };\n\n const modelAst = this.modelToAstConverter.toAst(model);\n await ensureItemIds(modelAst, mergedValues);\n\n const values = await referenceFieldsMapping<TValues>({\n context: this.cmsContext,\n model,\n values: mergedValues,\n validateEntries: false\n });\n\n const currentIdentity = this.identityContext.getIdentity();\n const currentDateTime = new Date();\n\n const entry: CmsEntry<TValues> = {\n ...originalEntry,\n revisionCreatedOn: getDate(rawInput.revisionCreatedOn, originalEntry.revisionCreatedOn),\n revisionModifiedOn: getDate(rawInput.revisionModifiedOn, currentDateTime),\n revisionSavedOn: getDate(rawInput.revisionSavedOn, currentDateTime),\n revisionDeletedOn: getDate(rawInput.revisionDeletedOn, null),\n revisionRestoredOn: getDate(rawInput.revisionRestoredOn, null),\n revisionFirstPublishedOn: getDate(\n rawInput.revisionFirstPublishedOn,\n originalEntry.revisionFirstPublishedOn\n ),\n revisionLastPublishedOn: getDate(\n rawInput.revisionLastPublishedOn,\n originalEntry.revisionLastPublishedOn\n ),\n revisionCreatedBy: getIdentity(\n rawInput.revisionCreatedBy,\n originalEntry.revisionCreatedBy\n )!,\n revisionModifiedBy: getIdentity(rawInput.revisionModifiedBy, currentIdentity),\n revisionSavedBy: getIdentity(rawInput.revisionSavedBy, currentIdentity)!,\n revisionDeletedBy: getIdentity(rawInput.revisionSavedBy, null),\n revisionRestoredBy: getIdentity(rawInput.revisionRestoredBy, null),\n revisionFirstPublishedBy: getIdentity(\n rawInput.revisionFirstPublishedBy,\n originalEntry.revisionFirstPublishedBy\n ),\n revisionLastPublishedBy: getIdentity(\n rawInput.revisionLastPublishedBy,\n originalEntry.revisionLastPublishedBy\n ),\n createdOn: getDate(rawInput.createdOn, originalEntry.createdOn),\n savedOn: getDate(rawInput.savedOn, currentDateTime),\n modifiedOn: getDate(rawInput.modifiedOn, currentDateTime),\n deletedOn: getDate(rawInput.deletedOn, null),\n restoredOn: getDate(rawInput.restoredOn, null),\n firstPublishedOn: getDate(rawInput.firstPublishedOn, originalEntry.firstPublishedOn),\n lastPublishedOn: getDate(rawInput.lastPublishedOn, originalEntry.lastPublishedOn),\n createdBy: getIdentity(rawInput.createdBy, originalEntry.createdBy)!,\n savedBy: getIdentity(rawInput.savedBy, currentIdentity)!,\n modifiedBy: getIdentity(rawInput.modifiedBy, currentIdentity),\n deletedBy: getIdentity(rawInput.deletedBy, null),\n restoredBy: getIdentity(rawInput.restoredBy, null),\n firstPublishedBy: getIdentity(\n rawInput.firstPublishedBy,\n originalEntry.firstPublishedBy\n ),\n lastPublishedBy: getIdentity(rawInput.lastPublishedBy, originalEntry.lastPublishedBy),\n values,\n status: transformEntryStatus(originalEntry.status),\n system: getSystem({\n input: rawInput,\n original: originalEntry\n }),\n live: originalEntry.live,\n expiresAt: getExpiresAt({ expiresAt: rawInput.expiresAt }, originalEntry)\n };\n\n const folderId = rawInput.wbyAco_location?.folderId;\n if (folderId) {\n entry.location = {\n folderId\n };\n }\n\n return {\n entry,\n input: {\n ...rawInput,\n values: structuredClone(values)\n }\n };\n }\n}\n\nexport const UpdateEntryDataFactory = createImplementation({\n abstraction: FactoryAbstraction,\n implementation: UpdateEntryDataFactoryImpl,\n dependencies: [CmsContext, IdentityContext, ModelToAstConverter]\n});\n"],"names":["allowedEntryStatus","transformEntryStatus","status","UpdateEntryDataFactoryImpl","cmsContext","identityContext","modelToAstConverter","model","rawInput","originalEntry","options","cleanedValues","mapAndCleanUpdatedInputData","validateModelEntryDataOrThrow","mergedValues","modelAst","ensureItemIds","values","referenceFieldsMapping","currentIdentity","currentDateTime","Date","entry","getDate","getIdentity","getSystem","getExpiresAt","folderId","structuredClone","UpdateEntryDataFactory","createImplementation","FactoryAbstraction","CmsContext","IdentityContext","ModelToAstConverter"],"mappings":"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"}
@@ -6,6 +6,7 @@ import { CmsContext, StorageOperations } from "../../../features/shared/abstract
6
6
  import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
7
7
  import type { CmsModel } from "../../../types/index.js";
8
8
  import { ModelFieldCompression } from "../../../features/contentModel/ModelFieldCompression/index.js";
9
+ import { RuntimeTenant } from "../../../features/runtimeTenant/abstractions.js";
9
10
  /**
10
11
  * CreateModelRepository - Validates domain rules and persists a new model.
11
12
  *
@@ -28,8 +29,9 @@ declare class CreateModelRepositoryImpl implements RepositoryAbstraction.Interfa
28
29
  private readonly tenantContext;
29
30
  private readonly cmsContext;
30
31
  private readonly modelFieldCompression;
31
- constructor(modelCache: ModelCache.Interface, pluginModelsProvider: PluginModelsProvider.Interface, listModelsUseCase: ListModelsUseCase.Interface, storageOperations: StorageOperations.Interface, tenantContext: TenantContext.Interface, cmsContext: CmsContext.Interface, modelFieldCompression: ModelFieldCompression.Interface);
32
- execute(model: CmsModel): Promise<Result<void, RepositoryAbstraction.Error>>;
32
+ private readonly runtimeTenant;
33
+ constructor(modelCache: ModelCache.Interface, pluginModelsProvider: PluginModelsProvider.Interface, listModelsUseCase: ListModelsUseCase.Interface, storageOperations: StorageOperations.Interface, tenantContext: TenantContext.Interface, cmsContext: CmsContext.Interface, modelFieldCompression: ModelFieldCompression.Interface, runtimeTenant: RuntimeTenant.Interface);
34
+ execute(initialModel: CmsModel): Promise<Result<CmsModel, RepositoryAbstraction.Error>>;
33
35
  }
34
36
  export declare const CreateModelRepository: typeof CreateModelRepositoryImpl & {
35
37
  __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ICreateModelRepository>;
@@ -13,6 +13,7 @@ import { validateSingularApiName } from "../../../domain/contentModel/validation
13
13
  import { validatePluralApiName } from "../../../domain/contentModel/validation/pluralApiName.js";
14
14
  import { validateModelFields } from "../../../domain/contentModel/validation/modelFields.js";
15
15
  import { ModelFieldCompression } from "../ModelFieldCompression/index.js";
16
+ import { RuntimeTenant } from "../../runtimeTenant/abstractions.js";
16
17
  const getModelId = (model)=>{
17
18
  const { modelId, name } = model;
18
19
  const value = modelId ? modelId.trim() : null;
@@ -25,7 +26,7 @@ const getModelId = (model)=>{
25
26
  throw new ModelValidationError('There is no "modelId" or "name" passed into the create model method.');
26
27
  };
27
28
  class CreateModelRepositoryImpl {
28
- constructor(modelCache, pluginModelsProvider, listModelsUseCase, storageOperations, tenantContext, cmsContext, modelFieldCompression){
29
+ constructor(modelCache, pluginModelsProvider, listModelsUseCase, storageOperations, tenantContext, cmsContext, modelFieldCompression, runtimeTenant){
29
30
  this.modelCache = modelCache;
30
31
  this.pluginModelsProvider = pluginModelsProvider;
31
32
  this.listModelsUseCase = listModelsUseCase;
@@ -33,8 +34,10 @@ class CreateModelRepositoryImpl {
33
34
  this.tenantContext = tenantContext;
34
35
  this.cmsContext = cmsContext;
35
36
  this.modelFieldCompression = modelFieldCompression;
37
+ this.runtimeTenant = runtimeTenant;
36
38
  }
37
- async execute(model) {
39
+ async execute(initialModel) {
40
+ const model = this.runtimeTenant.assign(initialModel);
38
41
  try {
39
42
  const tenant = this.tenantContext.getTenant();
40
43
  const modelId = getModelId(model);
@@ -103,7 +106,7 @@ class CreateModelRepositoryImpl {
103
106
  }
104
107
  });
105
108
  this.modelCache.clear();
106
- return Result.ok();
109
+ return Result.ok(model);
107
110
  } catch (error) {
108
111
  console.error(error, error.stack);
109
112
  return Result.fail(new ModelPersistenceError(error));
@@ -119,7 +122,8 @@ const CreateModelRepository_CreateModelRepository = CreateModelRepository.create
119
122
  StorageOperations,
120
123
  TenantContext,
121
124
  CmsContext,
122
- ModelFieldCompression
125
+ ModelFieldCompression,
126
+ RuntimeTenant
123
127
  ]
124
128
  });
125
129
  export { CreateModelRepository_CreateModelRepository as CreateModelRepository };
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/CreateModel/CreateModelRepository.js","sources":["../../../../src/features/contentModel/CreateModel/CreateModelRepository.ts"],"sourcesContent":["import camelCase from \"lodash/camelCase.js\";\nimport { Result } from \"@webiny/feature/api\";\nimport { CreateModelRepository as RepositoryAbstraction } from \"./abstractions.js\";\nimport { ModelCache, PluginModelsProvider } from \"~/features/contentModel/shared/abstractions.js\";\nimport { ListModelsUseCase } from \"~/features/contentModel/ListModels/index.js\";\nimport {\n ModelAlreadyExistsError,\n ModelPersistenceError,\n ModelValidationError\n} from \"~/domain/contentModel/errors.js\";\nimport { CmsContext, StorageOperations } from \"~/features/shared/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport {\n validateExistingModelId,\n validateModelIdAllowed\n} from \"~/crud/contentModel/validate/modelId.js\";\nimport { validateEndingAllowed } from \"~/crud/contentModel/validate/endingAllowed.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport { ensureTypeTag } from \"~/domain/contentModel/ensureTypeTag.js\";\nimport { validateSingularApiName } from \"~/domain/contentModel/validation/singularApiName.js\";\nimport { validatePluralApiName } from \"~/domain/contentModel/validation/pluralApiName.js\";\nimport { validateModelFields } from \"~/domain/contentModel/validation/modelFields.js\";\nimport { ModelFieldCompression } from \"~/features/contentModel/ModelFieldCompression/index.js\";\n\n/**\n * Generate modelId from model following the exact logic from beforeCreate.ts\n */\nconst getModelId = (model: { modelId?: string; name?: string }): string => {\n const { modelId, name } = model;\n const value = modelId ? modelId.trim() : null;\n if (value) {\n const isModelIdValid = camelCase(value).toLowerCase() === value.toLowerCase();\n if (isModelIdValid) {\n return value;\n }\n return camelCase(value);\n } else if (name) {\n return camelCase(name.trim());\n }\n throw new ModelValidationError(\n `There is no \"modelId\" or \"name\" passed into the create model method.`\n );\n};\n\n/**\n * CreateModelRepository - Validates domain rules and persists a new model.\n *\n * Responsibilities:\n * - Generate modelId from input\n * - Validate modelId is allowed (not in disallowed list)\n * - Validate API name endings\n * - Validate modelId uniqueness (database + plugins)\n * - Validate API name uniqueness (database + plugins)\n * - Validate plugin conflicts\n * - Validate model fields\n * - Persist to storage\n * - Clear ModelCache after successful create\n */\nclass CreateModelRepositoryImpl implements RepositoryAbstraction.Interface {\n public constructor(\n private readonly modelCache: ModelCache.Interface,\n private readonly pluginModelsProvider: PluginModelsProvider.Interface,\n private readonly listModelsUseCase: ListModelsUseCase.Interface,\n private readonly storageOperations: StorageOperations.Interface,\n private readonly tenantContext: TenantContext.Interface,\n private readonly cmsContext: CmsContext.Interface,\n private readonly modelFieldCompression: ModelFieldCompression.Interface\n ) {}\n\n async execute(model: CmsModel): Promise<Result<void, RepositoryAbstraction.Error>> {\n try {\n const tenant = this.tenantContext.getTenant();\n\n // TODO: this will eventually become part of the Model domain object.\n const modelId = getModelId(model);\n model.modelId = modelId;\n\n // Validate modelId is allowed (not in disallowed list)\n try {\n validateModelIdAllowed({ model });\n } catch (error) {\n return Result.fail(\n new ModelValidationError({\n message: error.message,\n data: error.data\n })\n );\n }\n\n // Validate API name endings\n try {\n validateEndingAllowed({ model });\n } catch (error) {\n return Result.fail(\n new ModelValidationError({\n message: error.message,\n data: error.data\n })\n );\n }\n\n // Check for plugin model conflicts\n const pluginModels = await this.pluginModelsProvider.list(tenant.id);\n const pluginModelConflict = pluginModels.find(pm => {\n return pm.modelId === model.modelId;\n });\n\n if (pluginModelConflict) {\n return Result.fail(\n new ModelAlreadyExistsError({\n modelId,\n message: `Model \"${modelId}\" is already registered via a plugin.`\n })\n );\n }\n\n // Get all models for further validation\n const modelsResult = await this.listModelsUseCase.execute();\n\n if (modelsResult.isFail()) {\n return Result.fail(new ModelPersistenceError(modelsResult.error));\n }\n\n const models = modelsResult.value;\n\n try {\n /**\n * We need to check for the existence of:\n * - modelId\n * - singularApiName\n * - pluralApiName\n */\n for (const existingModel of models) {\n validateExistingModelId({\n existingModel,\n model\n });\n validateSingularApiName({\n existingModel,\n model\n });\n validatePluralApiName({\n existingModel,\n model\n });\n }\n\n await validateModelFields({\n models,\n model,\n context: this.cmsContext\n });\n } catch (error) {\n return Result.fail(\n new ModelValidationError({ message: error.message, data: error.data })\n );\n }\n\n // TODO: ideally, this will eventually be handled by the Model domain object\n model.tags = ensureTypeTag(model);\n\n const fields = await this.modelFieldCompression.compress(model.fields);\n\n // Persist to storage\n await this.storageOperations.models.create({\n model: {\n ...model,\n fields\n }\n });\n\n // Clear cache\n this.modelCache.clear();\n\n return Result.ok();\n } catch (error) {\n console.error(error, error.stack);\n return Result.fail(new ModelPersistenceError(error as Error));\n }\n }\n}\n\nexport const CreateModelRepository = RepositoryAbstraction.createImplementation({\n implementation: CreateModelRepositoryImpl,\n dependencies: [\n ModelCache,\n PluginModelsProvider,\n ListModelsUseCase,\n StorageOperations,\n TenantContext,\n CmsContext,\n ModelFieldCompression\n ]\n});\n"],"names":["getModelId","model","modelId","name","value","isModelIdValid","camelCase","ModelValidationError","CreateModelRepositoryImpl","modelCache","pluginModelsProvider","listModelsUseCase","storageOperations","tenantContext","cmsContext","modelFieldCompression","tenant","validateModelIdAllowed","error","Result","validateEndingAllowed","pluginModels","pluginModelConflict","pm","ModelAlreadyExistsError","modelsResult","ModelPersistenceError","models","existingModel","validateExistingModelId","validateSingularApiName","validatePluralApiName","validateModelFields","ensureTypeTag","fields","console","CreateModelRepository","RepositoryAbstraction","ModelCache","PluginModelsProvider","ListModelsUseCase","StorageOperations","TenantContext","CmsContext","ModelFieldCompression"],"mappings":"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"}
1
+ {"version":3,"file":"features/contentModel/CreateModel/CreateModelRepository.js","sources":["../../../../src/features/contentModel/CreateModel/CreateModelRepository.ts"],"sourcesContent":["import camelCase from \"lodash/camelCase.js\";\nimport { Result } from \"@webiny/feature/api\";\nimport { CreateModelRepository as RepositoryAbstraction } from \"./abstractions.js\";\nimport { ModelCache, PluginModelsProvider } from \"~/features/contentModel/shared/abstractions.js\";\nimport { ListModelsUseCase } from \"~/features/contentModel/ListModels/index.js\";\nimport {\n ModelAlreadyExistsError,\n ModelPersistenceError,\n ModelValidationError\n} from \"~/domain/contentModel/errors.js\";\nimport { CmsContext, StorageOperations } from \"~/features/shared/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport {\n validateExistingModelId,\n validateModelIdAllowed\n} from \"~/crud/contentModel/validate/modelId.js\";\nimport { validateEndingAllowed } from \"~/crud/contentModel/validate/endingAllowed.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport { ensureTypeTag } from \"~/domain/contentModel/ensureTypeTag.js\";\nimport { validateSingularApiName } from \"~/domain/contentModel/validation/singularApiName.js\";\nimport { validatePluralApiName } from \"~/domain/contentModel/validation/pluralApiName.js\";\nimport { validateModelFields } from \"~/domain/contentModel/validation/modelFields.js\";\nimport { ModelFieldCompression } from \"~/features/contentModel/ModelFieldCompression/index.js\";\nimport { RuntimeTenant } from \"~/features/runtimeTenant/abstractions.js\";\n\n/**\n * Generate modelId from model following the exact logic from beforeCreate.ts\n */\nconst getModelId = (model: { modelId?: string; name?: string }): string => {\n const { modelId, name } = model;\n const value = modelId ? modelId.trim() : null;\n if (value) {\n const isModelIdValid = camelCase(value).toLowerCase() === value.toLowerCase();\n if (isModelIdValid) {\n return value;\n }\n return camelCase(value);\n } else if (name) {\n return camelCase(name.trim());\n }\n throw new ModelValidationError(\n `There is no \"modelId\" or \"name\" passed into the create model method.`\n );\n};\n\n/**\n * CreateModelRepository - Validates domain rules and persists a new model.\n *\n * Responsibilities:\n * - Generate modelId from input\n * - Validate modelId is allowed (not in disallowed list)\n * - Validate API name endings\n * - Validate modelId uniqueness (database + plugins)\n * - Validate API name uniqueness (database + plugins)\n * - Validate plugin conflicts\n * - Validate model fields\n * - Persist to storage\n * - Clear ModelCache after successful create\n */\nclass CreateModelRepositoryImpl implements RepositoryAbstraction.Interface {\n public constructor(\n private readonly modelCache: ModelCache.Interface,\n private readonly pluginModelsProvider: PluginModelsProvider.Interface,\n private readonly listModelsUseCase: ListModelsUseCase.Interface,\n private readonly storageOperations: StorageOperations.Interface,\n private readonly tenantContext: TenantContext.Interface,\n private readonly cmsContext: CmsContext.Interface,\n private readonly modelFieldCompression: ModelFieldCompression.Interface,\n private readonly runtimeTenant: RuntimeTenant.Interface\n ) {}\n\n async execute(initialModel: CmsModel): Promise<Result<CmsModel, RepositoryAbstraction.Error>> {\n const model = this.runtimeTenant.assign(initialModel);\n try {\n const tenant = this.tenantContext.getTenant();\n\n // TODO: this will eventually become part of the Model domain object.\n const modelId = getModelId(model);\n model.modelId = modelId;\n\n // Validate modelId is allowed (not in disallowed list)\n try {\n validateModelIdAllowed({ model });\n } catch (error) {\n return Result.fail(\n new ModelValidationError({\n message: error.message,\n data: error.data\n })\n );\n }\n\n // Validate API name endings\n try {\n validateEndingAllowed({ model });\n } catch (error) {\n return Result.fail(\n new ModelValidationError({\n message: error.message,\n data: error.data\n })\n );\n }\n\n // Check for plugin model conflicts\n const pluginModels = await this.pluginModelsProvider.list(tenant.id);\n const pluginModelConflict = pluginModels.find(pm => {\n return pm.modelId === model.modelId;\n });\n\n if (pluginModelConflict) {\n return Result.fail(\n new ModelAlreadyExistsError({\n modelId,\n message: `Model \"${modelId}\" is already registered via a plugin.`\n })\n );\n }\n\n // Get all models for further validation\n const modelsResult = await this.listModelsUseCase.execute();\n\n if (modelsResult.isFail()) {\n return Result.fail(new ModelPersistenceError(modelsResult.error));\n }\n\n const models = modelsResult.value;\n\n try {\n /**\n * We need to check for the existence of:\n * - modelId\n * - singularApiName\n * - pluralApiName\n */\n for (const existingModel of models) {\n validateExistingModelId({\n existingModel,\n model\n });\n validateSingularApiName({\n existingModel,\n model\n });\n validatePluralApiName({\n existingModel,\n model\n });\n }\n\n await validateModelFields({\n models,\n model,\n context: this.cmsContext\n });\n } catch (error) {\n return Result.fail(\n new ModelValidationError({ message: error.message, data: error.data })\n );\n }\n\n // TODO: ideally, this will eventually be handled by the Model domain object\n model.tags = ensureTypeTag(model);\n\n const fields = await this.modelFieldCompression.compress(model.fields);\n\n // Persist to storage\n await this.storageOperations.models.create({\n model: {\n ...model,\n fields\n }\n });\n\n // Clear cache\n this.modelCache.clear();\n\n return Result.ok(model);\n } catch (error) {\n console.error(error, error.stack);\n return Result.fail(new ModelPersistenceError(error as Error));\n }\n }\n}\n\nexport const CreateModelRepository = RepositoryAbstraction.createImplementation({\n implementation: CreateModelRepositoryImpl,\n dependencies: [\n ModelCache,\n PluginModelsProvider,\n ListModelsUseCase,\n StorageOperations,\n TenantContext,\n CmsContext,\n ModelFieldCompression,\n RuntimeTenant\n ]\n});\n"],"names":["getModelId","model","modelId","name","value","isModelIdValid","camelCase","ModelValidationError","CreateModelRepositoryImpl","modelCache","pluginModelsProvider","listModelsUseCase","storageOperations","tenantContext","cmsContext","modelFieldCompression","runtimeTenant","initialModel","tenant","validateModelIdAllowed","error","Result","validateEndingAllowed","pluginModels","pluginModelConflict","pm","ModelAlreadyExistsError","modelsResult","ModelPersistenceError","models","existingModel","validateExistingModelId","validateSingularApiName","validatePluralApiName","validateModelFields","ensureTypeTag","fields","console","CreateModelRepository","RepositoryAbstraction","ModelCache","PluginModelsProvider","ListModelsUseCase","StorageOperations","TenantContext","CmsContext","ModelFieldCompression","RuntimeTenant"],"mappings":"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"}
@@ -69,9 +69,9 @@ class CreateModelUseCaseImpl {
69
69
  return Result.fail(result.error);
70
70
  }
71
71
  await this.eventPublisher.publish(new ModelAfterCreateEvent({
72
- model
72
+ model: result.value
73
73
  }));
74
- return Result.ok(model);
74
+ return Result.ok(result.value);
75
75
  }
76
76
  }
77
77
  const CreateModelUseCase_CreateModelUseCase = CreateModelUseCase.createImplementation({
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/CreateModel/CreateModelUseCase.js","sources":["../../../../src/features/contentModel/CreateModel/CreateModelUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { CreateModelUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport { CreateModelRepository } from \"./abstractions.js\";\nimport { EventPublisher } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport { ModelBeforeCreateEvent } from \"./events.js\";\nimport { ModelAfterCreateEvent } from \"./events.js\";\nimport { ModelCreateErrorEvent } from \"./events.js\";\nimport { AccessControl } from \"~/features/shared/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { ModelNotAuthorizedError, ModelValidationError } from \"~/domain/contentModel/errors.js\";\nimport { createZodError } from \"@webiny/utils\";\nimport { removeUndefinedValues } from \"@webiny/utils\";\nimport { createModelCreateValidation } from \"~/domain/contentModel/schemas.js\";\nimport { assignModelDefaultFields } from \"~/crud/contentModel/defaultFields.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport type { CmsModelCreateInput } from \"~/types/index.js\";\n\n/**\n * CreateModelUseCase - Core model creation orchestration.\n *\n * Responsibilities:\n * - Validate input (Zod)\n * - Create domain model object\n * - Assign default fields if requested\n * - Access control checks\n * - Publish before event\n * - Delegate to repository\n * - Publish after event or error event\n *\n * Note: This use case is decorated by CreateModelValidator which handles:\n * - ModelId generation\n * - ModelId allowed validation\n * - API name ending validation\n * - Field validation and plugin conflict checks\n */\nclass CreateModelUseCaseImpl implements UseCaseAbstraction.Interface {\n public constructor(\n private eventPublisher: EventPublisher.Interface,\n private repository: CreateModelRepository.Interface,\n private accessControl: AccessControl.Interface,\n private tenantContext: TenantContext.Interface,\n private identityContext: IdentityContext.Interface\n ) {}\n\n async execute(input: CmsModelCreateInput): Promise<Result<CmsModel, UseCaseAbstraction.Error>> {\n // Initial access control check\n const canAccess = await this.accessControl.canAccessModel({ rwd: \"w\" });\n if (!canAccess) {\n return Result.fail(new ModelNotAuthorizedError());\n }\n\n // Validate input\n const validationResult = await createModelCreateValidation().safeParseAsync(input);\n if (!validationResult.success) {\n const zodError = createZodError(validationResult.error);\n return Result.fail(new ModelValidationError(zodError.message));\n }\n\n // Extract defaultFields flag and remove it from data\n const { defaultFields, ...data } = removeUndefinedValues(validationResult.data);\n\n // Assign default fields if requested\n if (defaultFields) {\n assignModelDefaultFields(data);\n }\n\n // Create the domain model object\n const identity = this.identityContext.getIdentity();\n const tenant = this.tenantContext.getTenant();\n\n const model: CmsModel = {\n ...data,\n icon: data.icon ?? null,\n modelId: data.modelId ?? \"\", // Will be set by repository\n tenant: tenant.id,\n createdOn: new Date().toISOString(),\n savedOn: new Date().toISOString(),\n createdBy: {\n id: identity.id,\n displayName: identity.displayName,\n type: identity.type\n },\n description: data.description || \"\",\n // Fields and layout from data\n fields: data.fields || [],\n layout: data.layout || [],\n // Title/description/image field IDs\n titleFieldId: data.titleFieldId || \"\",\n descriptionFieldId: data.descriptionFieldId,\n imageFieldId: data.imageFieldId\n };\n\n // Access control check on the created model\n const canAccessModel = await this.accessControl.canAccessModel({ model, rwd: \"w\" });\n if (!canAccessModel) {\n return Result.fail(ModelNotAuthorizedError.fromModel(model));\n }\n\n // Publish before event\n await this.eventPublisher.publish(new ModelBeforeCreateEvent({ model, input: data }));\n\n // Persist via repository (repository will validate and set modelId)\n const result = await this.repository.execute(model);\n if (result.isFail()) {\n // Publish error event\n await this.eventPublisher.publish(\n new ModelCreateErrorEvent({\n input,\n model,\n error: result.error\n })\n );\n return Result.fail(result.error);\n }\n\n // Publish after event\n await this.eventPublisher.publish(new ModelAfterCreateEvent({ model }));\n\n return Result.ok(model);\n }\n}\n\nexport const CreateModelUseCase = UseCaseAbstraction.createImplementation({\n implementation: CreateModelUseCaseImpl,\n dependencies: [\n EventPublisher,\n CreateModelRepository,\n AccessControl,\n TenantContext,\n IdentityContext\n ]\n});\n"],"names":["CreateModelUseCaseImpl","eventPublisher","repository","accessControl","tenantContext","identityContext","input","canAccess","Result","ModelNotAuthorizedError","validationResult","createModelCreateValidation","zodError","createZodError","ModelValidationError","defaultFields","data","removeUndefinedValues","assignModelDefaultFields","identity","tenant","model","Date","canAccessModel","ModelBeforeCreateEvent","result","ModelCreateErrorEvent","ModelAfterCreateEvent","CreateModelUseCase","UseCaseAbstraction","EventPublisher","CreateModelRepository","AccessControl","TenantContext","IdentityContext"],"mappings":";;;;;;;;;;;AAoCA,MAAMA;IACF,YACYC,cAAwC,EACxCC,UAA2C,EAC3CC,aAAsC,EACtCC,aAAsC,EACtCC,eAA0C,CACpD;aALUJ,cAAc,GAAdA;aACAC,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,aAAa,GAAbA;aACAC,eAAe,GAAfA;IACT;IAEH,MAAM,QAAQC,KAA0B,EAAuD;QAE3F,MAAMC,YAAY,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAE,KAAK;QAAI;QACrE,IAAI,CAACA,WACD,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAI3B,MAAMC,mBAAmB,MAAMC,8BAA8B,cAAc,CAACL;QAC5E,IAAI,CAACI,iBAAiB,OAAO,EAAE;YAC3B,MAAME,WAAWC,eAAeH,iBAAiB,KAAK;YACtD,OAAOF,OAAO,IAAI,CAAC,IAAIM,qBAAqBF,SAAS,OAAO;QAChE;QAGA,MAAM,EAAEG,aAAa,EAAE,GAAGC,MAAM,GAAGC,sBAAsBP,iBAAiB,IAAI;QAG9E,IAAIK,eACAG,yBAAyBF;QAI7B,MAAMG,WAAW,IAAI,CAAC,eAAe,CAAC,WAAW;QACjD,MAAMC,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAE3C,MAAMC,QAAkB;YACpB,GAAGL,IAAI;YACP,MAAMA,KAAK,IAAI,IAAI;YACnB,SAASA,KAAK,OAAO,IAAI;YACzB,QAAQI,OAAO,EAAE;YACjB,WAAW,IAAIE,OAAO,WAAW;YACjC,SAAS,IAAIA,OAAO,WAAW;YAC/B,WAAW;gBACP,IAAIH,SAAS,EAAE;gBACf,aAAaA,SAAS,WAAW;gBACjC,MAAMA,SAAS,IAAI;YACvB;YACA,aAAaH,KAAK,WAAW,IAAI;YAEjC,QAAQA,KAAK,MAAM,IAAI,EAAE;YACzB,QAAQA,KAAK,MAAM,IAAI,EAAE;YAEzB,cAAcA,KAAK,YAAY,IAAI;YACnC,oBAAoBA,KAAK,kBAAkB;YAC3C,cAAcA,KAAK,YAAY;QACnC;QAGA,MAAMO,iBAAiB,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAEF;YAAO,KAAK;QAAI;QACjF,IAAI,CAACE,gBACD,OAAOf,OAAO,IAAI,CAACC,wBAAwB,SAAS,CAACY;QAIzD,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAIG,uBAAuB;YAAEH;YAAO,OAAOL;QAAK;QAGlF,MAAMS,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACJ;QAC7C,IAAII,OAAO,MAAM,IAAI;YAEjB,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIC,sBAAsB;gBACtBpB;gBACAe;gBACA,OAAOI,OAAO,KAAK;YACvB;YAEJ,OAAOjB,OAAO,IAAI,CAACiB,OAAO,KAAK;QACnC;QAGA,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAIE,sBAAsB;YAAEN;QAAM;QAEpE,OAAOb,OAAO,EAAE,CAACa;IACrB;AACJ;AAEO,MAAMO,wCAAqBC,mBAAAA,oBAAuC,CAAC;IACtE,gBAAgB7B;IAChB,cAAc;QACV8B;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
1
+ {"version":3,"file":"features/contentModel/CreateModel/CreateModelUseCase.js","sources":["../../../../src/features/contentModel/CreateModel/CreateModelUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { CreateModelUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport { CreateModelRepository } from \"./abstractions.js\";\nimport { EventPublisher } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport { ModelBeforeCreateEvent } from \"./events.js\";\nimport { ModelAfterCreateEvent } from \"./events.js\";\nimport { ModelCreateErrorEvent } from \"./events.js\";\nimport { AccessControl } from \"~/features/shared/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { ModelNotAuthorizedError, ModelValidationError } from \"~/domain/contentModel/errors.js\";\nimport { createZodError } from \"@webiny/utils\";\nimport { removeUndefinedValues } from \"@webiny/utils\";\nimport { createModelCreateValidation } from \"~/domain/contentModel/schemas.js\";\nimport { assignModelDefaultFields } from \"~/crud/contentModel/defaultFields.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport type { CmsModelCreateInput } from \"~/types/index.js\";\n\n/**\n * CreateModelUseCase - Core model creation orchestration.\n *\n * Responsibilities:\n * - Validate input (Zod)\n * - Create domain model object\n * - Assign default fields if requested\n * - Access control checks\n * - Publish before event\n * - Delegate to repository\n * - Publish after event or error event\n *\n * Note: This use case is decorated by CreateModelValidator which handles:\n * - ModelId generation\n * - ModelId allowed validation\n * - API name ending validation\n * - Field validation and plugin conflict checks\n */\nclass CreateModelUseCaseImpl implements UseCaseAbstraction.Interface {\n public constructor(\n private eventPublisher: EventPublisher.Interface,\n private repository: CreateModelRepository.Interface,\n private accessControl: AccessControl.Interface,\n private tenantContext: TenantContext.Interface,\n private identityContext: IdentityContext.Interface\n ) {}\n\n async execute(input: CmsModelCreateInput): Promise<Result<CmsModel, UseCaseAbstraction.Error>> {\n // Initial access control check\n const canAccess = await this.accessControl.canAccessModel({ rwd: \"w\" });\n if (!canAccess) {\n return Result.fail(new ModelNotAuthorizedError());\n }\n\n // Validate input\n const validationResult = await createModelCreateValidation().safeParseAsync(input);\n if (!validationResult.success) {\n const zodError = createZodError(validationResult.error);\n return Result.fail(new ModelValidationError(zodError.message));\n }\n\n // Extract defaultFields flag and remove it from data\n const { defaultFields, ...data } = removeUndefinedValues(validationResult.data);\n\n // Assign default fields if requested\n if (defaultFields) {\n assignModelDefaultFields(data);\n }\n\n // Create the domain model object\n const identity = this.identityContext.getIdentity();\n const tenant = this.tenantContext.getTenant();\n\n const model: CmsModel = {\n ...data,\n icon: data.icon ?? null,\n modelId: data.modelId ?? \"\", // Will be set by repository\n tenant: tenant.id,\n createdOn: new Date().toISOString(),\n savedOn: new Date().toISOString(),\n createdBy: {\n id: identity.id,\n displayName: identity.displayName,\n type: identity.type\n },\n description: data.description || \"\",\n // Fields and layout from data\n fields: data.fields || [],\n layout: data.layout || [],\n // Title/description/image field IDs\n titleFieldId: data.titleFieldId || \"\",\n descriptionFieldId: data.descriptionFieldId,\n imageFieldId: data.imageFieldId\n };\n\n // Access control check on the created model\n const canAccessModel = await this.accessControl.canAccessModel({ model, rwd: \"w\" });\n if (!canAccessModel) {\n return Result.fail(ModelNotAuthorizedError.fromModel(model));\n }\n\n // Publish before event\n await this.eventPublisher.publish(new ModelBeforeCreateEvent({ model, input: data }));\n\n // Persist via repository (repository will validate and set modelId)\n const result = await this.repository.execute(model);\n if (result.isFail()) {\n // Publish error event\n await this.eventPublisher.publish(\n new ModelCreateErrorEvent({\n input,\n model,\n error: result.error\n })\n );\n return Result.fail(result.error);\n }\n\n // Publish after event\n await this.eventPublisher.publish(\n new ModelAfterCreateEvent({\n model: result.value\n })\n );\n\n return Result.ok(result.value);\n }\n}\n\nexport const CreateModelUseCase = UseCaseAbstraction.createImplementation({\n implementation: CreateModelUseCaseImpl,\n dependencies: [\n EventPublisher,\n CreateModelRepository,\n AccessControl,\n TenantContext,\n IdentityContext\n ]\n});\n"],"names":["CreateModelUseCaseImpl","eventPublisher","repository","accessControl","tenantContext","identityContext","input","canAccess","Result","ModelNotAuthorizedError","validationResult","createModelCreateValidation","zodError","createZodError","ModelValidationError","defaultFields","data","removeUndefinedValues","assignModelDefaultFields","identity","tenant","model","Date","canAccessModel","ModelBeforeCreateEvent","result","ModelCreateErrorEvent","ModelAfterCreateEvent","CreateModelUseCase","UseCaseAbstraction","EventPublisher","CreateModelRepository","AccessControl","TenantContext","IdentityContext"],"mappings":";;;;;;;;;;;AAoCA,MAAMA;IACF,YACYC,cAAwC,EACxCC,UAA2C,EAC3CC,aAAsC,EACtCC,aAAsC,EACtCC,eAA0C,CACpD;aALUJ,cAAc,GAAdA;aACAC,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,aAAa,GAAbA;aACAC,eAAe,GAAfA;IACT;IAEH,MAAM,QAAQC,KAA0B,EAAuD;QAE3F,MAAMC,YAAY,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAE,KAAK;QAAI;QACrE,IAAI,CAACA,WACD,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAI3B,MAAMC,mBAAmB,MAAMC,8BAA8B,cAAc,CAACL;QAC5E,IAAI,CAACI,iBAAiB,OAAO,EAAE;YAC3B,MAAME,WAAWC,eAAeH,iBAAiB,KAAK;YACtD,OAAOF,OAAO,IAAI,CAAC,IAAIM,qBAAqBF,SAAS,OAAO;QAChE;QAGA,MAAM,EAAEG,aAAa,EAAE,GAAGC,MAAM,GAAGC,sBAAsBP,iBAAiB,IAAI;QAG9E,IAAIK,eACAG,yBAAyBF;QAI7B,MAAMG,WAAW,IAAI,CAAC,eAAe,CAAC,WAAW;QACjD,MAAMC,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAE3C,MAAMC,QAAkB;YACpB,GAAGL,IAAI;YACP,MAAMA,KAAK,IAAI,IAAI;YACnB,SAASA,KAAK,OAAO,IAAI;YACzB,QAAQI,OAAO,EAAE;YACjB,WAAW,IAAIE,OAAO,WAAW;YACjC,SAAS,IAAIA,OAAO,WAAW;YAC/B,WAAW;gBACP,IAAIH,SAAS,EAAE;gBACf,aAAaA,SAAS,WAAW;gBACjC,MAAMA,SAAS,IAAI;YACvB;YACA,aAAaH,KAAK,WAAW,IAAI;YAEjC,QAAQA,KAAK,MAAM,IAAI,EAAE;YACzB,QAAQA,KAAK,MAAM,IAAI,EAAE;YAEzB,cAAcA,KAAK,YAAY,IAAI;YACnC,oBAAoBA,KAAK,kBAAkB;YAC3C,cAAcA,KAAK,YAAY;QACnC;QAGA,MAAMO,iBAAiB,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAEF;YAAO,KAAK;QAAI;QACjF,IAAI,CAACE,gBACD,OAAOf,OAAO,IAAI,CAACC,wBAAwB,SAAS,CAACY;QAIzD,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAIG,uBAAuB;YAAEH;YAAO,OAAOL;QAAK;QAGlF,MAAMS,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACJ;QAC7C,IAAII,OAAO,MAAM,IAAI;YAEjB,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIC,sBAAsB;gBACtBpB;gBACAe;gBACA,OAAOI,OAAO,KAAK;YACvB;YAEJ,OAAOjB,OAAO,IAAI,CAACiB,OAAO,KAAK;QACnC;QAGA,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIE,sBAAsB;YACtB,OAAOF,OAAO,KAAK;QACvB;QAGJ,OAAOjB,OAAO,EAAE,CAACiB,OAAO,KAAK;IACjC;AACJ;AAEO,MAAMG,wCAAqBC,mBAAAA,oBAAuC,CAAC;IACtE,gBAAgB7B;IAChB,cAAc;QACV8B;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
@@ -30,7 +30,7 @@ export declare namespace CreateModelUseCase {
30
30
  * CreateModelRepository - Validates domain rules and persists a new model to storage.
31
31
  */
32
32
  export interface ICreateModelRepository {
33
- execute(model: CmsModel): Promise<Result<void, RepositoryError>>;
33
+ execute(model: CmsModel): Promise<Result<CmsModel, RepositoryError>>;
34
34
  }
35
35
  export interface ICreateModelRepositoryErrors {
36
36
  alreadyExists: ModelAlreadyExistsError;
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/CreateModel/abstractions.js","sources":["../../../../src/features/contentModel/CreateModel/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\nimport type { CmsModel, CmsModelCreateInput } from \"~/types/index.js\";\nimport {\n ModelAlreadyExistsError,\n ModelNotAuthorizedError,\n type ModelPersistenceError,\n type ModelSlugTakenError,\n type ModelValidationError\n} from \"~/domain/contentModel/errors.js\";\nimport {\n type GroupNotAuthorizedError,\n type GroupNotFoundError\n} from \"~/domain/contentModelGroup/errors.js\";\n\n/**\n * CreateModel Use Case\n */\nexport interface ICreateModelUseCase {\n execute(input: CmsModelCreateInput): Promise<Result<CmsModel, UseCaseError>>;\n}\n\nexport interface ICreateModelUseCaseErrors {\n notAuthorized: ModelNotAuthorizedError;\n validation: ModelValidationError;\n slugTaken: ModelSlugTakenError;\n alreadyExists: ModelAlreadyExistsError;\n persistence: ModelPersistenceError;\n groupNotFound: GroupNotFoundError; // Reused from Group domain\n groupNotAccessible: GroupNotAuthorizedError; // Reused from Group domain\n}\n\ntype UseCaseError = ICreateModelUseCaseErrors[keyof ICreateModelUseCaseErrors];\n\n/** Create a new content model. */\nexport const CreateModelUseCase = createAbstraction<ICreateModelUseCase>(\"CreateModelUseCase\");\n\nexport namespace CreateModelUseCase {\n export type Interface = ICreateModelUseCase;\n export type Input = CmsModelCreateInput;\n\n export type Error = UseCaseError;\n export type Return = Promise<Result<CmsModel, UseCaseError>>;\n}\n\n/**\n * CreateModelRepository - Validates domain rules and persists a new model to storage.\n */\nexport interface ICreateModelRepository {\n execute(model: CmsModel): Promise<Result<void, RepositoryError>>;\n}\n\nexport interface ICreateModelRepositoryErrors {\n alreadyExists: ModelAlreadyExistsError;\n validation: ModelValidationError;\n persistence: ModelPersistenceError;\n}\n\ntype RepositoryError = ICreateModelRepositoryErrors[keyof ICreateModelRepositoryErrors];\n\nexport const CreateModelRepository =\n createAbstraction<ICreateModelRepository>(\"CreateModelRepository\");\n\nexport namespace CreateModelRepository {\n export type Interface = ICreateModelRepository;\n export type Error = RepositoryError;\n}\n"],"names":["CreateModelUseCase","createAbstraction","CreateModelRepository"],"mappings":";AAkCO,MAAMA,qBAAqBC,kBAAuC;AAyBlE,MAAMC,wBACTD,kBAA0C"}
1
+ {"version":3,"file":"features/contentModel/CreateModel/abstractions.js","sources":["../../../../src/features/contentModel/CreateModel/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\nimport type { CmsModel, CmsModelCreateInput } from \"~/types/index.js\";\nimport {\n ModelAlreadyExistsError,\n ModelNotAuthorizedError,\n type ModelPersistenceError,\n type ModelSlugTakenError,\n type ModelValidationError\n} from \"~/domain/contentModel/errors.js\";\nimport {\n type GroupNotAuthorizedError,\n type GroupNotFoundError\n} from \"~/domain/contentModelGroup/errors.js\";\n\n/**\n * CreateModel Use Case\n */\nexport interface ICreateModelUseCase {\n execute(input: CmsModelCreateInput): Promise<Result<CmsModel, UseCaseError>>;\n}\n\nexport interface ICreateModelUseCaseErrors {\n notAuthorized: ModelNotAuthorizedError;\n validation: ModelValidationError;\n slugTaken: ModelSlugTakenError;\n alreadyExists: ModelAlreadyExistsError;\n persistence: ModelPersistenceError;\n groupNotFound: GroupNotFoundError; // Reused from Group domain\n groupNotAccessible: GroupNotAuthorizedError; // Reused from Group domain\n}\n\ntype UseCaseError = ICreateModelUseCaseErrors[keyof ICreateModelUseCaseErrors];\n\n/** Create a new content model. */\nexport const CreateModelUseCase = createAbstraction<ICreateModelUseCase>(\"CreateModelUseCase\");\n\nexport namespace CreateModelUseCase {\n export type Interface = ICreateModelUseCase;\n export type Input = CmsModelCreateInput;\n\n export type Error = UseCaseError;\n export type Return = Promise<Result<CmsModel, UseCaseError>>;\n}\n\n/**\n * CreateModelRepository - Validates domain rules and persists a new model to storage.\n */\nexport interface ICreateModelRepository {\n execute(model: CmsModel): Promise<Result<CmsModel, RepositoryError>>;\n}\n\nexport interface ICreateModelRepositoryErrors {\n alreadyExists: ModelAlreadyExistsError;\n validation: ModelValidationError;\n persistence: ModelPersistenceError;\n}\n\ntype RepositoryError = ICreateModelRepositoryErrors[keyof ICreateModelRepositoryErrors];\n\nexport const CreateModelRepository =\n createAbstraction<ICreateModelRepository>(\"CreateModelRepository\");\n\nexport namespace CreateModelRepository {\n export type Interface = ICreateModelRepository;\n export type Error = RepositoryError;\n}\n"],"names":["CreateModelUseCase","createAbstraction","CreateModelRepository"],"mappings":";AAkCO,MAAMA,qBAAqBC,kBAAuC;AAyBlE,MAAMC,wBACTD,kBAA0C"}
@@ -5,6 +5,7 @@ import { CmsContext, StorageOperations } from "../../../features/shared/abstract
5
5
  import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
6
6
  import type { CmsModel } from "../../../types/index.js";
7
7
  import { ModelFieldCompression } from "../../../features/contentModel/ModelFieldCompression/index.js";
8
+ import { RuntimeTenant } from "../../../features/runtimeTenant/abstractions.js";
8
9
  /**
9
10
  * CreateModelFromRepository - Validates domain rules and persists cloned model.
10
11
  *
@@ -27,8 +28,9 @@ declare class CreateModelFromRepositoryImpl implements RepositoryAbstraction.Int
27
28
  private readonly tenantContext;
28
29
  private readonly cmsContext;
29
30
  private readonly modelFieldCompression;
30
- constructor(modelCache: ModelCache.Interface, pluginModelsProvider: PluginModelsProvider.Interface, modelsFetcher: ModelsFetcher.Interface, storageOperations: StorageOperations.Interface, tenantContext: TenantContext.Interface, cmsContext: CmsContext.Interface, modelFieldCompression: ModelFieldCompression.Interface);
31
- execute(model: CmsModel): Promise<Result<void, RepositoryAbstraction.Error>>;
31
+ private readonly runtimeTenant;
32
+ constructor(modelCache: ModelCache.Interface, pluginModelsProvider: PluginModelsProvider.Interface, modelsFetcher: ModelsFetcher.Interface, storageOperations: StorageOperations.Interface, tenantContext: TenantContext.Interface, cmsContext: CmsContext.Interface, modelFieldCompression: ModelFieldCompression.Interface, runtimeTenant: RuntimeTenant.Interface);
33
+ execute(initialModel: CmsModel): Promise<Result<CmsModel, RepositoryAbstraction.Error>>;
32
34
  }
33
35
  export declare const CreateModelFromRepository: typeof CreateModelFromRepositoryImpl & {
34
36
  __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ICreateModelFromRepository>;