@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
@@ -12,6 +12,7 @@ import { validatePluralApiName } from "../../../domain/contentModel/validation/p
12
12
  import { validateModelFields } from "../../../domain/contentModel/validation/modelFields.js";
13
13
  import { ensureTypeTag } from "../../../domain/contentModel/ensureTypeTag.js";
14
14
  import { ModelFieldCompression } from "../ModelFieldCompression/index.js";
15
+ import { RuntimeTenant } from "../../runtimeTenant/abstractions.js";
15
16
  const getModelId = (model)=>{
16
17
  const { modelId, name } = model;
17
18
  const value = modelId ? modelId.trim() : null;
@@ -24,7 +25,7 @@ const getModelId = (model)=>{
24
25
  throw new ModelValidationError('There is no "modelId" or "name" passed into the create model from method.');
25
26
  };
26
27
  class CreateModelFromRepositoryImpl {
27
- constructor(modelCache, pluginModelsProvider, modelsFetcher, storageOperations, tenantContext, cmsContext, modelFieldCompression){
28
+ constructor(modelCache, pluginModelsProvider, modelsFetcher, storageOperations, tenantContext, cmsContext, modelFieldCompression, runtimeTenant){
28
29
  this.modelCache = modelCache;
29
30
  this.pluginModelsProvider = pluginModelsProvider;
30
31
  this.modelsFetcher = modelsFetcher;
@@ -32,8 +33,10 @@ class CreateModelFromRepositoryImpl {
32
33
  this.tenantContext = tenantContext;
33
34
  this.cmsContext = cmsContext;
34
35
  this.modelFieldCompression = modelFieldCompression;
36
+ this.runtimeTenant = runtimeTenant;
35
37
  }
36
- async execute(model) {
38
+ async execute(initialModel) {
39
+ const model = this.runtimeTenant.assign(initialModel);
37
40
  try {
38
41
  const tenant = this.tenantContext.getTenant();
39
42
  const modelId = getModelId(model);
@@ -106,7 +109,7 @@ class CreateModelFromRepositoryImpl {
106
109
  }
107
110
  });
108
111
  this.modelCache.clear();
109
- return Result.ok();
112
+ return Result.ok(model);
110
113
  } catch (error) {
111
114
  return Result.fail(new ModelPersistenceError(error));
112
115
  }
@@ -121,7 +124,8 @@ const CreateModelFromRepository_CreateModelFromRepository = CreateModelFromRepos
121
124
  StorageOperations,
122
125
  TenantContext,
123
126
  CmsContext,
124
- ModelFieldCompression
127
+ ModelFieldCompression,
128
+ RuntimeTenant
125
129
  ]
126
130
  });
127
131
  export { CreateModelFromRepository_CreateModelFromRepository as CreateModelFromRepository };
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/CreateModelFrom/CreateModelFromRepository.js","sources":["../../../../src/features/contentModel/CreateModelFrom/CreateModelFromRepository.ts"],"sourcesContent":["import camelCase from \"lodash/camelCase.js\";\nimport { Result } from \"@webiny/feature/api\";\nimport { CreateModelFromRepository as RepositoryAbstraction } from \"./abstractions.js\";\nimport {\n ModelCache,\n ModelsFetcher,\n PluginModelsProvider\n} from \"~/features/contentModel/shared/abstractions.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 { validateSingularApiName } from \"~/domain/contentModel/validation/singularApiName.js\";\nimport { validatePluralApiName } from \"~/domain/contentModel/validation/pluralApiName.js\";\nimport { validateModelFields } from \"~/domain/contentModel/validation/modelFields.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport { ensureTypeTag } from \"~/domain/contentModel/ensureTypeTag.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 from method.`\n );\n};\n\n/**\n * CreateModelFromRepository - Validates domain rules and persists cloned 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 CreateModelFromRepositoryImpl implements RepositoryAbstraction.Interface {\n public constructor(\n private readonly modelCache: ModelCache.Interface,\n private readonly pluginModelsProvider: PluginModelsProvider.Interface,\n private readonly modelsFetcher: ModelsFetcher.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 // Generate modelId using the exact logic from beforeCreate.ts\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({ message: error.message, data: error.data })\n );\n }\n\n // Validate API name endings\n try {\n validateEndingAllowed({ model });\n } catch (error) {\n return Result.fail(\n new ModelValidationError({ message: error.message, data: error.data })\n );\n }\n\n // Validate modelId uniqueness (database)\n const modelsResult = await this.modelsFetcher.fetchAll();\n if (modelsResult.isFail()) {\n return Result.fail(new ModelPersistenceError(modelsResult.error));\n }\n\n const existingModel = modelsResult.value.find(m => m.modelId === modelId);\n if (existingModel) {\n return Result.fail(new ModelAlreadyExistsError({ modelId }));\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 (\n pm.modelId === model.modelId ||\n pm.singularApiName === model.singularApiName ||\n pm.pluralApiName === model.pluralApiName\n );\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 const models = modelsResult.value;\n\n try {\n // Validate uniqueness\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 // Validate model fields\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 // Ensure type tags\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 return Result.fail(new ModelPersistenceError(error as Error));\n }\n }\n}\n\nexport const CreateModelFromRepository = RepositoryAbstraction.createImplementation({\n implementation: CreateModelFromRepositoryImpl,\n dependencies: [\n ModelCache,\n PluginModelsProvider,\n ModelsFetcher,\n StorageOperations,\n TenantContext,\n CmsContext,\n ModelFieldCompression\n ]\n});\n"],"names":["getModelId","model","modelId","name","value","isModelIdValid","camelCase","ModelValidationError","CreateModelFromRepositoryImpl","modelCache","pluginModelsProvider","modelsFetcher","storageOperations","tenantContext","cmsContext","modelFieldCompression","tenant","validateModelIdAllowed","error","Result","validateEndingAllowed","modelsResult","ModelPersistenceError","existingModel","m","ModelAlreadyExistsError","pluginModels","pluginModelConflict","pm","models","validateExistingModelId","validateSingularApiName","validatePluralApiName","validateModelFields","ensureTypeTag","fields","CreateModelFromRepository","RepositoryAbstraction","ModelCache","PluginModelsProvider","ModelsFetcher","StorageOperations","TenantContext","CmsContext","ModelFieldCompression"],"mappings":"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"}
1
+ {"version":3,"file":"features/contentModel/CreateModelFrom/CreateModelFromRepository.js","sources":["../../../../src/features/contentModel/CreateModelFrom/CreateModelFromRepository.ts"],"sourcesContent":["import camelCase from \"lodash/camelCase.js\";\nimport { Result } from \"@webiny/feature/api\";\nimport { CreateModelFromRepository as RepositoryAbstraction } from \"./abstractions.js\";\nimport {\n ModelCache,\n ModelsFetcher,\n PluginModelsProvider\n} from \"~/features/contentModel/shared/abstractions.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 { validateSingularApiName } from \"~/domain/contentModel/validation/singularApiName.js\";\nimport { validatePluralApiName } from \"~/domain/contentModel/validation/pluralApiName.js\";\nimport { validateModelFields } from \"~/domain/contentModel/validation/modelFields.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport { ensureTypeTag } from \"~/domain/contentModel/ensureTypeTag.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 from method.`\n );\n};\n\n/**\n * CreateModelFromRepository - Validates domain rules and persists cloned 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 CreateModelFromRepositoryImpl implements RepositoryAbstraction.Interface {\n public constructor(\n private readonly modelCache: ModelCache.Interface,\n private readonly pluginModelsProvider: PluginModelsProvider.Interface,\n private readonly modelsFetcher: ModelsFetcher.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 // Generate modelId using the exact logic from beforeCreate.ts\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({ message: error.message, data: error.data })\n );\n }\n\n // Validate API name endings\n try {\n validateEndingAllowed({ model });\n } catch (error) {\n return Result.fail(\n new ModelValidationError({ message: error.message, data: error.data })\n );\n }\n\n // Validate modelId uniqueness (database)\n const modelsResult = await this.modelsFetcher.fetchAll();\n if (modelsResult.isFail()) {\n return Result.fail(new ModelPersistenceError(modelsResult.error));\n }\n\n const existingModel = modelsResult.value.find(m => m.modelId === modelId);\n if (existingModel) {\n return Result.fail(new ModelAlreadyExistsError({ modelId }));\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 (\n pm.modelId === model.modelId ||\n pm.singularApiName === model.singularApiName ||\n pm.pluralApiName === model.pluralApiName\n );\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 const models = modelsResult.value;\n\n try {\n // Validate uniqueness\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 // Validate model fields\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 // Ensure type tags\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 return Result.fail(new ModelPersistenceError(error as Error));\n }\n }\n}\n\nexport const CreateModelFromRepository = RepositoryAbstraction.createImplementation({\n implementation: CreateModelFromRepositoryImpl,\n dependencies: [\n ModelCache,\n PluginModelsProvider,\n ModelsFetcher,\n StorageOperations,\n TenantContext,\n CmsContext,\n ModelFieldCompression,\n RuntimeTenant\n ]\n});\n"],"names":["getModelId","model","modelId","name","value","isModelIdValid","camelCase","ModelValidationError","CreateModelFromRepositoryImpl","modelCache","pluginModelsProvider","modelsFetcher","storageOperations","tenantContext","cmsContext","modelFieldCompression","runtimeTenant","initialModel","tenant","validateModelIdAllowed","error","Result","validateEndingAllowed","modelsResult","ModelPersistenceError","existingModel","m","ModelAlreadyExistsError","pluginModels","pluginModelConflict","pm","models","validateExistingModelId","validateSingularApiName","validatePluralApiName","validateModelFields","ensureTypeTag","fields","CreateModelFromRepository","RepositoryAbstraction","ModelCache","PluginModelsProvider","ModelsFetcher","StorageOperations","TenantContext","CmsContext","ModelFieldCompression","RuntimeTenant"],"mappings":"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"}
@@ -77,10 +77,10 @@ class CreateModelFromUseCaseImpl {
77
77
  return Result.fail(result.error);
78
78
  }
79
79
  await this.eventPublisher.publish(new ModelAfterCreateFromEvent({
80
- model,
80
+ model: result.value,
81
81
  original
82
82
  }));
83
- return Result.ok(model);
83
+ return Result.ok(result.value);
84
84
  }
85
85
  }
86
86
  const CreateModelFromUseCase_CreateModelFromUseCase = CreateModelFromUseCase.createImplementation({
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/CreateModelFrom/CreateModelFromUseCase.js","sources":["../../../../src/features/contentModel/CreateModelFrom/CreateModelFromUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { CreateModelFromUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport { CreateModelFromRepository } from \"./abstractions.js\";\nimport { EventPublisher } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport { ModelBeforeCreateFromEvent } from \"./events.js\";\nimport { ModelAfterCreateFromEvent } from \"./events.js\";\nimport { ModelCreateFromErrorEvent } 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 { createModelCreateFromValidation } from \"~/domain/contentModel/schemas.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport type { CmsModelCreateFromInput } from \"~/types/index.js\";\nimport { GetModelUseCase } from \"~/features/contentModel/GetModel/index.js\";\n\n/**\n * CreateModelFromUseCase - Clone/copy a model from existing model.\n *\n * Responsibilities:\n * - Validate input (Zod)\n * - Fetch original model\n * - Create new model preserving fields and layout\n * - Handle group changes\n * - Access control checks\n * - Publish before event\n * - Delegate to repository for validation and persistence\n * - Publish after event or error event\n *\n * Note: Repository handles domain validations (modelId generation, uniqueness, etc.)\n */\nclass CreateModelFromUseCaseImpl implements UseCaseAbstraction.Interface {\n public constructor(\n private getModelUseCase: GetModelUseCase.Interface,\n private eventPublisher: EventPublisher.Interface,\n private repository: CreateModelFromRepository.Interface,\n private accessControl: AccessControl.Interface,\n private tenantContext: TenantContext.Interface,\n private identityContext: IdentityContext.Interface\n ) {}\n\n async execute(\n modelId: string,\n input: CmsModelCreateFromInput\n ): 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 // Get the original model (with access control check)\n const getResult = await this.getModelUseCase.execute(modelId);\n if (getResult.isFail()) {\n return getResult;\n }\n\n const original = getResult.value;\n\n // Validate input (merge with original description if not provided)\n const validationResult = await createModelCreateFromValidation().safeParseAsync({\n ...input,\n description: input.description || original.description\n });\n\n if (!validationResult.success) {\n const zodError = createZodError(validationResult.error);\n return Result.fail(new ModelValidationError(zodError.message));\n }\n\n const data = removeUndefinedValues(validationResult.data);\n\n // Create new model from original (preserve fields and layout)\n const identity = this.identityContext.getIdentity();\n const tenant = this.tenantContext.getTenant();\n\n const model: CmsModel = {\n ...original,\n isPlugin: undefined,\n group: input.group || original.group,\n singularApiName: data.singularApiName,\n pluralApiName: data.pluralApiName,\n icon: data.icon,\n name: data.name,\n modelId: data.modelId || \"\", // Will be set by repository\n description: data.description || \"\",\n createdBy: {\n id: identity.id,\n displayName: identity.displayName,\n type: identity.type\n },\n createdOn: new Date().toISOString(),\n savedOn: new Date().toISOString(),\n tenant: original.tenant || tenant.id\n };\n\n // Access control check on the new 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(\n new ModelBeforeCreateFromEvent({ model, original, input: data })\n );\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 ModelCreateFromErrorEvent({\n input: data,\n model,\n original,\n error: result.error\n })\n );\n return Result.fail(result.error);\n }\n\n // Publish after event\n await this.eventPublisher.publish(new ModelAfterCreateFromEvent({ model, original }));\n\n return Result.ok(model);\n }\n}\n\nexport const CreateModelFromUseCase = UseCaseAbstraction.createImplementation({\n implementation: CreateModelFromUseCaseImpl,\n dependencies: [\n GetModelUseCase,\n EventPublisher,\n CreateModelFromRepository,\n AccessControl,\n TenantContext,\n IdentityContext\n ]\n});\n"],"names":["CreateModelFromUseCaseImpl","getModelUseCase","eventPublisher","repository","accessControl","tenantContext","identityContext","modelId","input","canAccess","Result","ModelNotAuthorizedError","getResult","original","validationResult","createModelCreateFromValidation","zodError","createZodError","ModelValidationError","data","removeUndefinedValues","identity","tenant","model","undefined","Date","canAccessModel","ModelBeforeCreateFromEvent","result","ModelCreateFromErrorEvent","ModelAfterCreateFromEvent","CreateModelFromUseCase","UseCaseAbstraction","GetModelUseCase","EventPublisher","CreateModelFromRepository","AccessControl","TenantContext","IdentityContext"],"mappings":";;;;;;;;;;;AAiCA,MAAMA;IACF,YACYC,eAA0C,EAC1CC,cAAwC,EACxCC,UAA+C,EAC/CC,aAAsC,EACtCC,aAAsC,EACtCC,eAA0C,CACpD;aANUL,eAAe,GAAfA;aACAC,cAAc,GAAdA;aACAC,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,aAAa,GAAbA;aACAC,eAAe,GAAfA;IACT;IAEH,MAAM,QACFC,OAAe,EACfC,KAA8B,EACqB;QAEnD,MAAMC,YAAY,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAE,KAAK;QAAI;QACrE,IAAI,CAACA,WACD,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAI3B,MAAMC,YAAY,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAACL;QACrD,IAAIK,UAAU,MAAM,IAChB,OAAOA;QAGX,MAAMC,WAAWD,UAAU,KAAK;QAGhC,MAAME,mBAAmB,MAAMC,kCAAkC,cAAc,CAAC;YAC5E,GAAGP,KAAK;YACR,aAAaA,MAAM,WAAW,IAAIK,SAAS,WAAW;QAC1D;QAEA,IAAI,CAACC,iBAAiB,OAAO,EAAE;YAC3B,MAAME,WAAWC,eAAeH,iBAAiB,KAAK;YACtD,OAAOJ,OAAO,IAAI,CAAC,IAAIQ,qBAAqBF,SAAS,OAAO;QAChE;QAEA,MAAMG,OAAOC,sBAAsBN,iBAAiB,IAAI;QAGxD,MAAMO,WAAW,IAAI,CAAC,eAAe,CAAC,WAAW;QACjD,MAAMC,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAE3C,MAAMC,QAAkB;YACpB,GAAGV,QAAQ;YACX,UAAUW;YACV,OAAOhB,MAAM,KAAK,IAAIK,SAAS,KAAK;YACpC,iBAAiBM,KAAK,eAAe;YACrC,eAAeA,KAAK,aAAa;YACjC,MAAMA,KAAK,IAAI;YACf,MAAMA,KAAK,IAAI;YACf,SAASA,KAAK,OAAO,IAAI;YACzB,aAAaA,KAAK,WAAW,IAAI;YACjC,WAAW;gBACP,IAAIE,SAAS,EAAE;gBACf,aAAaA,SAAS,WAAW;gBACjC,MAAMA,SAAS,IAAI;YACvB;YACA,WAAW,IAAII,OAAO,WAAW;YACjC,SAAS,IAAIA,OAAO,WAAW;YAC/B,QAAQZ,SAAS,MAAM,IAAIS,OAAO,EAAE;QACxC;QAGA,MAAMI,iBAAiB,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAEH;YAAO,KAAK;QAAI;QACjF,IAAI,CAACG,gBACD,OAAOhB,OAAO,IAAI,CAACC,wBAAwB,SAAS,CAACY;QAIzD,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAII,2BAA2B;YAAEJ;YAAOV;YAAU,OAAOM;QAAK;QAIlE,MAAMS,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACL;QAC7C,IAAIK,OAAO,MAAM,IAAI;YAEjB,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIC,0BAA0B;gBAC1B,OAAOV;gBACPI;gBACAV;gBACA,OAAOe,OAAO,KAAK;YACvB;YAEJ,OAAOlB,OAAO,IAAI,CAACkB,OAAO,KAAK;QACnC;QAGA,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAIE,0BAA0B;YAAEP;YAAOV;QAAS;QAElF,OAAOH,OAAO,EAAE,CAACa;IACrB;AACJ;AAEO,MAAMQ,gDAAyBC,uBAAAA,oBAAuC,CAAC;IAC1E,gBAAgBhC;IAChB,cAAc;QACViC;QACAC;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
1
+ {"version":3,"file":"features/contentModel/CreateModelFrom/CreateModelFromUseCase.js","sources":["../../../../src/features/contentModel/CreateModelFrom/CreateModelFromUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { CreateModelFromUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport { CreateModelFromRepository } from \"./abstractions.js\";\nimport { EventPublisher } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport { ModelBeforeCreateFromEvent } from \"./events.js\";\nimport { ModelAfterCreateFromEvent } from \"./events.js\";\nimport { ModelCreateFromErrorEvent } 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 { createModelCreateFromValidation } from \"~/domain/contentModel/schemas.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport type { CmsModelCreateFromInput } from \"~/types/index.js\";\nimport { GetModelUseCase } from \"~/features/contentModel/GetModel/index.js\";\n\n/**\n * CreateModelFromUseCase - Clone/copy a model from existing model.\n *\n * Responsibilities:\n * - Validate input (Zod)\n * - Fetch original model\n * - Create new model preserving fields and layout\n * - Handle group changes\n * - Access control checks\n * - Publish before event\n * - Delegate to repository for validation and persistence\n * - Publish after event or error event\n *\n * Note: Repository handles domain validations (modelId generation, uniqueness, etc.)\n */\nclass CreateModelFromUseCaseImpl implements UseCaseAbstraction.Interface {\n public constructor(\n private getModelUseCase: GetModelUseCase.Interface,\n private eventPublisher: EventPublisher.Interface,\n private repository: CreateModelFromRepository.Interface,\n private accessControl: AccessControl.Interface,\n private tenantContext: TenantContext.Interface,\n private identityContext: IdentityContext.Interface\n ) {}\n\n async execute(\n modelId: string,\n input: CmsModelCreateFromInput\n ): 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 // Get the original model (with access control check)\n const getResult = await this.getModelUseCase.execute(modelId);\n if (getResult.isFail()) {\n return getResult;\n }\n\n const original = getResult.value;\n\n // Validate input (merge with original description if not provided)\n const validationResult = await createModelCreateFromValidation().safeParseAsync({\n ...input,\n description: input.description || original.description\n });\n\n if (!validationResult.success) {\n const zodError = createZodError(validationResult.error);\n return Result.fail(new ModelValidationError(zodError.message));\n }\n\n const data = removeUndefinedValues(validationResult.data);\n\n // Create new model from original (preserve fields and layout)\n const identity = this.identityContext.getIdentity();\n const tenant = this.tenantContext.getTenant();\n\n const model: CmsModel = {\n ...original,\n isPlugin: undefined,\n group: input.group || original.group,\n singularApiName: data.singularApiName,\n pluralApiName: data.pluralApiName,\n icon: data.icon,\n name: data.name,\n modelId: data.modelId || \"\", // Will be set by repository\n description: data.description || \"\",\n createdBy: {\n id: identity.id,\n displayName: identity.displayName,\n type: identity.type\n },\n createdOn: new Date().toISOString(),\n savedOn: new Date().toISOString(),\n tenant: original.tenant || tenant.id\n };\n\n // Access control check on the new 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(\n new ModelBeforeCreateFromEvent({ model, original, input: data })\n );\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 ModelCreateFromErrorEvent({\n input: data,\n model,\n original,\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 ModelAfterCreateFromEvent({\n model: result.value,\n original\n })\n );\n\n return Result.ok(result.value);\n }\n}\n\nexport const CreateModelFromUseCase = UseCaseAbstraction.createImplementation({\n implementation: CreateModelFromUseCaseImpl,\n dependencies: [\n GetModelUseCase,\n EventPublisher,\n CreateModelFromRepository,\n AccessControl,\n TenantContext,\n IdentityContext\n ]\n});\n"],"names":["CreateModelFromUseCaseImpl","getModelUseCase","eventPublisher","repository","accessControl","tenantContext","identityContext","modelId","input","canAccess","Result","ModelNotAuthorizedError","getResult","original","validationResult","createModelCreateFromValidation","zodError","createZodError","ModelValidationError","data","removeUndefinedValues","identity","tenant","model","undefined","Date","canAccessModel","ModelBeforeCreateFromEvent","result","ModelCreateFromErrorEvent","ModelAfterCreateFromEvent","CreateModelFromUseCase","UseCaseAbstraction","GetModelUseCase","EventPublisher","CreateModelFromRepository","AccessControl","TenantContext","IdentityContext"],"mappings":";;;;;;;;;;;AAiCA,MAAMA;IACF,YACYC,eAA0C,EAC1CC,cAAwC,EACxCC,UAA+C,EAC/CC,aAAsC,EACtCC,aAAsC,EACtCC,eAA0C,CACpD;aANUL,eAAe,GAAfA;aACAC,cAAc,GAAdA;aACAC,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,aAAa,GAAbA;aACAC,eAAe,GAAfA;IACT;IAEH,MAAM,QACFC,OAAe,EACfC,KAA8B,EACqB;QAEnD,MAAMC,YAAY,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAE,KAAK;QAAI;QACrE,IAAI,CAACA,WACD,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAI3B,MAAMC,YAAY,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAACL;QACrD,IAAIK,UAAU,MAAM,IAChB,OAAOA;QAGX,MAAMC,WAAWD,UAAU,KAAK;QAGhC,MAAME,mBAAmB,MAAMC,kCAAkC,cAAc,CAAC;YAC5E,GAAGP,KAAK;YACR,aAAaA,MAAM,WAAW,IAAIK,SAAS,WAAW;QAC1D;QAEA,IAAI,CAACC,iBAAiB,OAAO,EAAE;YAC3B,MAAME,WAAWC,eAAeH,iBAAiB,KAAK;YACtD,OAAOJ,OAAO,IAAI,CAAC,IAAIQ,qBAAqBF,SAAS,OAAO;QAChE;QAEA,MAAMG,OAAOC,sBAAsBN,iBAAiB,IAAI;QAGxD,MAAMO,WAAW,IAAI,CAAC,eAAe,CAAC,WAAW;QACjD,MAAMC,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAE3C,MAAMC,QAAkB;YACpB,GAAGV,QAAQ;YACX,UAAUW;YACV,OAAOhB,MAAM,KAAK,IAAIK,SAAS,KAAK;YACpC,iBAAiBM,KAAK,eAAe;YACrC,eAAeA,KAAK,aAAa;YACjC,MAAMA,KAAK,IAAI;YACf,MAAMA,KAAK,IAAI;YACf,SAASA,KAAK,OAAO,IAAI;YACzB,aAAaA,KAAK,WAAW,IAAI;YACjC,WAAW;gBACP,IAAIE,SAAS,EAAE;gBACf,aAAaA,SAAS,WAAW;gBACjC,MAAMA,SAAS,IAAI;YACvB;YACA,WAAW,IAAII,OAAO,WAAW;YACjC,SAAS,IAAIA,OAAO,WAAW;YAC/B,QAAQZ,SAAS,MAAM,IAAIS,OAAO,EAAE;QACxC;QAGA,MAAMI,iBAAiB,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAEH;YAAO,KAAK;QAAI;QACjF,IAAI,CAACG,gBACD,OAAOhB,OAAO,IAAI,CAACC,wBAAwB,SAAS,CAACY;QAIzD,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAII,2BAA2B;YAAEJ;YAAOV;YAAU,OAAOM;QAAK;QAIlE,MAAMS,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACL;QAC7C,IAAIK,OAAO,MAAM,IAAI;YAEjB,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIC,0BAA0B;gBAC1B,OAAOV;gBACPI;gBACAV;gBACA,OAAOe,OAAO,KAAK;YACvB;YAEJ,OAAOlB,OAAO,IAAI,CAACkB,OAAO,KAAK;QACnC;QAGA,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIE,0BAA0B;YAC1B,OAAOF,OAAO,KAAK;YACnBf;QACJ;QAGJ,OAAOH,OAAO,EAAE,CAACkB,OAAO,KAAK;IACjC;AACJ;AAEO,MAAMG,gDAAyBC,uBAAAA,oBAAuC,CAAC;IAC1E,gBAAgBhC;IAChB,cAAc;QACViC;QACAC;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
@@ -30,7 +30,7 @@ export declare namespace CreateModelFromUseCase {
30
30
  * CreateModelFromRepository - Validates domain rules and persists cloned model.
31
31
  */
32
32
  export interface ICreateModelFromRepository {
33
- execute(model: CmsModel): Promise<Result<void, RepositoryError>>;
33
+ execute(model: CmsModel): Promise<Result<CmsModel, RepositoryError>>;
34
34
  }
35
35
  export interface ICreateModelFromRepositoryErrors {
36
36
  alreadyExists: ModelAlreadyExistsError;
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/CreateModelFrom/abstractions.js","sources":["../../../../src/features/contentModel/CreateModelFrom/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\nimport type { CmsModel, CmsModelCreateFromInput } from \"~/types/index.js\";\nimport {\n ModelAlreadyExistsError,\n ModelNotAuthorizedError,\n type ModelNotFoundError,\n type ModelPersistenceError,\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 * CreateModelFrom Use Case (Clone/Copy Model)\n */\nexport interface ICreateModelFromUseCase {\n execute(\n modelId: string,\n input: CmsModelCreateFromInput\n ): Promise<Result<CmsModel, UseCaseError>>;\n}\n\nexport interface ICreateModelFromUseCaseErrors {\n notFound: ModelNotFoundError;\n notAuthorized: ModelNotAuthorizedError;\n validation: ModelValidationError;\n alreadyExists: ModelAlreadyExistsError;\n persistence: ModelPersistenceError;\n groupNotFound: GroupNotFoundError;\n groupNotAccessible: GroupNotAuthorizedError;\n}\n\ntype UseCaseError = ICreateModelFromUseCaseErrors[keyof ICreateModelFromUseCaseErrors];\n\n/** Create a content model by cloning an existing one. */\nexport const CreateModelFromUseCase =\n createAbstraction<ICreateModelFromUseCase>(\"CreateModelFromUseCase\");\n\nexport namespace CreateModelFromUseCase {\n export type Interface = ICreateModelFromUseCase;\n export type Input = CmsModelCreateFromInput;\n\n export type Error = UseCaseError;\n export type Return = Promise<Result<CmsModel, UseCaseError>>;\n}\n\n/**\n * CreateModelFromRepository - Validates domain rules and persists cloned model.\n */\nexport interface ICreateModelFromRepository {\n execute(model: CmsModel): Promise<Result<void, RepositoryError>>;\n}\n\nexport interface ICreateModelFromRepositoryErrors {\n alreadyExists: ModelAlreadyExistsError;\n validation: ModelValidationError;\n persistence: ModelPersistenceError;\n}\n\ntype RepositoryError = ICreateModelFromRepositoryErrors[keyof ICreateModelFromRepositoryErrors];\n\nexport const CreateModelFromRepository = createAbstraction<ICreateModelFromRepository>(\n \"CreateModelFromRepository\"\n);\n\nexport namespace CreateModelFromRepository {\n export type Interface = ICreateModelFromRepository;\n export type Error = RepositoryError;\n}\n"],"names":["CreateModelFromUseCase","createAbstraction","CreateModelFromRepository"],"mappings":";AAqCO,MAAMA,yBACTC,kBAA2C;AAyBxC,MAAMC,4BAA4BD,kBACrC"}
1
+ {"version":3,"file":"features/contentModel/CreateModelFrom/abstractions.js","sources":["../../../../src/features/contentModel/CreateModelFrom/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\nimport type { CmsModel, CmsModelCreateFromInput } from \"~/types/index.js\";\nimport {\n ModelAlreadyExistsError,\n ModelNotAuthorizedError,\n type ModelNotFoundError,\n type ModelPersistenceError,\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 * CreateModelFrom Use Case (Clone/Copy Model)\n */\nexport interface ICreateModelFromUseCase {\n execute(\n modelId: string,\n input: CmsModelCreateFromInput\n ): Promise<Result<CmsModel, UseCaseError>>;\n}\n\nexport interface ICreateModelFromUseCaseErrors {\n notFound: ModelNotFoundError;\n notAuthorized: ModelNotAuthorizedError;\n validation: ModelValidationError;\n alreadyExists: ModelAlreadyExistsError;\n persistence: ModelPersistenceError;\n groupNotFound: GroupNotFoundError;\n groupNotAccessible: GroupNotAuthorizedError;\n}\n\ntype UseCaseError = ICreateModelFromUseCaseErrors[keyof ICreateModelFromUseCaseErrors];\n\n/** Create a content model by cloning an existing one. */\nexport const CreateModelFromUseCase =\n createAbstraction<ICreateModelFromUseCase>(\"CreateModelFromUseCase\");\n\nexport namespace CreateModelFromUseCase {\n export type Interface = ICreateModelFromUseCase;\n export type Input = CmsModelCreateFromInput;\n\n export type Error = UseCaseError;\n export type Return = Promise<Result<CmsModel, UseCaseError>>;\n}\n\n/**\n * CreateModelFromRepository - Validates domain rules and persists cloned model.\n */\nexport interface ICreateModelFromRepository {\n execute(model: CmsModel): Promise<Result<CmsModel, RepositoryError>>;\n}\n\nexport interface ICreateModelFromRepositoryErrors {\n alreadyExists: ModelAlreadyExistsError;\n validation: ModelValidationError;\n persistence: ModelPersistenceError;\n}\n\ntype RepositoryError = ICreateModelFromRepositoryErrors[keyof ICreateModelFromRepositoryErrors];\n\nexport const CreateModelFromRepository = createAbstraction<ICreateModelFromRepository>(\n \"CreateModelFromRepository\"\n);\n\nexport namespace CreateModelFromRepository {\n export type Interface = ICreateModelFromRepository;\n export type Error = RepositoryError;\n}\n"],"names":["CreateModelFromUseCase","createAbstraction","CreateModelFromRepository"],"mappings":";AAqCO,MAAMA,yBACTC,kBAA2C;AAyBxC,MAAMC,4BAA4BD,kBACrC"}
@@ -3,6 +3,7 @@ import { DeleteModelRepository as RepositoryAbstraction } from "./abstractions.j
3
3
  import { ModelCache, ModelsFetcher } from "../../../features/contentModel/shared/abstractions.js";
4
4
  import { StorageOperations } from "../../../features/shared/abstractions.js";
5
5
  import type { CmsModel } from "../../../types/index.js";
6
+ import { RuntimeTenant } from "../../../features/runtimeTenant/abstractions.js";
6
7
  /**
7
8
  * DeleteModelRepository - Validates and deletes a model from storage.
8
9
  *
@@ -17,8 +18,9 @@ declare class DeleteModelRepositoryImpl implements RepositoryAbstraction.Interfa
17
18
  private modelCache;
18
19
  private modelsFetcher;
19
20
  private storageOperations;
20
- constructor(modelCache: ModelCache.Interface, modelsFetcher: ModelsFetcher.Interface, storageOperations: StorageOperations.Interface);
21
- execute(model: CmsModel): Promise<Result<void, RepositoryAbstraction.Error>>;
21
+ private runtimeTenant;
22
+ constructor(modelCache: ModelCache.Interface, modelsFetcher: ModelsFetcher.Interface, storageOperations: StorageOperations.Interface, runtimeTenant: RuntimeTenant.Interface);
23
+ execute(initialModel: CmsModel): Promise<Result<void, RepositoryAbstraction.Error>>;
22
24
  }
23
25
  export declare const DeleteModelRepository: typeof DeleteModelRepositoryImpl & {
24
26
  __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IDeleteModelRepository>;
@@ -3,13 +3,16 @@ import { DeleteModelRepository } from "./abstractions.js";
3
3
  import { ModelCache, ModelsFetcher } from "../shared/abstractions.js";
4
4
  import { ModelCannotDeleteCodeModelError, ModelPersistenceError } from "../../../domain/contentModel/errors.js";
5
5
  import { StorageOperations } from "../../shared/abstractions.js";
6
+ import { RuntimeTenant } from "../../runtimeTenant/abstractions.js";
6
7
  class DeleteModelRepositoryImpl {
7
- constructor(modelCache, modelsFetcher, storageOperations){
8
+ constructor(modelCache, modelsFetcher, storageOperations, runtimeTenant){
8
9
  this.modelCache = modelCache;
9
10
  this.modelsFetcher = modelsFetcher;
10
11
  this.storageOperations = storageOperations;
12
+ this.runtimeTenant = runtimeTenant;
11
13
  }
12
- async execute(model) {
14
+ async execute(initialModel) {
15
+ const model = this.runtimeTenant.assign(initialModel);
13
16
  try {
14
17
  const existingModelResult = await this.modelsFetcher.fetchById(model.modelId);
15
18
  if (existingModelResult.isFail()) return Result.fail(new ModelPersistenceError(existingModelResult.error));
@@ -29,7 +32,8 @@ const DeleteModelRepository_DeleteModelRepository = DeleteModelRepository.create
29
32
  dependencies: [
30
33
  ModelCache,
31
34
  ModelsFetcher,
32
- StorageOperations
35
+ StorageOperations,
36
+ RuntimeTenant
33
37
  ]
34
38
  });
35
39
  export { DeleteModelRepository_DeleteModelRepository as DeleteModelRepository };
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/DeleteModel/DeleteModelRepository.js","sources":["../../../../src/features/contentModel/DeleteModel/DeleteModelRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { DeleteModelRepository as RepositoryAbstraction } from \"./abstractions.js\";\nimport { ModelCache, ModelsFetcher } from \"~/features/contentModel/shared/abstractions.js\";\nimport {\n ModelCannotDeleteCodeModelError,\n ModelPersistenceError\n} from \"~/domain/contentModel/errors.js\";\nimport { StorageOperations } from \"~/features/shared/abstractions.js\";\nimport type { CmsModel } from \"~/types/index.js\";\n\n/**\n * DeleteModelRepository - Validates and deletes a model from storage.\n *\n * Responsibilities:\n * - Validate model is not defined via plugin (core domain rule)\n * - Delete from storage\n * - Clear ModelCache after successful deletion\n *\n * Note: Entry validation and cleanup is handled by decorator\n */\nclass DeleteModelRepositoryImpl implements RepositoryAbstraction.Interface {\n public constructor(\n private modelCache: ModelCache.Interface,\n private modelsFetcher: ModelsFetcher.Interface,\n private storageOperations: StorageOperations.Interface\n ) {}\n\n async execute(model: CmsModel): Promise<Result<void, RepositoryAbstraction.Error>> {\n try {\n // Check if this is a plugin model\n const existingModelResult = await this.modelsFetcher.fetchById(model.modelId);\n if (existingModelResult.isFail()) {\n return Result.fail(new ModelPersistenceError(existingModelResult.error));\n }\n\n if (existingModelResult.value.isPlugin) {\n return Result.fail(new ModelCannotDeleteCodeModelError(model.modelId));\n }\n\n // Delete from storage\n await this.storageOperations.models.delete({ model });\n\n // Clear cache\n this.modelCache.clear();\n\n return Result.ok();\n } catch (error) {\n return Result.fail(new ModelPersistenceError(error as Error));\n }\n }\n}\n\nexport const DeleteModelRepository = RepositoryAbstraction.createImplementation({\n implementation: DeleteModelRepositoryImpl,\n dependencies: [ModelCache, ModelsFetcher, StorageOperations]\n});\n"],"names":["DeleteModelRepositoryImpl","modelCache","modelsFetcher","storageOperations","model","existingModelResult","Result","ModelPersistenceError","ModelCannotDeleteCodeModelError","error","DeleteModelRepository","RepositoryAbstraction","ModelCache","ModelsFetcher","StorageOperations"],"mappings":";;;;;AAoBA,MAAMA;IACF,YACYC,UAAgC,EAChCC,aAAsC,EACtCC,iBAA8C,CACxD;aAHUF,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,iBAAiB,GAAjBA;IACT;IAEH,MAAM,QAAQC,KAAe,EAAsD;QAC/E,IAAI;YAEA,MAAMC,sBAAsB,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAACD,MAAM,OAAO;YAC5E,IAAIC,oBAAoB,MAAM,IAC1B,OAAOC,OAAO,IAAI,CAAC,IAAIC,sBAAsBF,oBAAoB,KAAK;YAG1E,IAAIA,oBAAoB,KAAK,CAAC,QAAQ,EAClC,OAAOC,OAAO,IAAI,CAAC,IAAIE,gCAAgCJ,MAAM,OAAO;YAIxE,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC;gBAAEA;YAAM;YAGnD,IAAI,CAAC,UAAU,CAAC,KAAK;YAErB,OAAOE,OAAO,EAAE;QACpB,EAAE,OAAOG,OAAO;YACZ,OAAOH,OAAO,IAAI,CAAC,IAAIC,sBAAsBE;QACjD;IACJ;AACJ;AAEO,MAAMC,8CAAwBC,sBAAAA,oBAA0C,CAAC;IAC5E,gBAAgBX;IAChB,cAAc;QAACY;QAAYC;QAAeC;KAAkB;AAChE"}
1
+ {"version":3,"file":"features/contentModel/DeleteModel/DeleteModelRepository.js","sources":["../../../../src/features/contentModel/DeleteModel/DeleteModelRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { DeleteModelRepository as RepositoryAbstraction } from \"./abstractions.js\";\nimport { ModelCache, ModelsFetcher } from \"~/features/contentModel/shared/abstractions.js\";\nimport {\n ModelCannotDeleteCodeModelError,\n ModelPersistenceError\n} from \"~/domain/contentModel/errors.js\";\nimport { StorageOperations } from \"~/features/shared/abstractions.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport { RuntimeTenant } from \"~/features/runtimeTenant/abstractions.js\";\n\n/**\n * DeleteModelRepository - Validates and deletes a model from storage.\n *\n * Responsibilities:\n * - Validate model is not defined via plugin (core domain rule)\n * - Delete from storage\n * - Clear ModelCache after successful deletion\n *\n * Note: Entry validation and cleanup is handled by decorator\n */\nclass DeleteModelRepositoryImpl implements RepositoryAbstraction.Interface {\n public constructor(\n private modelCache: ModelCache.Interface,\n private modelsFetcher: ModelsFetcher.Interface,\n private storageOperations: StorageOperations.Interface,\n private runtimeTenant: RuntimeTenant.Interface\n ) {}\n\n async execute(initialModel: CmsModel): Promise<Result<void, RepositoryAbstraction.Error>> {\n const model = this.runtimeTenant.assign(initialModel);\n try {\n // Check if this is a plugin model\n const existingModelResult = await this.modelsFetcher.fetchById(model.modelId);\n if (existingModelResult.isFail()) {\n return Result.fail(new ModelPersistenceError(existingModelResult.error));\n }\n\n if (existingModelResult.value.isPlugin) {\n return Result.fail(new ModelCannotDeleteCodeModelError(model.modelId));\n }\n\n // Delete from storage\n await this.storageOperations.models.delete({ model });\n\n // Clear cache\n this.modelCache.clear();\n\n return Result.ok();\n } catch (error) {\n return Result.fail(new ModelPersistenceError(error as Error));\n }\n }\n}\n\nexport const DeleteModelRepository = RepositoryAbstraction.createImplementation({\n implementation: DeleteModelRepositoryImpl,\n dependencies: [ModelCache, ModelsFetcher, StorageOperations, RuntimeTenant]\n});\n"],"names":["DeleteModelRepositoryImpl","modelCache","modelsFetcher","storageOperations","runtimeTenant","initialModel","model","existingModelResult","Result","ModelPersistenceError","ModelCannotDeleteCodeModelError","error","DeleteModelRepository","RepositoryAbstraction","ModelCache","ModelsFetcher","StorageOperations","RuntimeTenant"],"mappings":";;;;;;AAqBA,MAAMA;IACF,YACYC,UAAgC,EAChCC,aAAsC,EACtCC,iBAA8C,EAC9CC,aAAsC,CAChD;aAJUH,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,iBAAiB,GAAjBA;aACAC,aAAa,GAAbA;IACT;IAEH,MAAM,QAAQC,YAAsB,EAAsD;QACtF,MAAMC,QAAQ,IAAI,CAAC,aAAa,CAAC,MAAM,CAACD;QACxC,IAAI;YAEA,MAAME,sBAAsB,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAACD,MAAM,OAAO;YAC5E,IAAIC,oBAAoB,MAAM,IAC1B,OAAOC,OAAO,IAAI,CAAC,IAAIC,sBAAsBF,oBAAoB,KAAK;YAG1E,IAAIA,oBAAoB,KAAK,CAAC,QAAQ,EAClC,OAAOC,OAAO,IAAI,CAAC,IAAIE,gCAAgCJ,MAAM,OAAO;YAIxE,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC;gBAAEA;YAAM;YAGnD,IAAI,CAAC,UAAU,CAAC,KAAK;YAErB,OAAOE,OAAO,EAAE;QACpB,EAAE,OAAOG,OAAO;YACZ,OAAOH,OAAO,IAAI,CAAC,IAAIC,sBAAsBE;QACjD;IACJ;AACJ;AAEO,MAAMC,8CAAwBC,sBAAAA,oBAA0C,CAAC;IAC5E,gBAAgBb;IAChB,cAAc;QAACc;QAAYC;QAAeC;QAAmBC;KAAc;AAC/E"}
@@ -4,6 +4,7 @@ import { ModelCache, ModelsFetcher } from "../../../features/contentModel/shared
4
4
  import { CmsContext, StorageOperations } from "../../../features/shared/abstractions.js";
5
5
  import type { CmsModel } from "../../../types/index.js";
6
6
  import { ModelFieldCompression } from "../../../features/contentModel/ModelFieldCompression/index.js";
7
+ import { RuntimeTenant } from "../../../features/runtimeTenant/abstractions.js";
7
8
  /**
8
9
  * UpdateModelRepository - Validates domain rules and persists model updates.
9
10
  *
@@ -21,8 +22,9 @@ declare class UpdateModelRepositoryImpl implements RepositoryAbstraction.Interfa
21
22
  private readonly storageOperations;
22
23
  private readonly cmsContext;
23
24
  private readonly modelFieldCompression;
24
- constructor(modelCache: ModelCache.Interface, modelsFetcher: ModelsFetcher.Interface, storageOperations: StorageOperations.Interface, cmsContext: CmsContext.Interface, modelFieldCompression: ModelFieldCompression.Interface);
25
- execute(model: CmsModel, original: CmsModel): Promise<Result<void, RepositoryAbstraction.Error>>;
25
+ private readonly runtimeTenant;
26
+ constructor(modelCache: ModelCache.Interface, modelsFetcher: ModelsFetcher.Interface, storageOperations: StorageOperations.Interface, cmsContext: CmsContext.Interface, modelFieldCompression: ModelFieldCompression.Interface, runtimeTenant: RuntimeTenant.Interface);
27
+ execute(initialModel: CmsModel, original: CmsModel): Promise<Result<CmsModel, RepositoryAbstraction.Error>>;
26
28
  }
27
29
  export declare const UpdateModelRepository: typeof UpdateModelRepositoryImpl & {
28
30
  __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IUpdateModelRepository>;
@@ -8,15 +8,18 @@ import { validateSingularApiName } from "../../../domain/contentModel/validation
8
8
  import { validatePluralApiName } from "../../../domain/contentModel/validation/pluralApiName.js";
9
9
  import { validateModelFields } from "../../../domain/contentModel/validation/modelFields.js";
10
10
  import { ModelFieldCompression } from "../ModelFieldCompression/index.js";
11
+ import { RuntimeTenant } from "../../runtimeTenant/abstractions.js";
11
12
  class UpdateModelRepositoryImpl {
12
- constructor(modelCache, modelsFetcher, storageOperations, cmsContext, modelFieldCompression){
13
+ constructor(modelCache, modelsFetcher, storageOperations, cmsContext, modelFieldCompression, runtimeTenant){
13
14
  this.modelCache = modelCache;
14
15
  this.modelsFetcher = modelsFetcher;
15
16
  this.storageOperations = storageOperations;
16
17
  this.cmsContext = cmsContext;
17
18
  this.modelFieldCompression = modelFieldCompression;
19
+ this.runtimeTenant = runtimeTenant;
18
20
  }
19
- async execute(model, original) {
21
+ async execute(initialModel, original) {
22
+ const model = this.runtimeTenant.assign(initialModel);
20
23
  try {
21
24
  try {
22
25
  validateEndingAllowed({
@@ -66,7 +69,7 @@ class UpdateModelRepositoryImpl {
66
69
  }
67
70
  });
68
71
  this.modelCache.clear();
69
- return Result.ok();
72
+ return Result.ok(model);
70
73
  } catch (error) {
71
74
  return Result.fail(new ModelPersistenceError(error));
72
75
  }
@@ -79,7 +82,8 @@ const UpdateModelRepository_UpdateModelRepository = UpdateModelRepository.create
79
82
  ModelsFetcher,
80
83
  StorageOperations,
81
84
  CmsContext,
82
- ModelFieldCompression
85
+ ModelFieldCompression,
86
+ RuntimeTenant
83
87
  ]
84
88
  });
85
89
  export { UpdateModelRepository_UpdateModelRepository as UpdateModelRepository };
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/UpdateModel/UpdateModelRepository.js","sources":["../../../../src/features/contentModel/UpdateModel/UpdateModelRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { UpdateModelRepository as RepositoryAbstraction } from \"./abstractions.js\";\nimport { ModelCache, ModelsFetcher } from \"~/features/contentModel/shared/abstractions.js\";\nimport {\n ModelCannotUpdateCodeModelError,\n ModelPersistenceError,\n ModelValidationError\n} from \"~/domain/contentModel/errors.js\";\nimport { CmsContext, StorageOperations } from \"~/features/shared/abstractions.js\";\nimport { validateEndingAllowed } from \"~/crud/contentModel/validate/endingAllowed.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 type { CmsModel } from \"~/types/index.js\";\nimport { ModelFieldCompression } from \"~/features/contentModel/ModelFieldCompression/index.js\";\n\n/**\n * UpdateModelRepository - Validates domain rules and persists model updates.\n *\n * Responsibilities:\n * - Validate API name endings\n * - Validate singularApiName uniqueness (excluding current model)\n * - Validate pluralApiName uniqueness (excluding current model)\n * - Validate model fields\n * - Persist to storage\n * - Clear ModelCache after successful update\n */\nclass UpdateModelRepositoryImpl implements RepositoryAbstraction.Interface {\n public constructor(\n private readonly modelCache: ModelCache.Interface,\n private readonly modelsFetcher: ModelsFetcher.Interface,\n private readonly storageOperations: StorageOperations.Interface,\n private readonly cmsContext: CmsContext.Interface,\n private readonly modelFieldCompression: ModelFieldCompression.Interface\n ) {}\n\n async execute(\n model: CmsModel,\n original: CmsModel\n ): Promise<Result<void, RepositoryAbstraction.Error>> {\n try {\n // Validate API name endings\n try {\n validateEndingAllowed({ model });\n } catch (error) {\n return Result.fail(\n new ModelValidationError({ message: error.message, data: error.data })\n );\n }\n\n // Get all models for validation (excluding the current model)\n const modelsResult = await this.cmsContext.security.withoutAuthorization(async () => {\n return await this.modelsFetcher.fetchAll();\n });\n\n if (modelsResult.isFail()) {\n return Result.fail(new ModelPersistenceError(modelsResult.error));\n }\n\n const allModels = modelsResult.value;\n const models = allModels.filter(m => m.modelId !== model.modelId);\n\n // Check if this is a plugin model\n const existingModelResult = await this.modelsFetcher.fetchById(model.modelId);\n if (existingModelResult.isFail()) {\n return Result.fail(new ModelPersistenceError(existingModelResult.error));\n }\n\n if (existingModelResult.value.isPlugin) {\n return Result.fail(new ModelCannotUpdateCodeModelError(model.modelId));\n }\n\n // Validate uniqueness\n try {\n for (const existingModel of models) {\n validateSingularApiName({\n existingModel,\n model\n });\n validatePluralApiName({\n existingModel,\n model\n });\n }\n\n // Validate model fields\n await validateModelFields({\n models,\n model,\n original,\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 const fields = await this.modelFieldCompression.compress(model.fields);\n\n // Persist to storage\n await this.storageOperations.models.update({\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 return Result.fail(new ModelPersistenceError(error as Error));\n }\n }\n}\n\nexport const UpdateModelRepository = RepositoryAbstraction.createImplementation({\n implementation: UpdateModelRepositoryImpl,\n dependencies: [ModelCache, ModelsFetcher, StorageOperations, CmsContext, ModelFieldCompression]\n});\n"],"names":["UpdateModelRepositoryImpl","modelCache","modelsFetcher","storageOperations","cmsContext","modelFieldCompression","model","original","validateEndingAllowed","error","Result","ModelValidationError","modelsResult","ModelPersistenceError","allModels","models","m","existingModelResult","ModelCannotUpdateCodeModelError","existingModel","validateSingularApiName","validatePluralApiName","validateModelFields","fields","UpdateModelRepository","RepositoryAbstraction","ModelCache","ModelsFetcher","StorageOperations","CmsContext","ModelFieldCompression"],"mappings":";;;;;;;;;;AA2BA,MAAMA;IACF,YACqBC,UAAgC,EAChCC,aAAsC,EACtCC,iBAA8C,EAC9CC,UAAgC,EAChCC,qBAAsD,CACzE;aALmBJ,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,iBAAiB,GAAjBA;aACAC,UAAU,GAAVA;aACAC,qBAAqB,GAArBA;IAClB;IAEH,MAAM,QACFC,KAAe,EACfC,QAAkB,EACgC;QAClD,IAAI;YAEA,IAAI;gBACAC,sBAAsB;oBAAEF;gBAAM;YAClC,EAAE,OAAOG,OAAO;gBACZ,OAAOC,OAAO,IAAI,CACd,IAAIC,qBAAqB;oBAAE,SAASF,MAAM,OAAO;oBAAE,MAAMA,MAAM,IAAI;gBAAC;YAE5E;YAGA,MAAMG,eAAe,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,oBAAoB,CAAC,UAC9D,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ;YAG5C,IAAIA,aAAa,MAAM,IACnB,OAAOF,OAAO,IAAI,CAAC,IAAIG,sBAAsBD,aAAa,KAAK;YAGnE,MAAME,YAAYF,aAAa,KAAK;YACpC,MAAMG,SAASD,UAAU,MAAM,CAACE,CAAAA,IAAKA,EAAE,OAAO,KAAKV,MAAM,OAAO;YAGhE,MAAMW,sBAAsB,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAACX,MAAM,OAAO;YAC5E,IAAIW,oBAAoB,MAAM,IAC1B,OAAOP,OAAO,IAAI,CAAC,IAAIG,sBAAsBI,oBAAoB,KAAK;YAG1E,IAAIA,oBAAoB,KAAK,CAAC,QAAQ,EAClC,OAAOP,OAAO,IAAI,CAAC,IAAIQ,gCAAgCZ,MAAM,OAAO;YAIxE,IAAI;gBACA,KAAK,MAAMa,iBAAiBJ,OAAQ;oBAChCK,wBAAwB;wBACpBD;wBACAb;oBACJ;oBACAe,sBAAsB;wBAClBF;wBACAb;oBACJ;gBACJ;gBAGA,MAAMgB,oBAAoB;oBACtBP;oBACAT;oBACAC;oBACA,SAAS,IAAI,CAAC,UAAU;gBAC5B;YACJ,EAAE,OAAOE,OAAO;gBACZ,OAAOC,OAAO,IAAI,CACd,IAAIC,qBAAqB;oBAAE,SAASF,MAAM,OAAO;oBAAE,MAAMA,MAAM,IAAI;gBAAC;YAE5E;YAEA,MAAMc,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAACjB,MAAM,MAAM;YAGrE,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC;gBACvC,OAAO;oBACH,GAAGA,KAAK;oBACRiB;gBACJ;YACJ;YAGA,IAAI,CAAC,UAAU,CAAC,KAAK;YAErB,OAAOb,OAAO,EAAE;QACpB,EAAE,OAAOD,OAAO;YACZ,OAAOC,OAAO,IAAI,CAAC,IAAIG,sBAAsBJ;QACjD;IACJ;AACJ;AAEO,MAAMe,8CAAwBC,sBAAAA,oBAA0C,CAAC;IAC5E,gBAAgBzB;IAChB,cAAc;QAAC0B;QAAYC;QAAeC;QAAmBC;QAAYC;KAAsB;AACnG"}
1
+ {"version":3,"file":"features/contentModel/UpdateModel/UpdateModelRepository.js","sources":["../../../../src/features/contentModel/UpdateModel/UpdateModelRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { UpdateModelRepository as RepositoryAbstraction } from \"./abstractions.js\";\nimport { ModelCache, ModelsFetcher } from \"~/features/contentModel/shared/abstractions.js\";\nimport {\n ModelCannotUpdateCodeModelError,\n ModelPersistenceError,\n ModelValidationError\n} from \"~/domain/contentModel/errors.js\";\nimport { CmsContext, StorageOperations } from \"~/features/shared/abstractions.js\";\nimport { validateEndingAllowed } from \"~/crud/contentModel/validate/endingAllowed.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 type { CmsModel } from \"~/types/index.js\";\nimport { ModelFieldCompression } from \"~/features/contentModel/ModelFieldCompression/index.js\";\nimport { RuntimeTenant } from \"~/features/runtimeTenant/abstractions.js\";\n\n/**\n * UpdateModelRepository - Validates domain rules and persists model updates.\n *\n * Responsibilities:\n * - Validate API name endings\n * - Validate singularApiName uniqueness (excluding current model)\n * - Validate pluralApiName uniqueness (excluding current model)\n * - Validate model fields\n * - Persist to storage\n * - Clear ModelCache after successful update\n */\nclass UpdateModelRepositoryImpl implements RepositoryAbstraction.Interface {\n public constructor(\n private readonly modelCache: ModelCache.Interface,\n private readonly modelsFetcher: ModelsFetcher.Interface,\n private readonly storageOperations: StorageOperations.Interface,\n private readonly cmsContext: CmsContext.Interface,\n private readonly modelFieldCompression: ModelFieldCompression.Interface,\n private readonly runtimeTenant: RuntimeTenant.Interface\n ) {}\n\n async execute(\n initialModel: CmsModel,\n original: CmsModel\n ): Promise<Result<CmsModel, RepositoryAbstraction.Error>> {\n const model = this.runtimeTenant.assign(initialModel);\n try {\n // Validate API name endings\n try {\n validateEndingAllowed({ model });\n } catch (error) {\n return Result.fail(\n new ModelValidationError({ message: error.message, data: error.data })\n );\n }\n\n // Get all models for validation (excluding the current model)\n const modelsResult = await this.cmsContext.security.withoutAuthorization(async () => {\n return await this.modelsFetcher.fetchAll();\n });\n\n if (modelsResult.isFail()) {\n return Result.fail(new ModelPersistenceError(modelsResult.error));\n }\n\n const allModels = modelsResult.value;\n const models = allModels.filter(m => m.modelId !== model.modelId);\n\n // Check if this is a plugin model\n const existingModelResult = await this.modelsFetcher.fetchById(model.modelId);\n if (existingModelResult.isFail()) {\n return Result.fail(new ModelPersistenceError(existingModelResult.error));\n }\n\n if (existingModelResult.value.isPlugin) {\n return Result.fail(new ModelCannotUpdateCodeModelError(model.modelId));\n }\n\n // Validate uniqueness\n try {\n for (const existingModel of models) {\n validateSingularApiName({\n existingModel,\n model\n });\n validatePluralApiName({\n existingModel,\n model\n });\n }\n\n // Validate model fields\n await validateModelFields({\n models,\n model,\n original,\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 const fields = await this.modelFieldCompression.compress(model.fields);\n\n // Persist to storage\n await this.storageOperations.models.update({\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 return Result.fail(new ModelPersistenceError(error as Error));\n }\n }\n}\n\nexport const UpdateModelRepository = RepositoryAbstraction.createImplementation({\n implementation: UpdateModelRepositoryImpl,\n dependencies: [\n ModelCache,\n ModelsFetcher,\n StorageOperations,\n CmsContext,\n ModelFieldCompression,\n RuntimeTenant\n ]\n});\n"],"names":["UpdateModelRepositoryImpl","modelCache","modelsFetcher","storageOperations","cmsContext","modelFieldCompression","runtimeTenant","initialModel","original","model","validateEndingAllowed","error","Result","ModelValidationError","modelsResult","ModelPersistenceError","allModels","models","m","existingModelResult","ModelCannotUpdateCodeModelError","existingModel","validateSingularApiName","validatePluralApiName","validateModelFields","fields","UpdateModelRepository","RepositoryAbstraction","ModelCache","ModelsFetcher","StorageOperations","CmsContext","ModelFieldCompression","RuntimeTenant"],"mappings":";;;;;;;;;;;AA4BA,MAAMA;IACF,YACqBC,UAAgC,EAChCC,aAAsC,EACtCC,iBAA8C,EAC9CC,UAAgC,EAChCC,qBAAsD,EACtDC,aAAsC,CACzD;aANmBL,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,iBAAiB,GAAjBA;aACAC,UAAU,GAAVA;aACAC,qBAAqB,GAArBA;aACAC,aAAa,GAAbA;IAClB;IAEH,MAAM,QACFC,YAAsB,EACtBC,QAAkB,EACoC;QACtD,MAAMC,QAAQ,IAAI,CAAC,aAAa,CAAC,MAAM,CAACF;QACxC,IAAI;YAEA,IAAI;gBACAG,sBAAsB;oBAAED;gBAAM;YAClC,EAAE,OAAOE,OAAO;gBACZ,OAAOC,OAAO,IAAI,CACd,IAAIC,qBAAqB;oBAAE,SAASF,MAAM,OAAO;oBAAE,MAAMA,MAAM,IAAI;gBAAC;YAE5E;YAGA,MAAMG,eAAe,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,oBAAoB,CAAC,UAC9D,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ;YAG5C,IAAIA,aAAa,MAAM,IACnB,OAAOF,OAAO,IAAI,CAAC,IAAIG,sBAAsBD,aAAa,KAAK;YAGnE,MAAME,YAAYF,aAAa,KAAK;YACpC,MAAMG,SAASD,UAAU,MAAM,CAACE,CAAAA,IAAKA,EAAE,OAAO,KAAKT,MAAM,OAAO;YAGhE,MAAMU,sBAAsB,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAACV,MAAM,OAAO;YAC5E,IAAIU,oBAAoB,MAAM,IAC1B,OAAOP,OAAO,IAAI,CAAC,IAAIG,sBAAsBI,oBAAoB,KAAK;YAG1E,IAAIA,oBAAoB,KAAK,CAAC,QAAQ,EAClC,OAAOP,OAAO,IAAI,CAAC,IAAIQ,gCAAgCX,MAAM,OAAO;YAIxE,IAAI;gBACA,KAAK,MAAMY,iBAAiBJ,OAAQ;oBAChCK,wBAAwB;wBACpBD;wBACAZ;oBACJ;oBACAc,sBAAsB;wBAClBF;wBACAZ;oBACJ;gBACJ;gBAGA,MAAMe,oBAAoB;oBACtBP;oBACAR;oBACAD;oBACA,SAAS,IAAI,CAAC,UAAU;gBAC5B;YACJ,EAAE,OAAOG,OAAO;gBACZ,OAAOC,OAAO,IAAI,CACd,IAAIC,qBAAqB;oBAAE,SAASF,MAAM,OAAO;oBAAE,MAAMA,MAAM,IAAI;gBAAC;YAE5E;YAEA,MAAMc,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAChB,MAAM,MAAM;YAGrE,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC;gBACvC,OAAO;oBACH,GAAGA,KAAK;oBACRgB;gBACJ;YACJ;YAGA,IAAI,CAAC,UAAU,CAAC,KAAK;YAErB,OAAOb,OAAO,EAAE,CAACH;QACrB,EAAE,OAAOE,OAAO;YACZ,OAAOC,OAAO,IAAI,CAAC,IAAIG,sBAAsBJ;QACjD;IACJ;AACJ;AAEO,MAAMe,8CAAwBC,sBAAAA,oBAA0C,CAAC;IAC5E,gBAAgB3B;IAChB,cAAc;QACV4B;QACAC;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
@@ -69,10 +69,10 @@ class UpdateModelUseCaseImpl {
69
69
  return Result.fail(result.error);
70
70
  }
71
71
  await this.eventPublisher.publish(new ModelAfterUpdateEvent({
72
- model,
72
+ model: result.value,
73
73
  original
74
74
  }));
75
- return Result.ok(model);
75
+ return Result.ok(result.value);
76
76
  }
77
77
  }
78
78
  const UpdateModelUseCase_UpdateModelUseCase = UpdateModelUseCase.createImplementation({
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/UpdateModel/UpdateModelUseCase.js","sources":["../../../../src/features/contentModel/UpdateModel/UpdateModelUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { UpdateModelUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport { UpdateModelRepository } from \"./abstractions.js\";\nimport { EventPublisher } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport { ModelBeforeUpdateEvent } from \"./events.js\";\nimport { ModelAfterUpdateEvent } from \"./events.js\";\nimport { ModelUpdateErrorEvent } from \"./events.js\";\nimport { AccessControl } from \"~/features/shared/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { ModelNotAuthorizedError, ModelValidationError } from \"~/domain/contentModel/errors.js\";\nimport { createZodError } from \"@webiny/utils\";\nimport { removeUndefinedValues } from \"@webiny/utils\";\nimport { createModelUpdateValidation } from \"~/domain/contentModel/schemas.js\";\nimport { ensureTypeTag } from \"~/domain/contentModel/ensureTypeTag.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport type { CmsModelUpdateInput } from \"~/types/index.js\";\nimport { GetModelUseCase } from \"~/features/contentModel/GetModel/index.js\";\n\n/**\n * UpdateModelUseCase - Core model update orchestration.\n *\n * Responsibilities:\n * - Validate input (Zod)\n * - Fetch original model\n * - Create updated domain model object\n * - Handle group changes\n * - Handle field ID changes (title, description, image)\n * - Access control checks\n * - Publish before event\n * - Delegate to repository for validation and persistence\n * - Publish after event or error event\n *\n * Note: Repository handles domain validations (API name uniqueness, field validation, etc.)\n */\nclass UpdateModelUseCaseImpl implements UseCaseAbstraction.Interface {\n public constructor(\n private getModelUseCase: GetModelUseCase.Interface,\n private eventPublisher: EventPublisher.Interface,\n private repository: UpdateModelRepository.Interface,\n private accessControl: AccessControl.Interface,\n private tenantContext: TenantContext.Interface\n ) {}\n\n async execute(\n modelId: string,\n input: CmsModelUpdateInput\n ): 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 // Get the original model (with access control check)\n const getResult = await this.getModelUseCase.execute(modelId);\n if (getResult.isFail()) {\n return getResult;\n }\n\n const original = structuredClone(getResult.value);\n\n // Validate input\n const validationResult = await createModelUpdateValidation().safeParseAsync(input);\n if (!validationResult.success) {\n const zodError = createZodError(validationResult.error);\n return Result.fail(\n new ModelValidationError({\n message: zodError.message,\n data: zodError.data\n })\n );\n }\n\n const data = removeUndefinedValues(validationResult.data);\n\n // If no changes, return original\n if (Object.keys(data).length === 0) {\n return Result.ok(original);\n }\n\n // Create updated model\n const tenant = this.tenantContext.getTenant();\n\n const model: CmsModel = {\n ...original,\n ...data,\n icon: data.icon ?? original.icon,\n // Handle optional field IDs explicitly\n titleFieldId:\n data.titleFieldId === undefined\n ? original.titleFieldId\n : (data.titleFieldId as string),\n descriptionFieldId:\n data.descriptionFieldId === undefined\n ? original.descriptionFieldId\n : data.descriptionFieldId,\n imageFieldId:\n data.imageFieldId === undefined ? original.imageFieldId : data.imageFieldId,\n description: data.description || original.description,\n tenant: original.tenant || tenant.id,\n savedOn: new Date().toISOString()\n };\n\n // Access control check on the updated model\n const canAccessModel = await this.accessControl.canAccessModel({ model, rwd: \"w\" });\n if (!canAccessModel) {\n return Result.fail(ModelNotAuthorizedError.fromModel(model));\n }\n\n // Ensure type tags\n model.tags = ensureTypeTag(model);\n\n // Publish before event\n await this.eventPublisher.publish(\n new ModelBeforeUpdateEvent({ model, original, input: data })\n );\n\n // Persist via repository (repository will validate)\n const result = await this.repository.execute(model, original);\n if (result.isFail()) {\n // Publish error event\n await this.eventPublisher.publish(\n new ModelUpdateErrorEvent({\n input: data,\n model,\n original,\n error: result.error\n })\n );\n return Result.fail(result.error);\n }\n\n // Publish after event\n await this.eventPublisher.publish(new ModelAfterUpdateEvent({ model, original }));\n\n return Result.ok(model);\n }\n}\n\nexport const UpdateModelUseCase = UseCaseAbstraction.createImplementation({\n implementation: UpdateModelUseCaseImpl,\n dependencies: [\n GetModelUseCase,\n EventPublisher,\n UpdateModelRepository,\n AccessControl,\n TenantContext\n ]\n});\n"],"names":["UpdateModelUseCaseImpl","getModelUseCase","eventPublisher","repository","accessControl","tenantContext","modelId","input","canAccess","Result","ModelNotAuthorizedError","getResult","original","structuredClone","validationResult","createModelUpdateValidation","zodError","createZodError","ModelValidationError","data","removeUndefinedValues","Object","tenant","model","undefined","Date","canAccessModel","ensureTypeTag","ModelBeforeUpdateEvent","result","ModelUpdateErrorEvent","ModelAfterUpdateEvent","UpdateModelUseCase","UseCaseAbstraction","GetModelUseCase","EventPublisher","UpdateModelRepository","AccessControl","TenantContext"],"mappings":";;;;;;;;;;;AAkCA,MAAMA;IACF,YACYC,eAA0C,EAC1CC,cAAwC,EACxCC,UAA2C,EAC3CC,aAAsC,EACtCC,aAAsC,CAChD;aALUJ,eAAe,GAAfA;aACAC,cAAc,GAAdA;aACAC,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,aAAa,GAAbA;IACT;IAEH,MAAM,QACFC,OAAe,EACfC,KAA0B,EACyB;QAEnD,MAAMC,YAAY,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAE,KAAK;QAAI;QACrE,IAAI,CAACA,WACD,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAI3B,MAAMC,YAAY,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAACL;QACrD,IAAIK,UAAU,MAAM,IAChB,OAAOA;QAGX,MAAMC,WAAWC,gBAAgBF,UAAU,KAAK;QAGhD,MAAMG,mBAAmB,MAAMC,8BAA8B,cAAc,CAACR;QAC5E,IAAI,CAACO,iBAAiB,OAAO,EAAE;YAC3B,MAAME,WAAWC,eAAeH,iBAAiB,KAAK;YACtD,OAAOL,OAAO,IAAI,CACd,IAAIS,qBAAqB;gBACrB,SAASF,SAAS,OAAO;gBACzB,MAAMA,SAAS,IAAI;YACvB;QAER;QAEA,MAAMG,OAAOC,sBAAsBN,iBAAiB,IAAI;QAGxD,IAAIO,AAA6B,MAA7BA,OAAO,IAAI,CAACF,MAAM,MAAM,EACxB,OAAOV,OAAO,EAAE,CAACG;QAIrB,MAAMU,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAE3C,MAAMC,QAAkB;YACpB,GAAGX,QAAQ;YACX,GAAGO,IAAI;YACP,MAAMA,KAAK,IAAI,IAAIP,SAAS,IAAI;YAEhC,cACIO,AAAsBK,WAAtBL,KAAK,YAAY,GACXP,SAAS,YAAY,GACpBO,KAAK,YAAY;YAC5B,oBACIA,AAA4BK,WAA5BL,KAAK,kBAAkB,GACjBP,SAAS,kBAAkB,GAC3BO,KAAK,kBAAkB;YACjC,cACIA,AAAsBK,WAAtBL,KAAK,YAAY,GAAiBP,SAAS,YAAY,GAAGO,KAAK,YAAY;YAC/E,aAAaA,KAAK,WAAW,IAAIP,SAAS,WAAW;YACrD,QAAQA,SAAS,MAAM,IAAIU,OAAO,EAAE;YACpC,SAAS,IAAIG,OAAO,WAAW;QACnC;QAGA,MAAMC,iBAAiB,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAEH;YAAO,KAAK;QAAI;QACjF,IAAI,CAACG,gBACD,OAAOjB,OAAO,IAAI,CAACC,wBAAwB,SAAS,CAACa;QAIzDA,MAAM,IAAI,GAAGI,cAAcJ;QAG3B,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIK,uBAAuB;YAAEL;YAAOX;YAAU,OAAOO;QAAK;QAI9D,MAAMU,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACN,OAAOX;QACpD,IAAIiB,OAAO,MAAM,IAAI;YAEjB,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIC,sBAAsB;gBACtB,OAAOX;gBACPI;gBACAX;gBACA,OAAOiB,OAAO,KAAK;YACvB;YAEJ,OAAOpB,OAAO,IAAI,CAACoB,OAAO,KAAK;QACnC;QAGA,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAIE,sBAAsB;YAAER;YAAOX;QAAS;QAE9E,OAAOH,OAAO,EAAE,CAACc;IACrB;AACJ;AAEO,MAAMS,wCAAqBC,mBAAAA,oBAAuC,CAAC;IACtE,gBAAgBjC;IAChB,cAAc;QACVkC;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
1
+ {"version":3,"file":"features/contentModel/UpdateModel/UpdateModelUseCase.js","sources":["../../../../src/features/contentModel/UpdateModel/UpdateModelUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { UpdateModelUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport { UpdateModelRepository } from \"./abstractions.js\";\nimport { EventPublisher } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport { ModelBeforeUpdateEvent } from \"./events.js\";\nimport { ModelAfterUpdateEvent } from \"./events.js\";\nimport { ModelUpdateErrorEvent } from \"./events.js\";\nimport { AccessControl } from \"~/features/shared/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { ModelNotAuthorizedError, ModelValidationError } from \"~/domain/contentModel/errors.js\";\nimport { createZodError } from \"@webiny/utils\";\nimport { removeUndefinedValues } from \"@webiny/utils\";\nimport { createModelUpdateValidation } from \"~/domain/contentModel/schemas.js\";\nimport { ensureTypeTag } from \"~/domain/contentModel/ensureTypeTag.js\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport type { CmsModelUpdateInput } from \"~/types/index.js\";\nimport { GetModelUseCase } from \"~/features/contentModel/GetModel/index.js\";\n\n/**\n * UpdateModelUseCase - Core model update orchestration.\n *\n * Responsibilities:\n * - Validate input (Zod)\n * - Fetch original model\n * - Create updated domain model object\n * - Handle group changes\n * - Handle field ID changes (title, description, image)\n * - Access control checks\n * - Publish before event\n * - Delegate to repository for validation and persistence\n * - Publish after event or error event\n *\n * Note: Repository handles domain validations (API name uniqueness, field validation, etc.)\n */\nclass UpdateModelUseCaseImpl implements UseCaseAbstraction.Interface {\n public constructor(\n private getModelUseCase: GetModelUseCase.Interface,\n private eventPublisher: EventPublisher.Interface,\n private repository: UpdateModelRepository.Interface,\n private accessControl: AccessControl.Interface,\n private tenantContext: TenantContext.Interface\n ) {}\n\n async execute(\n modelId: string,\n input: CmsModelUpdateInput\n ): 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 // Get the original model (with access control check)\n const getResult = await this.getModelUseCase.execute(modelId);\n if (getResult.isFail()) {\n return getResult;\n }\n\n const original = structuredClone(getResult.value);\n\n // Validate input\n const validationResult = await createModelUpdateValidation().safeParseAsync(input);\n if (!validationResult.success) {\n const zodError = createZodError(validationResult.error);\n return Result.fail(\n new ModelValidationError({\n message: zodError.message,\n data: zodError.data\n })\n );\n }\n\n const data = removeUndefinedValues(validationResult.data);\n\n // If no changes, return original\n if (Object.keys(data).length === 0) {\n return Result.ok(original);\n }\n\n // Create updated model\n const tenant = this.tenantContext.getTenant();\n\n const model: CmsModel = {\n ...original,\n ...data,\n icon: data.icon ?? original.icon,\n // Handle optional field IDs explicitly\n titleFieldId:\n data.titleFieldId === undefined\n ? original.titleFieldId\n : (data.titleFieldId as string),\n descriptionFieldId:\n data.descriptionFieldId === undefined\n ? original.descriptionFieldId\n : data.descriptionFieldId,\n imageFieldId:\n data.imageFieldId === undefined ? original.imageFieldId : data.imageFieldId,\n description: data.description || original.description,\n tenant: original.tenant || tenant.id,\n savedOn: new Date().toISOString()\n };\n\n // Access control check on the updated model\n const canAccessModel = await this.accessControl.canAccessModel({ model, rwd: \"w\" });\n if (!canAccessModel) {\n return Result.fail(ModelNotAuthorizedError.fromModel(model));\n }\n\n // Ensure type tags\n model.tags = ensureTypeTag(model);\n\n // Publish before event\n await this.eventPublisher.publish(\n new ModelBeforeUpdateEvent({ model, original, input: data })\n );\n\n // Persist via repository (repository will validate)\n const result = await this.repository.execute(model, original);\n if (result.isFail()) {\n // Publish error event\n await this.eventPublisher.publish(\n new ModelUpdateErrorEvent({\n input: data,\n model,\n original,\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 ModelAfterUpdateEvent({\n model: result.value,\n original\n })\n );\n\n return Result.ok(result.value);\n }\n}\n\nexport const UpdateModelUseCase = UseCaseAbstraction.createImplementation({\n implementation: UpdateModelUseCaseImpl,\n dependencies: [\n GetModelUseCase,\n EventPublisher,\n UpdateModelRepository,\n AccessControl,\n TenantContext\n ]\n});\n"],"names":["UpdateModelUseCaseImpl","getModelUseCase","eventPublisher","repository","accessControl","tenantContext","modelId","input","canAccess","Result","ModelNotAuthorizedError","getResult","original","structuredClone","validationResult","createModelUpdateValidation","zodError","createZodError","ModelValidationError","data","removeUndefinedValues","Object","tenant","model","undefined","Date","canAccessModel","ensureTypeTag","ModelBeforeUpdateEvent","result","ModelUpdateErrorEvent","ModelAfterUpdateEvent","UpdateModelUseCase","UseCaseAbstraction","GetModelUseCase","EventPublisher","UpdateModelRepository","AccessControl","TenantContext"],"mappings":";;;;;;;;;;;AAkCA,MAAMA;IACF,YACYC,eAA0C,EAC1CC,cAAwC,EACxCC,UAA2C,EAC3CC,aAAsC,EACtCC,aAAsC,CAChD;aALUJ,eAAe,GAAfA;aACAC,cAAc,GAAdA;aACAC,UAAU,GAAVA;aACAC,aAAa,GAAbA;aACAC,aAAa,GAAbA;IACT;IAEH,MAAM,QACFC,OAAe,EACfC,KAA0B,EACyB;QAEnD,MAAMC,YAAY,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAE,KAAK;QAAI;QACrE,IAAI,CAACA,WACD,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAI3B,MAAMC,YAAY,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAACL;QACrD,IAAIK,UAAU,MAAM,IAChB,OAAOA;QAGX,MAAMC,WAAWC,gBAAgBF,UAAU,KAAK;QAGhD,MAAMG,mBAAmB,MAAMC,8BAA8B,cAAc,CAACR;QAC5E,IAAI,CAACO,iBAAiB,OAAO,EAAE;YAC3B,MAAME,WAAWC,eAAeH,iBAAiB,KAAK;YACtD,OAAOL,OAAO,IAAI,CACd,IAAIS,qBAAqB;gBACrB,SAASF,SAAS,OAAO;gBACzB,MAAMA,SAAS,IAAI;YACvB;QAER;QAEA,MAAMG,OAAOC,sBAAsBN,iBAAiB,IAAI;QAGxD,IAAIO,AAA6B,MAA7BA,OAAO,IAAI,CAACF,MAAM,MAAM,EACxB,OAAOV,OAAO,EAAE,CAACG;QAIrB,MAAMU,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAE3C,MAAMC,QAAkB;YACpB,GAAGX,QAAQ;YACX,GAAGO,IAAI;YACP,MAAMA,KAAK,IAAI,IAAIP,SAAS,IAAI;YAEhC,cACIO,AAAsBK,WAAtBL,KAAK,YAAY,GACXP,SAAS,YAAY,GACpBO,KAAK,YAAY;YAC5B,oBACIA,AAA4BK,WAA5BL,KAAK,kBAAkB,GACjBP,SAAS,kBAAkB,GAC3BO,KAAK,kBAAkB;YACjC,cACIA,AAAsBK,WAAtBL,KAAK,YAAY,GAAiBP,SAAS,YAAY,GAAGO,KAAK,YAAY;YAC/E,aAAaA,KAAK,WAAW,IAAIP,SAAS,WAAW;YACrD,QAAQA,SAAS,MAAM,IAAIU,OAAO,EAAE;YACpC,SAAS,IAAIG,OAAO,WAAW;QACnC;QAGA,MAAMC,iBAAiB,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAEH;YAAO,KAAK;QAAI;QACjF,IAAI,CAACG,gBACD,OAAOjB,OAAO,IAAI,CAACC,wBAAwB,SAAS,CAACa;QAIzDA,MAAM,IAAI,GAAGI,cAAcJ;QAG3B,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIK,uBAAuB;YAAEL;YAAOX;YAAU,OAAOO;QAAK;QAI9D,MAAMU,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACN,OAAOX;QACpD,IAAIiB,OAAO,MAAM,IAAI;YAEjB,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIC,sBAAsB;gBACtB,OAAOX;gBACPI;gBACAX;gBACA,OAAOiB,OAAO,KAAK;YACvB;YAEJ,OAAOpB,OAAO,IAAI,CAACoB,OAAO,KAAK;QACnC;QAGA,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B,IAAIE,sBAAsB;YACtB,OAAOF,OAAO,KAAK;YACnBjB;QACJ;QAGJ,OAAOH,OAAO,EAAE,CAACoB,OAAO,KAAK;IACjC;AACJ;AAEO,MAAMG,wCAAqBC,mBAAAA,oBAAuC,CAAC;IACtE,gBAAgBjC;IAChB,cAAc;QACVkC;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
@@ -32,7 +32,7 @@ export declare namespace UpdateModelUseCase {
32
32
  * UpdateModelRepository - Validates domain rules and persists model updates.
33
33
  */
34
34
  export interface IUpdateModelRepository {
35
- execute(model: CmsModel, original: CmsModel): Promise<Result<void, RepositoryError>>;
35
+ execute(model: CmsModel, original: CmsModel): Promise<Result<CmsModel, RepositoryError>>;
36
36
  }
37
37
  export interface IUpdateModelRepositoryErrors {
38
38
  alreadyExists: ModelSlugTakenError;
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/UpdateModel/abstractions.js","sources":["../../../../src/features/contentModel/UpdateModel/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport type { CmsModelUpdateInput } from \"~/types/index.js\";\nimport {\n type ModelSlugTakenError,\n ModelNotAuthorizedError,\n type ModelNotFoundError,\n type ModelValidationError,\n type ModelPersistenceError,\n ModelCannotUpdateCodeModelError\n} from \"~/domain/contentModel/errors.js\";\nimport {\n type GroupNotFoundError,\n type GroupNotAuthorizedError\n} from \"~/domain/contentModelGroup/errors.js\";\n\n/**\n * UpdateModel Use Case\n */\nexport interface IUpdateModelUseCase {\n execute(modelId: string, input: CmsModelUpdateInput): Promise<Result<CmsModel, UseCaseError>>;\n}\n\nexport interface IUpdateModelUseCaseErrors {\n notFound: ModelNotFoundError;\n notAuthorized: ModelNotAuthorizedError;\n validation: ModelValidationError;\n alreadyExists: ModelSlugTakenError;\n persistence: ModelPersistenceError;\n updateCodeModel: ModelCannotUpdateCodeModelError;\n groupNotFound: GroupNotFoundError;\n groupNotAccessible: GroupNotAuthorizedError;\n}\n\ntype UseCaseError = IUpdateModelUseCaseErrors[keyof IUpdateModelUseCaseErrors];\n\n/** Update a content model. */\nexport const UpdateModelUseCase = createAbstraction<IUpdateModelUseCase>(\"UpdateModelUseCase\");\n\nexport namespace UpdateModelUseCase {\n export type Interface = IUpdateModelUseCase;\n export type Input = CmsModelUpdateInput;\n\n export type Error = UseCaseError;\n export type Return = Promise<Result<CmsModel, UseCaseError>>;\n}\n\n/**\n * UpdateModelRepository - Validates domain rules and persists model updates.\n */\nexport interface IUpdateModelRepository {\n execute(model: CmsModel, original: CmsModel): Promise<Result<void, RepositoryError>>;\n}\n\nexport interface IUpdateModelRepositoryErrors {\n alreadyExists: ModelSlugTakenError;\n validation: ModelValidationError;\n persistence: ModelPersistenceError;\n updateCodeModel: ModelCannotUpdateCodeModelError;\n}\n\ntype RepositoryError = IUpdateModelRepositoryErrors[keyof IUpdateModelRepositoryErrors];\n\nexport const UpdateModelRepository =\n createAbstraction<IUpdateModelRepository>(\"UpdateModelRepository\");\n\nexport namespace UpdateModelRepository {\n export type Interface = IUpdateModelRepository;\n export type Error = RepositoryError;\n}\n"],"names":["UpdateModelUseCase","createAbstraction","UpdateModelRepository"],"mappings":";AAsCO,MAAMA,qBAAqBC,kBAAuC;AA0BlE,MAAMC,wBACTD,kBAA0C"}
1
+ {"version":3,"file":"features/contentModel/UpdateModel/abstractions.js","sources":["../../../../src/features/contentModel/UpdateModel/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { CmsModel } from \"~/types/index.js\";\nimport type { CmsModelUpdateInput } from \"~/types/index.js\";\nimport {\n type ModelSlugTakenError,\n ModelNotAuthorizedError,\n type ModelNotFoundError,\n type ModelValidationError,\n type ModelPersistenceError,\n ModelCannotUpdateCodeModelError\n} from \"~/domain/contentModel/errors.js\";\nimport {\n type GroupNotFoundError,\n type GroupNotAuthorizedError\n} from \"~/domain/contentModelGroup/errors.js\";\n\n/**\n * UpdateModel Use Case\n */\nexport interface IUpdateModelUseCase {\n execute(modelId: string, input: CmsModelUpdateInput): Promise<Result<CmsModel, UseCaseError>>;\n}\n\nexport interface IUpdateModelUseCaseErrors {\n notFound: ModelNotFoundError;\n notAuthorized: ModelNotAuthorizedError;\n validation: ModelValidationError;\n alreadyExists: ModelSlugTakenError;\n persistence: ModelPersistenceError;\n updateCodeModel: ModelCannotUpdateCodeModelError;\n groupNotFound: GroupNotFoundError;\n groupNotAccessible: GroupNotAuthorizedError;\n}\n\ntype UseCaseError = IUpdateModelUseCaseErrors[keyof IUpdateModelUseCaseErrors];\n\n/** Update a content model. */\nexport const UpdateModelUseCase = createAbstraction<IUpdateModelUseCase>(\"UpdateModelUseCase\");\n\nexport namespace UpdateModelUseCase {\n export type Interface = IUpdateModelUseCase;\n export type Input = CmsModelUpdateInput;\n\n export type Error = UseCaseError;\n export type Return = Promise<Result<CmsModel, UseCaseError>>;\n}\n\n/**\n * UpdateModelRepository - Validates domain rules and persists model updates.\n */\nexport interface IUpdateModelRepository {\n execute(model: CmsModel, original: CmsModel): Promise<Result<CmsModel, RepositoryError>>;\n}\n\nexport interface IUpdateModelRepositoryErrors {\n alreadyExists: ModelSlugTakenError;\n validation: ModelValidationError;\n persistence: ModelPersistenceError;\n updateCodeModel: ModelCannotUpdateCodeModelError;\n}\n\ntype RepositoryError = IUpdateModelRepositoryErrors[keyof IUpdateModelRepositoryErrors];\n\nexport const UpdateModelRepository =\n createAbstraction<IUpdateModelRepository>(\"UpdateModelRepository\");\n\nexport namespace UpdateModelRepository {\n export type Interface = IUpdateModelRepository;\n export type Error = RepositoryError;\n}\n"],"names":["UpdateModelUseCase","createAbstraction","UpdateModelRepository"],"mappings":";AAsCO,MAAMA,qBAAqBC,kBAAuC;AA0BlE,MAAMC,wBACTD,kBAA0C"}
@@ -31,7 +31,8 @@ class ValuesSelectionGeneratorImpl {
31
31
  const nestedPrefix = `${typePrefix}_${createTypeName(field.fieldId)}`;
32
32
  const childSelection = children.map((child)=>this.walkNode(child, nestedPrefix)).filter(Boolean).join("\n");
33
33
  if (!childSelection) return null;
34
- return `${field.fieldId} { ${childSelection} }`;
34
+ const idSelection = "object" === field.type ? "_id " : "";
35
+ return `${field.fieldId} { ${idSelection}${childSelection} }`;
35
36
  }
36
37
  walkCollectionNode(node, typePrefix) {
37
38
  const { collection, children } = node;
@@ -39,7 +40,7 @@ class ValuesSelectionGeneratorImpl {
39
40
  if (!gqlTypeName) return null;
40
41
  const templateType = `${typePrefix}_${gqlTypeName}`;
41
42
  const childSelection = children.map((child)=>this.walkNode(child, templateType)).filter(Boolean).join("\n");
42
- return `...on ${templateType} { ${childSelection} _templateId __typename }`;
43
+ return `...on ${templateType} { ${childSelection} _templateId _id __typename }`;
43
44
  }
44
45
  }
45
46
  const ValuesSelectionGenerator_ValuesSelectionGenerator = ValuesSelectionGenerator.createImplementation({
@@ -1 +1 @@
1
- {"version":3,"file":"features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js","sources":["../../../../src/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.ts"],"sourcesContent":["import {\n ValuesSelectionGenerator as Abstraction,\n type IValuesSelectionGenerator\n} from \"./abstractions.js\";\nimport { ModelToAstConverter } from \"../ModelToAstConverter/abstractions.js\";\nimport type {\n CmsModel,\n CmsModelAst,\n CmsModelFieldAstNode,\n CmsModelFieldAstNodeCollection,\n CmsModelFieldAstNodeField\n} from \"~/types/index.js\";\nimport { createTypeName } from \"~/utils/createTypeName.js\";\n\nconst REF_SELECTION = \"{ id modelId }\";\n\nconst ASSET_SELECTION = [\n \"{ id src url name type size\",\n \"image { width height crop { top left bottom right } focalPoint { x y } alt caption }\",\n \"document { pages }\",\n \"video { autoplay poster } }\"\n].join(\" \");\n\nclass ValuesSelectionGeneratorImpl implements IValuesSelectionGenerator {\n constructor(private readonly modelToAst: ModelToAstConverter.Interface) {}\n\n generate(model: CmsModel): string {\n const ast = this.modelToAst.toAst(model);\n const selection = this.walkRoot(ast, model.singularApiName);\n return selection || \"_empty\";\n }\n\n private walkRoot(ast: CmsModelAst, typePrefix: string): string {\n return ast.children\n .map(node => this.walkNode(node, typePrefix))\n .filter(Boolean)\n .join(\"\\n\");\n }\n\n private walkNode(node: CmsModelFieldAstNode, typePrefix: string): string | null {\n if (node.type === \"field\") {\n return this.walkFieldNode(node, typePrefix);\n }\n if (node.type === \"collection\") {\n return this.walkCollectionNode(node, typePrefix);\n }\n return null;\n }\n\n private walkFieldNode(node: CmsModelFieldAstNodeField, typePrefix: string): string | null {\n const { field, children } = node;\n\n if (field.type === \"ref\") {\n return `${field.fieldId} ${REF_SELECTION}`;\n }\n\n if (field.type === \"asset\") {\n return `${field.fieldId} ${ASSET_SELECTION}`;\n }\n\n if (children.length === 0) {\n if (field.type === \"object\" || field.type === \"dynamicZone\") {\n return null;\n }\n return field.fieldId;\n }\n\n const nestedPrefix = `${typePrefix}_${createTypeName(field.fieldId)}`;\n const childSelection = children\n .map(child => this.walkNode(child, nestedPrefix))\n .filter(Boolean)\n .join(\"\\n\");\n\n if (!childSelection) {\n return null;\n }\n\n return `${field.fieldId} { ${childSelection} }`;\n }\n\n private walkCollectionNode(\n node: CmsModelFieldAstNodeCollection,\n typePrefix: string\n ): string | null {\n const { collection, children } = node;\n const gqlTypeName = collection.gqlTypeName;\n\n if (!gqlTypeName) {\n return null;\n }\n\n const templateType = `${typePrefix}_${gqlTypeName}`;\n const childSelection = children\n .map(child => this.walkNode(child, templateType))\n .filter(Boolean)\n .join(\"\\n\");\n\n return `...on ${templateType} { ${childSelection} _templateId __typename }`;\n }\n}\n\nexport const ValuesSelectionGenerator = Abstraction.createImplementation({\n implementation: ValuesSelectionGeneratorImpl,\n dependencies: [ModelToAstConverter]\n});\n"],"names":["REF_SELECTION","ASSET_SELECTION","ValuesSelectionGeneratorImpl","modelToAst","model","ast","selection","typePrefix","node","Boolean","field","children","nestedPrefix","createTypeName","childSelection","child","collection","gqlTypeName","templateType","ValuesSelectionGenerator","Abstraction","ModelToAstConverter"],"mappings":";;;AAcA,MAAMA,gBAAgB;AAEtB,MAAMC,kBAAkB;AAOxB,MAAMC;IACF,YAA6BC,UAAyC,CAAE;aAA3CA,UAAU,GAAVA;IAA4C;IAEzE,SAASC,KAAe,EAAU;QAC9B,MAAMC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAACD;QAClC,MAAME,YAAY,IAAI,CAAC,QAAQ,CAACD,KAAKD,MAAM,eAAe;QAC1D,OAAOE,aAAa;IACxB;IAEQ,SAASD,GAAgB,EAAEE,UAAkB,EAAU;QAC3D,OAAOF,IAAI,QAAQ,CACd,GAAG,CAACG,CAAAA,OAAQ,IAAI,CAAC,QAAQ,CAACA,MAAMD,aAChC,MAAM,CAACE,SACP,IAAI,CAAC;IACd;IAEQ,SAASD,IAA0B,EAAED,UAAkB,EAAiB;QAC5E,IAAIC,AAAc,YAAdA,KAAK,IAAI,EACT,OAAO,IAAI,CAAC,aAAa,CAACA,MAAMD;QAEpC,IAAIC,AAAc,iBAAdA,KAAK,IAAI,EACT,OAAO,IAAI,CAAC,kBAAkB,CAACA,MAAMD;QAEzC,OAAO;IACX;IAEQ,cAAcC,IAA+B,EAAED,UAAkB,EAAiB;QACtF,MAAM,EAAEG,KAAK,EAAEC,QAAQ,EAAE,GAAGH;QAE5B,IAAIE,AAAe,UAAfA,MAAM,IAAI,EACV,OAAO,GAAGA,MAAM,OAAO,CAAC,CAAC,EAAEV,eAAe;QAG9C,IAAIU,AAAe,YAAfA,MAAM,IAAI,EACV,OAAO,GAAGA,MAAM,OAAO,CAAC,CAAC,EAAET,iBAAiB;QAGhD,IAAIU,AAAoB,MAApBA,SAAS,MAAM,EAAQ;YACvB,IAAID,AAAe,aAAfA,MAAM,IAAI,IAAiBA,AAAe,kBAAfA,MAAM,IAAI,EACrC,OAAO;YAEX,OAAOA,MAAM,OAAO;QACxB;QAEA,MAAME,eAAe,GAAGL,WAAW,CAAC,EAAEM,eAAeH,MAAM,OAAO,GAAG;QACrE,MAAMI,iBAAiBH,SAClB,GAAG,CAACI,CAAAA,QAAS,IAAI,CAAC,QAAQ,CAACA,OAAOH,eAClC,MAAM,CAACH,SACP,IAAI,CAAC;QAEV,IAAI,CAACK,gBACD,OAAO;QAGX,OAAO,GAAGJ,MAAM,OAAO,CAAC,GAAG,EAAEI,eAAe,EAAE,CAAC;IACnD;IAEQ,mBACJN,IAAoC,EACpCD,UAAkB,EACL;QACb,MAAM,EAAES,UAAU,EAAEL,QAAQ,EAAE,GAAGH;QACjC,MAAMS,cAAcD,WAAW,WAAW;QAE1C,IAAI,CAACC,aACD,OAAO;QAGX,MAAMC,eAAe,GAAGX,WAAW,CAAC,EAAEU,aAAa;QACnD,MAAMH,iBAAiBH,SAClB,GAAG,CAACI,CAAAA,QAAS,IAAI,CAAC,QAAQ,CAACA,OAAOG,eAClC,MAAM,CAACT,SACP,IAAI,CAAC;QAEV,OAAO,CAAC,MAAM,EAAES,aAAa,GAAG,EAAEJ,eAAe,yBAAyB,CAAC;IAC/E;AACJ;AAEO,MAAMK,oDAA2BC,yBAAAA,oBAAgC,CAAC;IACrE,gBAAgBlB;IAChB,cAAc;QAACmB;KAAoB;AACvC"}
1
+ {"version":3,"file":"features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js","sources":["../../../../src/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.ts"],"sourcesContent":["import {\n ValuesSelectionGenerator as Abstraction,\n type IValuesSelectionGenerator\n} from \"./abstractions.js\";\nimport { ModelToAstConverter } from \"../ModelToAstConverter/abstractions.js\";\nimport type {\n CmsModel,\n CmsModelAst,\n CmsModelFieldAstNode,\n CmsModelFieldAstNodeCollection,\n CmsModelFieldAstNodeField\n} from \"~/types/index.js\";\nimport { createTypeName } from \"~/utils/createTypeName.js\";\n\nconst REF_SELECTION = \"{ id modelId }\";\n\nconst ASSET_SELECTION = [\n \"{ id src url name type size\",\n \"image { width height crop { top left bottom right } focalPoint { x y } alt caption }\",\n \"document { pages }\",\n \"video { autoplay poster } }\"\n].join(\" \");\n\nclass ValuesSelectionGeneratorImpl implements IValuesSelectionGenerator {\n constructor(private readonly modelToAst: ModelToAstConverter.Interface) {}\n\n generate(model: CmsModel): string {\n const ast = this.modelToAst.toAst(model);\n const selection = this.walkRoot(ast, model.singularApiName);\n return selection || \"_empty\";\n }\n\n private walkRoot(ast: CmsModelAst, typePrefix: string): string {\n return ast.children\n .map(node => this.walkNode(node, typePrefix))\n .filter(Boolean)\n .join(\"\\n\");\n }\n\n private walkNode(node: CmsModelFieldAstNode, typePrefix: string): string | null {\n if (node.type === \"field\") {\n return this.walkFieldNode(node, typePrefix);\n }\n if (node.type === \"collection\") {\n return this.walkCollectionNode(node, typePrefix);\n }\n return null;\n }\n\n private walkFieldNode(node: CmsModelFieldAstNodeField, typePrefix: string): string | null {\n const { field, children } = node;\n\n if (field.type === \"ref\") {\n return `${field.fieldId} ${REF_SELECTION}`;\n }\n\n if (field.type === \"asset\") {\n return `${field.fieldId} ${ASSET_SELECTION}`;\n }\n\n if (children.length === 0) {\n if (field.type === \"object\" || field.type === \"dynamicZone\") {\n return null;\n }\n return field.fieldId;\n }\n\n const nestedPrefix = `${typePrefix}_${createTypeName(field.fieldId)}`;\n const childSelection = children\n .map(child => this.walkNode(child, nestedPrefix))\n .filter(Boolean)\n .join(\"\\n\");\n\n if (!childSelection) {\n return null;\n }\n\n const idSelection = field.type === \"object\" ? \"_id \" : \"\";\n return `${field.fieldId} { ${idSelection}${childSelection} }`;\n }\n\n private walkCollectionNode(\n node: CmsModelFieldAstNodeCollection,\n typePrefix: string\n ): string | null {\n const { collection, children } = node;\n const gqlTypeName = collection.gqlTypeName;\n\n if (!gqlTypeName) {\n return null;\n }\n\n const templateType = `${typePrefix}_${gqlTypeName}`;\n const childSelection = children\n .map(child => this.walkNode(child, templateType))\n .filter(Boolean)\n .join(\"\\n\");\n\n return `...on ${templateType} { ${childSelection} _templateId _id __typename }`;\n }\n}\n\nexport const ValuesSelectionGenerator = Abstraction.createImplementation({\n implementation: ValuesSelectionGeneratorImpl,\n dependencies: [ModelToAstConverter]\n});\n"],"names":["REF_SELECTION","ASSET_SELECTION","ValuesSelectionGeneratorImpl","modelToAst","model","ast","selection","typePrefix","node","Boolean","field","children","nestedPrefix","createTypeName","childSelection","child","idSelection","collection","gqlTypeName","templateType","ValuesSelectionGenerator","Abstraction","ModelToAstConverter"],"mappings":";;;AAcA,MAAMA,gBAAgB;AAEtB,MAAMC,kBAAkB;AAOxB,MAAMC;IACF,YAA6BC,UAAyC,CAAE;aAA3CA,UAAU,GAAVA;IAA4C;IAEzE,SAASC,KAAe,EAAU;QAC9B,MAAMC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAACD;QAClC,MAAME,YAAY,IAAI,CAAC,QAAQ,CAACD,KAAKD,MAAM,eAAe;QAC1D,OAAOE,aAAa;IACxB;IAEQ,SAASD,GAAgB,EAAEE,UAAkB,EAAU;QAC3D,OAAOF,IAAI,QAAQ,CACd,GAAG,CAACG,CAAAA,OAAQ,IAAI,CAAC,QAAQ,CAACA,MAAMD,aAChC,MAAM,CAACE,SACP,IAAI,CAAC;IACd;IAEQ,SAASD,IAA0B,EAAED,UAAkB,EAAiB;QAC5E,IAAIC,AAAc,YAAdA,KAAK,IAAI,EACT,OAAO,IAAI,CAAC,aAAa,CAACA,MAAMD;QAEpC,IAAIC,AAAc,iBAAdA,KAAK,IAAI,EACT,OAAO,IAAI,CAAC,kBAAkB,CAACA,MAAMD;QAEzC,OAAO;IACX;IAEQ,cAAcC,IAA+B,EAAED,UAAkB,EAAiB;QACtF,MAAM,EAAEG,KAAK,EAAEC,QAAQ,EAAE,GAAGH;QAE5B,IAAIE,AAAe,UAAfA,MAAM,IAAI,EACV,OAAO,GAAGA,MAAM,OAAO,CAAC,CAAC,EAAEV,eAAe;QAG9C,IAAIU,AAAe,YAAfA,MAAM,IAAI,EACV,OAAO,GAAGA,MAAM,OAAO,CAAC,CAAC,EAAET,iBAAiB;QAGhD,IAAIU,AAAoB,MAApBA,SAAS,MAAM,EAAQ;YACvB,IAAID,AAAe,aAAfA,MAAM,IAAI,IAAiBA,AAAe,kBAAfA,MAAM,IAAI,EACrC,OAAO;YAEX,OAAOA,MAAM,OAAO;QACxB;QAEA,MAAME,eAAe,GAAGL,WAAW,CAAC,EAAEM,eAAeH,MAAM,OAAO,GAAG;QACrE,MAAMI,iBAAiBH,SAClB,GAAG,CAACI,CAAAA,QAAS,IAAI,CAAC,QAAQ,CAACA,OAAOH,eAClC,MAAM,CAACH,SACP,IAAI,CAAC;QAEV,IAAI,CAACK,gBACD,OAAO;QAGX,MAAME,cAAcN,AAAe,aAAfA,MAAM,IAAI,GAAgB,SAAS;QACvD,OAAO,GAAGA,MAAM,OAAO,CAAC,GAAG,EAAEM,cAAcF,eAAe,EAAE,CAAC;IACjE;IAEQ,mBACJN,IAAoC,EACpCD,UAAkB,EACL;QACb,MAAM,EAAEU,UAAU,EAAEN,QAAQ,EAAE,GAAGH;QACjC,MAAMU,cAAcD,WAAW,WAAW;QAE1C,IAAI,CAACC,aACD,OAAO;QAGX,MAAMC,eAAe,GAAGZ,WAAW,CAAC,EAAEW,aAAa;QACnD,MAAMJ,iBAAiBH,SAClB,GAAG,CAACI,CAAAA,QAAS,IAAI,CAAC,QAAQ,CAACA,OAAOI,eAClC,MAAM,CAACV,SACP,IAAI,CAAC;QAEV,OAAO,CAAC,MAAM,EAAEU,aAAa,GAAG,EAAEL,eAAe,6BAA6B,CAAC;IACnF;AACJ;AAEO,MAAMM,oDAA2BC,yBAAAA,oBAAgC,CAAC;IACrE,gBAAgBnB;IAChB,cAAc;QAACoB;KAAoB;AACvC"}
@@ -5,6 +5,7 @@ import { PluginGroupsProvider } from "../../../features/contentModelGroup/shared
5
5
  import { StorageOperations } from "../../../features/shared/abstractions.js";
6
6
  import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
7
7
  import type { CmsGroup } from "../../../types/index.js";
8
+ import { RuntimeTenant } from "../../../features/runtimeTenant/abstractions.js";
8
9
  /**
9
10
  * CreateGroupRepository - Validates and persists a new group.
10
11
  *
@@ -20,8 +21,9 @@ declare class CreateGroupRepositoryImpl implements RepositoryAbstraction.Interfa
20
21
  private pluginGroupsProvider;
21
22
  private storageOperations;
22
23
  private tenantContext;
23
- constructor(groupCache: GroupCache.Interface, pluginGroupsProvider: PluginGroupsProvider.Interface, storageOperations: StorageOperations.Interface, tenantContext: TenantContext.Interface);
24
- execute(group: CmsGroup): Promise<Result<void, RepositoryAbstraction.Error>>;
24
+ private runtimeTenant;
25
+ constructor(groupCache: GroupCache.Interface, pluginGroupsProvider: PluginGroupsProvider.Interface, storageOperations: StorageOperations.Interface, tenantContext: TenantContext.Interface, runtimeTenant: RuntimeTenant.Interface);
26
+ execute(initialGroup: CmsGroup): Promise<Result<CmsGroup, RepositoryAbstraction.Error>>;
25
27
  private isSlugTaken;
26
28
  }
27
29
  export declare const CreateGroupRepository: import("@webiny/di").Implementation<typeof CreateGroupRepositoryImpl>;
@@ -6,14 +6,17 @@ import { StorageOperations } from "../../shared/abstractions.js";
6
6
  import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
7
7
  import { toSlug } from "../../../utils/toSlug.js";
8
8
  import { generateAlphaNumericId } from "@webiny/utils";
9
+ import { RuntimeTenant } from "../../runtimeTenant/abstractions.js";
9
10
  class CreateGroupRepositoryImpl {
10
- constructor(groupCache, pluginGroupsProvider, storageOperations, tenantContext){
11
+ constructor(groupCache, pluginGroupsProvider, storageOperations, tenantContext, runtimeTenant){
11
12
  this.groupCache = groupCache;
12
13
  this.pluginGroupsProvider = pluginGroupsProvider;
13
14
  this.storageOperations = storageOperations;
14
15
  this.tenantContext = tenantContext;
16
+ this.runtimeTenant = runtimeTenant;
15
17
  }
16
- async execute(group) {
18
+ async execute(initialGroup) {
19
+ const group = this.runtimeTenant.assign(initialGroup);
17
20
  try {
18
21
  const tenant = this.tenantContext.getTenant();
19
22
  if (group.id) {
@@ -34,7 +37,7 @@ class CreateGroupRepositoryImpl {
34
37
  group
35
38
  });
36
39
  this.groupCache.clear();
37
- return Result.ok();
40
+ return Result.ok(group);
38
41
  } catch (error) {
39
42
  return Result.fail(new GroupPersistenceError(error));
40
43
  }
@@ -68,7 +71,8 @@ const CreateGroupRepository_CreateGroupRepository = createImplementation({
68
71
  GroupCache,
69
72
  PluginGroupsProvider,
70
73
  StorageOperations,
71
- TenantContext
74
+ TenantContext,
75
+ RuntimeTenant
72
76
  ]
73
77
  });
74
78
  export { CreateGroupRepository_CreateGroupRepository as CreateGroupRepository };