@webiny/api-headless-cms 6.6.0-alpha.0 → 6.6.0-alpha.1

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 (139) hide show
  1. package/HeadlessCmsFeature.js +4 -1
  2. package/HeadlessCmsFeature.js.map +1 -1
  3. package/createCmsRoute.d.ts +13 -8
  4. package/createCmsRoute.js +14 -4
  5. package/createCmsRoute.js.map +1 -1
  6. package/crud/contentEntry/entryDataValidation.js +27 -0
  7. package/crud/contentEntry/entryDataValidation.js.map +1 -1
  8. package/crud/contentModel/defaultFields.js +3 -2
  9. package/crud/contentModel/defaultFields.js.map +1 -1
  10. package/domain/contentModel/schemas.d.ts +8 -6
  11. package/domain/contentModel/schemas.js +5 -3
  12. package/domain/contentModel/schemas.js.map +1 -1
  13. package/exports/api/cms/model.d.ts +4 -1
  14. package/exports/api/cms/model.js +2 -0
  15. package/features/ai/DescribeContentModelTool.d.ts +55 -0
  16. package/features/ai/DescribeContentModelTool.js +60 -0
  17. package/features/ai/DescribeContentModelTool.js.map +1 -0
  18. package/features/ai/ListContentModelsTool.d.ts +41 -0
  19. package/features/ai/ListContentModelsTool.js +44 -0
  20. package/features/ai/ListContentModelsTool.js.map +1 -0
  21. package/features/ai/QueryEntriesTool.d.ts +75 -0
  22. package/features/ai/QueryEntriesTool.js +90 -0
  23. package/features/ai/QueryEntriesTool.js.map +1 -0
  24. package/features/ai/feature.d.ts +8 -0
  25. package/features/ai/feature.js +15 -0
  26. package/features/ai/feature.js.map +1 -0
  27. package/features/ai/index.d.ts +4 -0
  28. package/features/ai/index.js +4 -0
  29. package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.d.ts +14 -0
  30. package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.js +32 -0
  31. package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.js.map +1 -0
  32. package/features/contentModel/ComponentMapGenerator/abstractions.d.ts +8 -0
  33. package/features/contentModel/ComponentMapGenerator/abstractions.js +5 -0
  34. package/features/contentModel/ComponentMapGenerator/abstractions.js.map +1 -0
  35. package/features/contentModel/ComponentMapGenerator/feature.d.ts +4 -0
  36. package/features/contentModel/ComponentMapGenerator/feature.js +11 -0
  37. package/features/contentModel/ComponentMapGenerator/feature.js.map +1 -0
  38. package/features/contentModel/ComponentMapGenerator/index.d.ts +2 -0
  39. package/features/contentModel/ComponentMapGenerator/index.js +2 -0
  40. package/features/contentModel/ContentModelFeature.js +4 -0
  41. package/features/contentModel/ContentModelFeature.js.map +1 -1
  42. package/features/contentModel/RefModelsGenerator/RefModelsGenerator.d.ts +19 -0
  43. package/features/contentModel/RefModelsGenerator/RefModelsGenerator.js +56 -0
  44. package/features/contentModel/RefModelsGenerator/RefModelsGenerator.js.map +1 -0
  45. package/features/contentModel/RefModelsGenerator/abstractions.d.ts +11 -0
  46. package/features/contentModel/RefModelsGenerator/abstractions.js +5 -0
  47. package/features/contentModel/RefModelsGenerator/abstractions.js.map +1 -0
  48. package/features/contentModel/RefModelsGenerator/feature.d.ts +4 -0
  49. package/features/contentModel/RefModelsGenerator/feature.js +11 -0
  50. package/features/contentModel/RefModelsGenerator/feature.js.map +1 -0
  51. package/features/contentModel/RefModelsGenerator/index.d.ts +2 -0
  52. package/features/contentModel/RefModelsGenerator/index.js +2 -0
  53. package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js +2 -0
  54. package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js.map +1 -1
  55. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.d.ts +3 -1
  56. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.js +6 -4
  57. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.js.map +1 -1
  58. package/features/graphql/feature.js +2 -0
  59. package/features/graphql/feature.js.map +1 -1
  60. package/features/graphql/fields/base/AssetToGraphQL.d.ts +26 -0
  61. package/features/graphql/fields/base/AssetToGraphQL.js +148 -0
  62. package/features/graphql/fields/base/AssetToGraphQL.js.map +1 -0
  63. package/features/graphql/fields/base/DynamicZoneToGraphQL.js +5 -1
  64. package/features/graphql/fields/base/DynamicZoneToGraphQL.js.map +1 -1
  65. package/features/graphql/fields/base/ObjectToGraphQL.js +2 -2
  66. package/features/graphql/fields/base/ObjectToGraphQL.js.map +1 -1
  67. package/features/modelBuilder/abstractions.d.ts +10 -0
  68. package/features/modelBuilder/abstractions.js.map +1 -1
  69. package/features/modelBuilder/feature.js +2 -0
  70. package/features/modelBuilder/feature.js.map +1 -1
  71. package/features/modelBuilder/fields/AssetFieldType.d.ts +20 -0
  72. package/features/modelBuilder/fields/AssetFieldType.js +46 -0
  73. package/features/modelBuilder/fields/AssetFieldType.js.map +1 -0
  74. package/features/modelBuilder/fields/BaseFieldBuilder.d.ts +3 -1
  75. package/features/modelBuilder/fields/BaseFieldBuilder.js +4 -0
  76. package/features/modelBuilder/fields/BaseFieldBuilder.js.map +1 -1
  77. package/features/modelBuilder/fields/DataFieldBuilder.d.ts +42 -0
  78. package/features/modelBuilder/fields/DataFieldBuilder.js +5 -1
  79. package/features/modelBuilder/fields/DataFieldBuilder.js.map +1 -1
  80. package/features/modelBuilder/fields/DynamicZoneFieldType.d.ts +1 -0
  81. package/features/modelBuilder/fields/DynamicZoneFieldType.js +10 -9
  82. package/features/modelBuilder/fields/DynamicZoneFieldType.js.map +1 -1
  83. package/features/modelBuilder/fields/UiAlertFieldType.js +2 -1
  84. package/features/modelBuilder/fields/UiAlertFieldType.js.map +1 -1
  85. package/features/modelBuilder/fields/UiSeparatorFieldType.js +2 -1
  86. package/features/modelBuilder/fields/UiSeparatorFieldType.js.map +1 -1
  87. package/features/modelBuilder/fields/UiTabsFieldType.d.ts +2 -1
  88. package/features/modelBuilder/fields/UiTabsFieldType.js +6 -3
  89. package/features/modelBuilder/fields/UiTabsFieldType.js.map +1 -1
  90. package/features/modelBuilder/fields/resolveAssetUrl.d.ts +35 -0
  91. package/features/modelBuilder/fields/resolveAssetUrl.js +26 -0
  92. package/features/modelBuilder/fields/resolveAssetUrl.js.map +1 -0
  93. package/features/modelBuilder/index.d.ts +1 -1
  94. package/features/modelBuilder/models/BaseModelBuilder.d.ts +3 -1
  95. package/features/modelBuilder/models/BaseModelBuilder.js +7 -0
  96. package/features/modelBuilder/models/BaseModelBuilder.js.map +1 -1
  97. package/features/modelBuilder/models/PrivateModelBuilder.js +2 -1
  98. package/features/modelBuilder/models/PrivateModelBuilder.js.map +1 -1
  99. package/features/modelBuilder/models/PublicModelBuilder.js +2 -1
  100. package/features/modelBuilder/models/PublicModelBuilder.js.map +1 -1
  101. package/features/sortMapper/SortMapper.js +2 -5
  102. package/features/sortMapper/SortMapper.js.map +1 -1
  103. package/features/whereMapper/WhereMapper.js +7 -5
  104. package/features/whereMapper/WhereMapper.js.map +1 -1
  105. package/graphql/schema/cms/getEntryResolver.js +3 -2
  106. package/graphql/schema/cms/getEntryResolver.js.map +1 -1
  107. package/graphql/schema/cms/getModelResolver.d.ts +35 -0
  108. package/graphql/schema/cms/getModelResolver.js +49 -0
  109. package/graphql/schema/cms/getModelResolver.js.map +1 -0
  110. package/graphql/schema/cms/helpers/buildFieldsSelection.js +9 -2
  111. package/graphql/schema/cms/helpers/buildFieldsSelection.js.map +1 -1
  112. package/graphql/schema/cms/helpers/expandFieldWildcards.d.ts +2 -0
  113. package/graphql/schema/cms/helpers/expandFieldWildcards.js +13 -0
  114. package/graphql/schema/cms/helpers/expandFieldWildcards.js.map +1 -0
  115. package/graphql/schema/cms/helpers/index.d.ts +1 -0
  116. package/graphql/schema/cms/helpers/index.js +1 -0
  117. package/graphql/schema/cms/helpers/transformWhereToNested.js +39 -17
  118. package/graphql/schema/cms/helpers/transformWhereToNested.js.map +1 -1
  119. package/graphql/schema/cms/helpers.d.ts +1 -0
  120. package/graphql/schema/cms/helpers.js +1 -0
  121. package/graphql/schema/cms/listEntriesResolver.js +3 -2
  122. package/graphql/schema/cms/listEntriesResolver.js.map +1 -1
  123. package/graphql/schema/cms/resolvers/getModel.d.ts +8 -0
  124. package/graphql/schema/cms/resolvers/getModel.js +18 -0
  125. package/graphql/schema/cms/resolvers/getModel.js.map +1 -0
  126. package/graphql/schema/cms/resolvers/index.d.ts +1 -0
  127. package/graphql/schema/cms/resolvers/index.js +1 -0
  128. package/graphql/schema/cms/typeDefs/query.js +1 -0
  129. package/graphql/schema/cms/typeDefs/query.js.map +1 -1
  130. package/graphql/schema/cms/typeDefs/responses.js +5 -0
  131. package/graphql/schema/cms/typeDefs/responses.js.map +1 -1
  132. package/graphql/schema/contentModels.js +31 -0
  133. package/graphql/schema/contentModels.js.map +1 -1
  134. package/package.json +21 -22
  135. package/plugins/CmsModelPlugin.js +2 -1
  136. package/plugins/CmsModelPlugin.js.map +1 -1
  137. package/types/fields/dynamicZoneField.d.ts +3 -2
  138. package/types/model.d.ts +6 -0
  139. package/types/modelField.d.ts +3 -1
@@ -14,6 +14,7 @@ import { StorageFeature } from "./features/storage/index.js";
14
14
  import { CmsInstallerFeature } from "./features/installer/feature.js";
15
15
  import { ContentEntriesFeature } from "./features/contentEntry/ContentEntriesFeature.js";
16
16
  import { ContentModelFeature } from "./features/contentModel/ContentModelFeature.js";
17
+ import { CmsAiToolsFeature } from "./features/ai/index.js";
17
18
  import { ContentModelGroupFeature } from "./features/contentModelGroup/ContentModelGroupFeature.js";
18
19
  import { ModelBuilderFeature } from "./features/modelBuilder/index.js";
19
20
  import { CmsWhereMapperFeature } from "./features/whereMapper/feature.js";
@@ -22,7 +23,7 @@ import { CmsWebhooksFeature } from "./features/webhooks/feature.js";
22
23
  import { CmsBaseErrorTypeFactory } from "./graphql/schema/cms/CmsBaseErrorTypeFactory.js";
23
24
  import { CmsSchemaExecutor } from "./graphql/CmsSchemaExecutor.js";
24
25
  import { CmsMutationTypeDefsImpl, CmsQueryTypeDefsImpl, CmsResponseTypeDefsImpl } from "./graphql/schema/cms/typeDefs/index.js";
25
- import { CreateEntryResolverImpl, DeleteEntryRevisionResolverImpl, GetEntryResolverImpl, ListEntriesResolverImpl, MutationCmsResolverImpl, PublishEntryRevisionResolverImpl, QueryCmsResolverImpl, UnpublishEntryRevisionResolverImpl, UpdateEntryRevisionResolverImpl } from "./graphql/schema/cms/resolvers/index.js";
26
+ import { CreateEntryResolverImpl, DeleteEntryRevisionResolverImpl, GetEntryResolverImpl, GetModelResolverImpl, ListEntriesResolverImpl, MutationCmsResolverImpl, PublishEntryRevisionResolverImpl, QueryCmsResolverImpl, UnpublishEntryRevisionResolverImpl, UpdateEntryRevisionResolverImpl } from "./graphql/schema/cms/resolvers/index.js";
26
27
  import { AccessControl } from "./crud/AccessControl/AccessControl.js";
27
28
  import { createModelGroupsCrud } from "./crud/contentModelGroup.crud.js";
28
29
  import { createModelsCrud } from "./crud/contentModel.crud.js";
@@ -56,6 +57,7 @@ const HeadlessCmsFeature = createFeature({
56
57
  container.register(CmsMutationTypeDefsImpl);
57
58
  container.register(QueryCmsResolverImpl);
58
59
  container.register(MutationCmsResolverImpl);
60
+ container.register(GetModelResolverImpl);
59
61
  container.register(GetEntryResolverImpl);
60
62
  container.register(ListEntriesResolverImpl);
61
63
  container.register(CreateEntryResolverImpl);
@@ -73,6 +75,7 @@ const HeadlessCmsFeature = createFeature({
73
75
  CmsInstallerFeature.register(container);
74
76
  ContentEntriesFeature.register(container);
75
77
  ContentModelFeature.register(container);
78
+ CmsAiToolsFeature.register(container);
76
79
  ContentModelGroupFeature.register(container);
77
80
  ModelBuilderFeature.register(container);
78
81
  CmsWhereMapperFeature.register(container);
@@ -1 +1 @@
1
- {"version":3,"file":"HeadlessCmsFeature.js","sources":["../src/HeadlessCmsFeature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/abstractions.js\";\nimport { HeadlessCmsEndpointConfig } from \"./HeadlessCmsEndpointConfig.js\";\nimport { createCmsRoute } from \"./createCmsRoute.js\";\nimport { createRequestBody, processRequestBody } from \"@webiny/api-graphql\";\nimport { BenchmarkAbstraction } from \"@webiny/api\";\nimport { Benchmark } from \"@webiny/api/Benchmark.js\";\nimport { PluginsContainer } from \"@webiny/plugins\";\nimport { CompressionFeature } from \"@webiny/utils/features/compression/feature.js\";\nimport { GraphQLFeature } from \"~/features/graphql/index.js\";\nimport { ValidationFeature } from \"~/features/validation/index.js\";\nimport { StorageFeature } from \"~/features/storage/index.js\";\nimport { CmsInstallerFeature } from \"~/features/installer/feature.js\";\nimport { ContentEntriesFeature } from \"~/features/contentEntry/ContentEntriesFeature.js\";\nimport { ContentModelFeature } from \"~/features/contentModel/ContentModelFeature.js\";\nimport { ContentModelGroupFeature } from \"~/features/contentModelGroup/ContentModelGroupFeature.js\";\nimport { ModelBuilderFeature } from \"~/features/modelBuilder/index.js\";\nimport { CmsWhereMapperFeature } from \"~/features/whereMapper/feature.js\";\nimport { CmsSortMapperFeature } from \"~/features/sortMapper/feature.js\";\nimport { CmsWebhooksFeature } from \"~/features/webhooks/feature.js\";\nimport type { ApiEndpoint, CmsContext } from \"~/types/index.js\";\nimport { CmsBaseErrorTypeFactory } from \"~/graphql/schema/cms/CmsBaseErrorTypeFactory.js\";\nimport { CmsSchemaExecutor } from \"~/graphql/CmsSchemaExecutor.js\";\nimport {\n CmsResponseTypeDefsImpl,\n CmsQueryTypeDefsImpl,\n CmsMutationTypeDefsImpl\n} from \"~/graphql/schema/cms/typeDefs/index.js\";\nimport {\n QueryCmsResolverImpl,\n MutationCmsResolverImpl,\n GetEntryResolverImpl,\n ListEntriesResolverImpl,\n CreateEntryResolverImpl,\n UpdateEntryRevisionResolverImpl,\n DeleteEntryRevisionResolverImpl,\n PublishEntryRevisionResolverImpl,\n UnpublishEntryRevisionResolverImpl\n} from \"~/graphql/schema/cms/resolvers/index.js\";\n// Facade wiring (moved here from HeadlessCmsInitializer so the facade can be a lazy DI factory).\nimport { AccessControl } from \"~/crud/AccessControl/AccessControl.js\";\nimport { createModelGroupsCrud } from \"~/crud/contentModelGroup.crud.js\";\nimport { createModelsCrud } from \"~/crud/contentModel.crud.js\";\nimport { createContentEntryCrud } from \"~/crud/contentEntry.crud.js\";\nimport type { ICmsGraphQLSchemaPlugin } from \"~/plugins/index.js\";\nimport {\n CmsGraphQLSchemaPlugin,\n CmsGroupPlugin,\n CmsModelPlugin,\n StorageOperationsCmsModelPlugin\n} from \"~/plugins/index.js\";\nimport { createCmsModelFieldConvertersAttachFactory } from \"~/utils/converters/valueKeyStorageConverter.js\";\nimport { registerFieldConverters } from \"~/fieldConverters/abstractions.js\";\nimport { CmsModelPluginInstance } from \"~/features/contentModel/shared/abstractions.js\";\nimport { CmsGroupPluginInstance } from \"~/features/contentModelGroup/shared/abstractions.js\";\nimport { createExportCrud } from \"~/export/index.js\";\nimport { createImportCrud } from \"~/export/crud/importing.js\";\nimport { getSchema } from \"~/graphql/getSchema.js\";\nimport { createBaseSchemaPlugins } from \"~/graphql/schema/baseSchema.js\";\nimport { exportPlugin } from \"~/export/graphql/index.js\";\nimport { CoreGraphQLSchemaFactory } from \"@webiny/api-graphql/graphql/abstractions.js\";\nimport { CmsGraphQLSchemaFactory } from \"~/graphql/CmsGraphQLSchemaFactory.js\";\nimport { CmsExport, CmsImport } from \"~/export/abstractions.js\";\nimport { ListGroupsUseCase } from \"~/features/contentModelGroup/ListGroups/index.js\";\nimport { RevisionIdScalar } from \"~/graphql/scalars/RevisionId.js\";\nimport {\n AccessControl as AccessControlAbstraction,\n CmsContext as CmsContextAbstraction,\n CmsStorageModelProvider,\n HeadlessCms\n} from \"~/features/shared/abstractions.js\";\n\nimport {\n EntryFromStorageTransform,\n EntryToStorageTransform,\n PluginsContainer as PluginsContainerAbstraction,\n SearchableFieldsProvider\n} from \"~/legacy/abstractions.js\";\nimport { entryFromStorageTransform, entryToStorageTransform } from \"~/utils/entryStorage.js\";\nimport { getSearchableFields } from \"~/crud/contentEntry/searchableFields.js\";\nexport interface HeadlessCmsConfig {\n type: ApiEndpoint;\n /** Extra plugins (e.g. CmsGraphQLSchemaPlugin) to register in ctx.plugins at runtime. */\n extraPlugins?: any[];\n}\n\nexport const HeadlessCmsFeature = createFeature<HeadlessCmsConfig>({\n name: \"HeadlessCms\",\n register(container, config) {\n const { type } = config;\n\n // Pre-register the CMS SDK namespace schema (Query.cms / Mutation.cms) so it is\n // available when GraphQLSchemaComposer is constructed (before context enhancement).\n // All these implementations have zero DI dependencies and are safe to register early.\n container.register(CmsBaseErrorTypeFactory); // CmsError must come first\n container.register(CmsResponseTypeDefsImpl);\n container.register(CmsQueryTypeDefsImpl);\n container.register(CmsMutationTypeDefsImpl);\n container.register(QueryCmsResolverImpl);\n container.register(MutationCmsResolverImpl);\n container.register(GetEntryResolverImpl);\n container.register(ListEntriesResolverImpl);\n container.register(CreateEntryResolverImpl);\n container.register(UpdateEntryRevisionResolverImpl);\n container.register(DeleteEntryRevisionResolverImpl);\n container.register(PublishEntryRevisionResolverImpl);\n container.register(UnpublishEntryRevisionResolverImpl);\n\n container.registerInstance(HeadlessCmsEndpointConfig, {\n type: config.type\n });\n\n // Register CMS DI features statically so they are available before any enhancers run.\n // All these are pure class registrations (no eager instantiation) so they are safe\n // to register here before any request-time context is available.\n CompressionFeature.register(container);\n GraphQLFeature.register(container);\n ValidationFeature.register(container);\n StorageFeature.register(container);\n CmsInstallerFeature.register(container);\n ContentEntriesFeature.register(container);\n ContentModelFeature.register(container);\n ContentModelGroupFeature.register(container);\n ModelBuilderFeature.register(container);\n CmsWhereMapperFeature.register(container);\n CmsSortMapperFeature.register(container);\n CmsWebhooksFeature.register(container);\n\n // ============================================================================\n // Synchronous per-request wiring (moved out of HeadlessCmsInitializer.init).\n // register() runs per request, pre-auth — correct for pure wiring and closures.\n // ============================================================================\n\n // Field value converters are resolved from the DI container.\n registerFieldConverters(container);\n\n // PluginsContainer still carries legacy extension plugins (e.g. CmsGraphQLSchemaPlugin)\n // until those remaining consumers are migrated to DI.\n const pluginsContainer = new PluginsContainer([...(config.extraPlugins ?? [])]);\n container.registerInstance(PluginsContainerAbstraction, pluginsContainer);\n\n // Code-defined model/group plugins are exposed via DI tokens so the\n // Plugin{Models,Groups}Provider can resolve them without the plugins container.\n for (const plugin of pluginsContainer.byType<CmsModelPlugin>(CmsModelPlugin.type)) {\n container.registerInstance(CmsModelPluginInstance, plugin);\n }\n for (const plugin of pluginsContainer.byType<CmsGroupPlugin>(CmsGroupPlugin.type)) {\n container.registerInstance(CmsGroupPluginInstance, plugin);\n }\n\n // User-provided GraphQL schema extension plugins (added via extraPlugins) are bridged\n // to the CmsGraphQLSchemaFactory DI token so generateSchema includes them.\n const userSchemaPlugins = pluginsContainer.byType<ICmsGraphQLSchemaPlugin>(\n CmsGraphQLSchemaPlugin.type\n );\n if (userSchemaPlugins.length > 0) {\n container.registerInstance(CmsGraphQLSchemaFactory, {\n execute: () => userSchemaPlugins\n });\n }\n\n // RegisterExtensionPlugins supplied via extraPlugins (test infra) only do DI registration\n // via their apply(). Apply them here at register() time — matching the app's registerExtensions\n // and the storage presets above — so code-defined models are present before per-request model\n // listing runs.\n for (const plugin of config.extraPlugins ?? []) {\n if (plugin && typeof (plugin as any).apply === \"function\") {\n (plugin as any).apply({ container });\n }\n }\n\n const benchmark = new Benchmark();\n container.registerInstance(BenchmarkAbstraction, benchmark);\n\n // The CmsContext \"shim\": the request-scoped context object the facade builders, transforms\n // and getSchema operate on. They only read `.container` (+ plugins/benchmark), so this is\n // all they need — there is no legacy bag.\n const cmsContext = {\n container,\n plugins: pluginsContainer,\n benchmark\n } as unknown as CmsContext;\n container.registerInstance(CmsContextAbstraction, cmsContext);\n\n container.registerInstance(CoreGraphQLSchemaFactory, {\n execute: async builder => {\n builder.addTypeDefs(\"scalar RevisionId\");\n builder.addLegacyResolvers({ RevisionId: RevisionIdScalar });\n return builder;\n }\n });\n\n container.registerInstance(\n CmsStorageModelProvider,\n new StorageOperationsCmsModelPlugin(\n createCmsModelFieldConvertersAttachFactory(cmsContext)\n )\n );\n\n // Entry storage operations are registered by each adapter's feature at app-scope.\n // HeadlessCmsFeature no longer manages entry storage registration.\n\n const identityContext = container.resolve(IdentityContext);\n const tenantContext = container.resolve(TenantContext);\n const getTenant = () => tenantContext.getTenant();\n\n // AccessControl is identity-dependent; build it lazily and memoise per request container.\n let accessControlInstance: AccessControl | undefined;\n const getAccessControl = (): AccessControl => {\n if (!accessControlInstance) {\n accessControlInstance = new AccessControl({\n getIdentity: async () => identityContext.getIdentity(),\n getGroupsPermissions: () =>\n identityContext.getPermissions(\"cms.contentModelGroup\"),\n getModelsPermissions: () => identityContext.getPermissions(\"cms.contentModel\"),\n getEntriesPermissions: () => identityContext.getPermissions(\"cms.contentEntry\"),\n listAllGroups: async () => {\n const result = await identityContext.withoutAuthorization(() =>\n container.resolve(ListGroupsUseCase).execute()\n );\n if (result.isFail()) {\n throw result.error;\n }\n return result.value;\n }\n });\n }\n return accessControlInstance;\n };\n container.registerFactory(AccessControlAbstraction, () => getAccessControl());\n\n // The HeadlessCms facade — a LAZY factory built on first resolve (post-auth), memoised per\n // request container.\n let cmsFacade: HeadlessCms.Interface | undefined;\n container.registerFactory(HeadlessCms, () => {\n if (!cmsFacade) {\n cmsFacade = {\n type,\n READ: type === \"read\",\n PREVIEW: type === \"preview\",\n MANAGE: type === \"manage\",\n accessControl: getAccessControl(),\n ...createModelGroupsCrud({ context: cmsContext }),\n ...createModelsCrud({ context: cmsContext }),\n ...createContentEntryCrud({ context: cmsContext }),\n export: { ...createExportCrud(cmsContext) },\n importing: { ...createImportCrud(cmsContext) }\n } as HeadlessCms.Interface;\n }\n return cmsFacade;\n });\n container.registerFactory(CmsExport, () => container.resolve(HeadlessCms).export);\n container.registerFactory(CmsImport, () => container.resolve(HeadlessCms).importing);\n\n // Register CmsSchemaExecutor so proxy resolvers can build and execute the CMS sub-schema.\n container.registerInstance(CmsSchemaExecutor, {\n execute: async (schemaType: ApiEndpoint, body: any) => {\n const bm = container.resolve(BenchmarkAbstraction);\n const schema = await bm.measure(\"headlessCms.graphql.getSchema\", () =>\n identityContext.withoutAuthorization(() =>\n getSchema({ context: cmsContext, getTenant, type: schemaType })\n )\n );\n const requestBody = await bm.measure(\n \"headlessCms.graphql.createRequestBody\",\n async () => createRequestBody(body)\n );\n return bm.measure(\"headlessCms.graphql.processRequestBody\", () =>\n processRequestBody(requestBody, schema, cmsContext)\n );\n }\n });\n\n // Register CMS sub-schema factories: base types (CmsError, CmsIdentity, etc.)\n // and, for manage endpoints, the import/export operations.\n container.registerInstance(CmsGraphQLSchemaFactory, {\n execute: () => createBaseSchemaPlugins(cmsContext)\n });\n if (type === \"manage\") {\n container.registerInstance(CmsGraphQLSchemaFactory, {\n execute: () => [exportPlugin]\n });\n }\n\n container.registerInstance(EntryToStorageTransform, (model, entry) => {\n return entryToStorageTransform(cmsContext, model, entry);\n });\n container.registerInstance(EntryFromStorageTransform, (model, entry) => {\n return entryFromStorageTransform(cmsContext, model, entry);\n });\n container.registerInstance(SearchableFieldsProvider, params => {\n return getSearchableFields({\n context: cmsContext,\n fields: params.fields,\n input: []\n });\n });\n\n container.register(createCmsRoute(config.type));\n }\n});\n"],"names":["HeadlessCmsFeature","createFeature","container","config","type","CmsBaseErrorTypeFactory","CmsResponseTypeDefsImpl","CmsQueryTypeDefsImpl","CmsMutationTypeDefsImpl","QueryCmsResolverImpl","MutationCmsResolverImpl","GetEntryResolverImpl","ListEntriesResolverImpl","CreateEntryResolverImpl","UpdateEntryRevisionResolverImpl","DeleteEntryRevisionResolverImpl","PublishEntryRevisionResolverImpl","UnpublishEntryRevisionResolverImpl","HeadlessCmsEndpointConfig","CompressionFeature","GraphQLFeature","ValidationFeature","StorageFeature","CmsInstallerFeature","ContentEntriesFeature","ContentModelFeature","ContentModelGroupFeature","ModelBuilderFeature","CmsWhereMapperFeature","CmsSortMapperFeature","CmsWebhooksFeature","registerFieldConverters","pluginsContainer","PluginsContainer","PluginsContainerAbstraction","plugin","CmsModelPlugin","CmsModelPluginInstance","CmsGroupPlugin","CmsGroupPluginInstance","userSchemaPlugins","CmsGraphQLSchemaPlugin","CmsGraphQLSchemaFactory","benchmark","Benchmark","BenchmarkAbstraction","cmsContext","CmsContextAbstraction","CoreGraphQLSchemaFactory","builder","RevisionIdScalar","CmsStorageModelProvider","StorageOperationsCmsModelPlugin","createCmsModelFieldConvertersAttachFactory","identityContext","IdentityContext","tenantContext","TenantContext","getTenant","accessControlInstance","getAccessControl","AccessControl","result","ListGroupsUseCase","AccessControlAbstraction","cmsFacade","HeadlessCms","createModelGroupsCrud","createModelsCrud","createContentEntryCrud","createExportCrud","createImportCrud","CmsExport","CmsImport","CmsSchemaExecutor","schemaType","body","bm","schema","getSchema","requestBody","createRequestBody","processRequestBody","createBaseSchemaPlugins","exportPlugin","EntryToStorageTransform","model","entry","entryToStorageTransform","EntryFromStorageTransform","entryFromStorageTransform","SearchableFieldsProvider","params","getSearchableFields","createCmsRoute"],"mappings":"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"}
1
+ {"version":3,"file":"HeadlessCmsFeature.js","sources":["../src/HeadlessCmsFeature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/abstractions.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/abstractions.js\";\nimport { HeadlessCmsEndpointConfig } from \"./HeadlessCmsEndpointConfig.js\";\nimport { createCmsRoute } from \"./createCmsRoute.js\";\nimport { createRequestBody, processRequestBody } from \"@webiny/api-graphql\";\nimport { BenchmarkAbstraction } from \"@webiny/api\";\nimport { Benchmark } from \"@webiny/api/Benchmark.js\";\nimport { PluginsContainer } from \"@webiny/plugins\";\nimport { CompressionFeature } from \"@webiny/utils/features/compression/feature.js\";\nimport { GraphQLFeature } from \"~/features/graphql/index.js\";\nimport { ValidationFeature } from \"~/features/validation/index.js\";\nimport { StorageFeature } from \"~/features/storage/index.js\";\nimport { CmsInstallerFeature } from \"~/features/installer/feature.js\";\nimport { ContentEntriesFeature } from \"~/features/contentEntry/ContentEntriesFeature.js\";\nimport { ContentModelFeature } from \"~/features/contentModel/ContentModelFeature.js\";\nimport { CmsAiToolsFeature } from \"~/features/ai/index.js\";\nimport { ContentModelGroupFeature } from \"~/features/contentModelGroup/ContentModelGroupFeature.js\";\nimport { ModelBuilderFeature } from \"~/features/modelBuilder/index.js\";\nimport { CmsWhereMapperFeature } from \"~/features/whereMapper/feature.js\";\nimport { CmsSortMapperFeature } from \"~/features/sortMapper/feature.js\";\nimport { CmsWebhooksFeature } from \"~/features/webhooks/feature.js\";\nimport type { ApiEndpoint, CmsContext } from \"~/types/index.js\";\nimport { CmsBaseErrorTypeFactory } from \"~/graphql/schema/cms/CmsBaseErrorTypeFactory.js\";\nimport { CmsSchemaExecutor } from \"~/graphql/CmsSchemaExecutor.js\";\nimport {\n CmsResponseTypeDefsImpl,\n CmsQueryTypeDefsImpl,\n CmsMutationTypeDefsImpl\n} from \"~/graphql/schema/cms/typeDefs/index.js\";\nimport {\n QueryCmsResolverImpl,\n MutationCmsResolverImpl,\n GetModelResolverImpl,\n GetEntryResolverImpl,\n ListEntriesResolverImpl,\n CreateEntryResolverImpl,\n UpdateEntryRevisionResolverImpl,\n DeleteEntryRevisionResolverImpl,\n PublishEntryRevisionResolverImpl,\n UnpublishEntryRevisionResolverImpl\n} from \"~/graphql/schema/cms/resolvers/index.js\";\n// Facade wiring (moved here from HeadlessCmsInitializer so the facade can be a lazy DI factory).\nimport { AccessControl } from \"~/crud/AccessControl/AccessControl.js\";\nimport { createModelGroupsCrud } from \"~/crud/contentModelGroup.crud.js\";\nimport { createModelsCrud } from \"~/crud/contentModel.crud.js\";\nimport { createContentEntryCrud } from \"~/crud/contentEntry.crud.js\";\nimport type { ICmsGraphQLSchemaPlugin } from \"~/plugins/index.js\";\nimport {\n CmsGraphQLSchemaPlugin,\n CmsGroupPlugin,\n CmsModelPlugin,\n StorageOperationsCmsModelPlugin\n} from \"~/plugins/index.js\";\nimport { createCmsModelFieldConvertersAttachFactory } from \"~/utils/converters/valueKeyStorageConverter.js\";\nimport { registerFieldConverters } from \"~/fieldConverters/abstractions.js\";\nimport { CmsModelPluginInstance } from \"~/features/contentModel/shared/abstractions.js\";\nimport { CmsGroupPluginInstance } from \"~/features/contentModelGroup/shared/abstractions.js\";\nimport { createExportCrud } from \"~/export/index.js\";\nimport { createImportCrud } from \"~/export/crud/importing.js\";\nimport { getSchema } from \"~/graphql/getSchema.js\";\nimport { createBaseSchemaPlugins } from \"~/graphql/schema/baseSchema.js\";\nimport { exportPlugin } from \"~/export/graphql/index.js\";\nimport { CoreGraphQLSchemaFactory } from \"@webiny/api-graphql/graphql/abstractions.js\";\nimport { CmsGraphQLSchemaFactory } from \"~/graphql/CmsGraphQLSchemaFactory.js\";\nimport { CmsExport, CmsImport } from \"~/export/abstractions.js\";\nimport { ListGroupsUseCase } from \"~/features/contentModelGroup/ListGroups/index.js\";\nimport { RevisionIdScalar } from \"~/graphql/scalars/RevisionId.js\";\nimport {\n AccessControl as AccessControlAbstraction,\n CmsContext as CmsContextAbstraction,\n CmsStorageModelProvider,\n HeadlessCms\n} from \"~/features/shared/abstractions.js\";\n\nimport {\n EntryFromStorageTransform,\n EntryToStorageTransform,\n PluginsContainer as PluginsContainerAbstraction,\n SearchableFieldsProvider\n} from \"~/legacy/abstractions.js\";\nimport { entryFromStorageTransform, entryToStorageTransform } from \"~/utils/entryStorage.js\";\nimport { getSearchableFields } from \"~/crud/contentEntry/searchableFields.js\";\n\nexport interface HeadlessCmsConfig {\n type: ApiEndpoint;\n /** Extra plugins (e.g. CmsGraphQLSchemaPlugin) to register in ctx.plugins at runtime. */\n extraPlugins?: any[];\n}\n\nexport const HeadlessCmsFeature = createFeature<HeadlessCmsConfig>({\n name: \"HeadlessCms\",\n register(container, config) {\n const { type } = config;\n\n // Pre-register the CMS SDK namespace schema (Query.cms / Mutation.cms) so it is\n // available when GraphQLSchemaComposer is constructed (before context enhancement).\n // All these implementations have zero DI dependencies and are safe to register early.\n container.register(CmsBaseErrorTypeFactory); // CmsError must come first\n container.register(CmsResponseTypeDefsImpl);\n container.register(CmsQueryTypeDefsImpl);\n container.register(CmsMutationTypeDefsImpl);\n container.register(QueryCmsResolverImpl);\n container.register(MutationCmsResolverImpl);\n container.register(GetModelResolverImpl);\n container.register(GetEntryResolverImpl);\n container.register(ListEntriesResolverImpl);\n container.register(CreateEntryResolverImpl);\n container.register(UpdateEntryRevisionResolverImpl);\n container.register(DeleteEntryRevisionResolverImpl);\n container.register(PublishEntryRevisionResolverImpl);\n container.register(UnpublishEntryRevisionResolverImpl);\n\n container.registerInstance(HeadlessCmsEndpointConfig, {\n type: config.type\n });\n\n // Register CMS DI features statically so they are available before any enhancers run.\n // All these are pure class registrations (no eager instantiation) so they are safe\n // to register here before any request-time context is available.\n CompressionFeature.register(container);\n GraphQLFeature.register(container);\n ValidationFeature.register(container);\n StorageFeature.register(container);\n CmsInstallerFeature.register(container);\n ContentEntriesFeature.register(container);\n ContentModelFeature.register(container);\n CmsAiToolsFeature.register(container);\n ContentModelGroupFeature.register(container);\n ModelBuilderFeature.register(container);\n CmsWhereMapperFeature.register(container);\n CmsSortMapperFeature.register(container);\n CmsWebhooksFeature.register(container);\n\n // ============================================================================\n // Synchronous per-request wiring (moved out of HeadlessCmsInitializer.init).\n // register() runs per request, pre-auth — correct for pure wiring and closures.\n // ============================================================================\n\n // Field value converters are resolved from the DI container.\n registerFieldConverters(container);\n\n // PluginsContainer still carries legacy extension plugins (e.g. CmsGraphQLSchemaPlugin)\n // until those remaining consumers are migrated to DI.\n const pluginsContainer = new PluginsContainer([...(config.extraPlugins ?? [])]);\n container.registerInstance(PluginsContainerAbstraction, pluginsContainer);\n\n // Code-defined model/group plugins are exposed via DI tokens so the\n // Plugin{Models,Groups}Provider can resolve them without the plugins container.\n for (const plugin of pluginsContainer.byType<CmsModelPlugin>(CmsModelPlugin.type)) {\n container.registerInstance(CmsModelPluginInstance, plugin);\n }\n for (const plugin of pluginsContainer.byType<CmsGroupPlugin>(CmsGroupPlugin.type)) {\n container.registerInstance(CmsGroupPluginInstance, plugin);\n }\n\n // User-provided GraphQL schema extension plugins (added via extraPlugins) are bridged\n // to the CmsGraphQLSchemaFactory DI token so generateSchema includes them.\n const userSchemaPlugins = pluginsContainer.byType<ICmsGraphQLSchemaPlugin>(\n CmsGraphQLSchemaPlugin.type\n );\n if (userSchemaPlugins.length > 0) {\n container.registerInstance(CmsGraphQLSchemaFactory, {\n execute: () => userSchemaPlugins\n });\n }\n\n // RegisterExtensionPlugins supplied via extraPlugins (test infra) only do DI registration\n // via their apply(). Apply them here at register() time — matching the app's registerExtensions\n // and the storage presets above — so code-defined models are present before per-request model\n // listing runs.\n for (const plugin of config.extraPlugins ?? []) {\n if (plugin && typeof (plugin as any).apply === \"function\") {\n (plugin as any).apply({ container });\n }\n }\n\n const benchmark = new Benchmark();\n container.registerInstance(BenchmarkAbstraction, benchmark);\n\n // The CmsContext \"shim\": the request-scoped context object the facade builders, transforms\n // and getSchema operate on. They only read `.container` (+ plugins/benchmark), so this is\n // all they need — there is no legacy bag.\n const cmsContext = {\n container,\n plugins: pluginsContainer,\n benchmark\n } as unknown as CmsContext;\n container.registerInstance(CmsContextAbstraction, cmsContext);\n\n container.registerInstance(CoreGraphQLSchemaFactory, {\n execute: async builder => {\n builder.addTypeDefs(\"scalar RevisionId\");\n builder.addLegacyResolvers({ RevisionId: RevisionIdScalar });\n return builder;\n }\n });\n\n container.registerInstance(\n CmsStorageModelProvider,\n new StorageOperationsCmsModelPlugin(\n createCmsModelFieldConvertersAttachFactory(cmsContext)\n )\n );\n\n // Entry storage operations are registered by each adapter's feature at app-scope.\n // HeadlessCmsFeature no longer manages entry storage registration.\n\n const identityContext = container.resolve(IdentityContext);\n const tenantContext = container.resolve(TenantContext);\n const getTenant = () => tenantContext.getTenant();\n\n // AccessControl is identity-dependent; build it lazily and memoise per request container.\n let accessControlInstance: AccessControl | undefined;\n const getAccessControl = (): AccessControl => {\n if (!accessControlInstance) {\n accessControlInstance = new AccessControl({\n getIdentity: async () => identityContext.getIdentity(),\n getGroupsPermissions: () =>\n identityContext.getPermissions(\"cms.contentModelGroup\"),\n getModelsPermissions: () => identityContext.getPermissions(\"cms.contentModel\"),\n getEntriesPermissions: () => identityContext.getPermissions(\"cms.contentEntry\"),\n listAllGroups: async () => {\n const result = await identityContext.withoutAuthorization(() =>\n container.resolve(ListGroupsUseCase).execute()\n );\n if (result.isFail()) {\n throw result.error;\n }\n return result.value;\n }\n });\n }\n return accessControlInstance;\n };\n container.registerFactory(AccessControlAbstraction, () => getAccessControl());\n\n // The HeadlessCms facade — a LAZY factory built on first resolve (post-auth), memoised per\n // request container.\n let cmsFacade: HeadlessCms.Interface | undefined;\n container.registerFactory(HeadlessCms, () => {\n if (!cmsFacade) {\n cmsFacade = {\n type,\n READ: type === \"read\",\n PREVIEW: type === \"preview\",\n MANAGE: type === \"manage\",\n accessControl: getAccessControl(),\n ...createModelGroupsCrud({ context: cmsContext }),\n ...createModelsCrud({ context: cmsContext }),\n ...createContentEntryCrud({ context: cmsContext }),\n export: { ...createExportCrud(cmsContext) },\n importing: { ...createImportCrud(cmsContext) }\n } as HeadlessCms.Interface;\n }\n return cmsFacade;\n });\n container.registerFactory(CmsExport, () => container.resolve(HeadlessCms).export);\n container.registerFactory(CmsImport, () => container.resolve(HeadlessCms).importing);\n\n // Register CmsSchemaExecutor so proxy resolvers can build and execute the CMS sub-schema.\n container.registerInstance(CmsSchemaExecutor, {\n execute: async (schemaType: ApiEndpoint, body: any) => {\n const bm = container.resolve(BenchmarkAbstraction);\n const schema = await bm.measure(\"headlessCms.graphql.getSchema\", () =>\n identityContext.withoutAuthorization(() =>\n getSchema({ context: cmsContext, getTenant, type: schemaType })\n )\n );\n const requestBody = await bm.measure(\n \"headlessCms.graphql.createRequestBody\",\n async () => createRequestBody(body)\n );\n return bm.measure(\"headlessCms.graphql.processRequestBody\", () =>\n processRequestBody(requestBody, schema, cmsContext)\n );\n }\n });\n\n // Register CMS sub-schema factories: base types (CmsError, CmsIdentity, etc.)\n // and, for manage endpoints, the import/export operations.\n container.registerInstance(CmsGraphQLSchemaFactory, {\n execute: () => createBaseSchemaPlugins(cmsContext)\n });\n if (type === \"manage\") {\n container.registerInstance(CmsGraphQLSchemaFactory, {\n execute: () => [exportPlugin]\n });\n }\n\n container.registerInstance(EntryToStorageTransform, (model, entry) => {\n return entryToStorageTransform(cmsContext, model, entry);\n });\n container.registerInstance(EntryFromStorageTransform, (model, entry) => {\n return entryFromStorageTransform(cmsContext, model, entry);\n });\n container.registerInstance(SearchableFieldsProvider, params => {\n return getSearchableFields({\n context: cmsContext,\n fields: params.fields,\n input: []\n });\n });\n\n container.register(createCmsRoute(config.type));\n }\n});\n"],"names":["HeadlessCmsFeature","createFeature","container","config","type","CmsBaseErrorTypeFactory","CmsResponseTypeDefsImpl","CmsQueryTypeDefsImpl","CmsMutationTypeDefsImpl","QueryCmsResolverImpl","MutationCmsResolverImpl","GetModelResolverImpl","GetEntryResolverImpl","ListEntriesResolverImpl","CreateEntryResolverImpl","UpdateEntryRevisionResolverImpl","DeleteEntryRevisionResolverImpl","PublishEntryRevisionResolverImpl","UnpublishEntryRevisionResolverImpl","HeadlessCmsEndpointConfig","CompressionFeature","GraphQLFeature","ValidationFeature","StorageFeature","CmsInstallerFeature","ContentEntriesFeature","ContentModelFeature","CmsAiToolsFeature","ContentModelGroupFeature","ModelBuilderFeature","CmsWhereMapperFeature","CmsSortMapperFeature","CmsWebhooksFeature","registerFieldConverters","pluginsContainer","PluginsContainer","PluginsContainerAbstraction","plugin","CmsModelPlugin","CmsModelPluginInstance","CmsGroupPlugin","CmsGroupPluginInstance","userSchemaPlugins","CmsGraphQLSchemaPlugin","CmsGraphQLSchemaFactory","benchmark","Benchmark","BenchmarkAbstraction","cmsContext","CmsContextAbstraction","CoreGraphQLSchemaFactory","builder","RevisionIdScalar","CmsStorageModelProvider","StorageOperationsCmsModelPlugin","createCmsModelFieldConvertersAttachFactory","identityContext","IdentityContext","tenantContext","TenantContext","getTenant","accessControlInstance","getAccessControl","AccessControl","result","ListGroupsUseCase","AccessControlAbstraction","cmsFacade","HeadlessCms","createModelGroupsCrud","createModelsCrud","createContentEntryCrud","createExportCrud","createImportCrud","CmsExport","CmsImport","CmsSchemaExecutor","schemaType","body","bm","schema","getSchema","requestBody","createRequestBody","processRequestBody","createBaseSchemaPlugins","exportPlugin","EntryToStorageTransform","model","entry","entryToStorageTransform","EntryFromStorageTransform","entryFromStorageTransform","SearchableFieldsProvider","params","getSearchableFields","createCmsRoute"],"mappings":"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"}
@@ -4,18 +4,23 @@ import type { IGraphQLContextualSchema } from "@webiny/api-graphql";
4
4
  import type { ApiEndpoint } from "./types/index.js";
5
5
  /**
6
6
  * The HTTP route for a CMS GraphQL endpoint (manage/read/preview). Per request it runs the
7
- * contextual schemas, then executes the CMS sub-schema via CmsSchemaExecutor. The post-auth
8
- * RequestContextInitializers are run once per request by the HTTP layer
9
- * (RequestContextInitializerDecorator) before the router dispatches, so they cover every route.
7
+ * contextual schemas, then executes the CMS sub-schema via CmsSchemaExecutor.
10
8
  */
11
9
  export declare function createCmsRoute(type: ApiEndpoint): {
12
- new (container: Container, contextualSchemas: IGraphQLContextualSchema[]): {
10
+ new (): {
11
+ readonly name: string;
13
12
  readonly method: "POST";
14
13
  readonly path: string;
15
- container: Container;
16
- contextualSchemas: IGraphQLContextualSchema[];
17
- handle(request: IHttpRequest): Promise<IHttpResponse>;
14
+ readonly handler: {
15
+ new (container: Container, contextualSchemas: IGraphQLContextualSchema[]): {
16
+ container: Container;
17
+ contextualSchemas: IGraphQLContextualSchema[];
18
+ handle(request: IHttpRequest): Promise<IHttpResponse>;
19
+ };
20
+ } & {
21
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/event-handler-core").IHttpRoute>;
22
+ };
18
23
  };
19
24
  } & {
20
- __abstraction: import("@webiny/di").Abstraction<import("@webiny/event-handler-core").IHttpRoute>;
25
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/event-handler-core").IHttpRouteDefinition>;
21
26
  };
package/createCmsRoute.js CHANGED
@@ -1,4 +1,4 @@
1
- import { HttpRoute, RequestContainer } from "@webiny/event-handler-core";
1
+ import { HttpRouteDefinition, HttpRouteHandler, RequestContainer } from "@webiny/event-handler-core";
2
2
  import { GraphQLContextualSchema } from "@webiny/api-graphql";
3
3
  import { BenchmarkAbstraction } from "@webiny/api";
4
4
  import { CmsSchemaExecutor } from "./graphql/CmsSchemaExecutor.js";
@@ -12,8 +12,6 @@ function createCmsRoute(type) {
12
12
  constructor(container, contextualSchemas){
13
13
  this.container = container;
14
14
  this.contextualSchemas = contextualSchemas;
15
- this.method = "POST";
16
- this.path = CMS_PATHS[type];
17
15
  }
18
16
  async handle(request) {
19
17
  const ctx = {
@@ -31,7 +29,7 @@ function createCmsRoute(type) {
31
29
  };
32
30
  }
33
31
  }
34
- return HttpRoute.createImplementation({
32
+ const implementation = HttpRouteHandler.createImplementation({
35
33
  implementation: CmsGraphQLRoute,
36
34
  dependencies: [
37
35
  RequestContainer,
@@ -43,6 +41,18 @@ function createCmsRoute(type) {
43
41
  ]
44
42
  ]
45
43
  });
44
+ class CmsRouteDefinition {
45
+ constructor(){
46
+ this.name = `cms-${type}`;
47
+ this.method = "POST";
48
+ this.path = CMS_PATHS[type];
49
+ this.handler = implementation;
50
+ }
51
+ }
52
+ return HttpRouteDefinition.createImplementation({
53
+ implementation: CmsRouteDefinition,
54
+ dependencies: []
55
+ });
46
56
  }
47
57
  export { createCmsRoute };
48
58
 
@@ -1 +1 @@
1
- {"version":3,"file":"createCmsRoute.js","sources":["../src/createCmsRoute.ts"],"sourcesContent":["import type { Container } from \"@webiny/di\";\nimport { HttpRoute, RequestContainer } from \"@webiny/event-handler-core\";\nimport type { IHttpRequest, IHttpResponse } from \"@webiny/event-handler-core\";\nimport { GraphQLContextualSchema } from \"@webiny/api-graphql\";\nimport type { IGraphQLContextualSchema } from \"@webiny/api-graphql\";\nimport { BenchmarkAbstraction } from \"@webiny/api\";\nimport { CmsSchemaExecutor } from \"~/graphql/CmsSchemaExecutor.js\";\nimport type { ApiEndpoint } from \"~/types/index.js\";\n\nconst CMS_PATHS: Record<ApiEndpoint, string> = {\n manage: \"/cms/manage\",\n read: \"/cms/read\",\n preview: \"/cms/preview\"\n};\n\n/**\n * The HTTP route for a CMS GraphQL endpoint (manage/read/preview). Per request it runs the\n * contextual schemas, then executes the CMS sub-schema via CmsSchemaExecutor. The post-auth\n * RequestContextInitializers are run once per request by the HTTP layer\n * (RequestContextInitializerDecorator) before the router dispatches, so they cover every route.\n */\nexport function createCmsRoute(type: ApiEndpoint) {\n class CmsGraphQLRoute implements HttpRoute.Interface {\n readonly method = \"POST\";\n readonly path = CMS_PATHS[type];\n\n // public (not private): this class is returned from an exported factory, so its members\n // must be declarable in the emitted .d.ts — private parameter-properties on an exported\n // anonymous class type are a TS4094 error.\n constructor(\n public container: Container,\n public contextualSchemas: IGraphQLContextualSchema[]\n ) {}\n\n async handle(request: IHttpRequest): Promise<IHttpResponse> {\n const ctx: Record<string, any> = { container: this.container };\n for (const schema of this.contextualSchemas) {\n await schema.build(ctx);\n }\n const result = await this.container\n .resolve(CmsSchemaExecutor)\n .execute(type, request.body);\n // Flush benchmark measurements (no-op unless benchmarking was enabled for the request).\n await this.container.resolve(BenchmarkAbstraction).output();\n return {\n statusCode: 200,\n headers: { \"Content-Type\": \"application/json\" },\n body: result\n };\n }\n }\n\n return HttpRoute.createImplementation({\n implementation: CmsGraphQLRoute,\n dependencies: [RequestContainer, [GraphQLContextualSchema, { multiple: true }]]\n });\n}\n"],"names":["CMS_PATHS","createCmsRoute","type","CmsGraphQLRoute","container","contextualSchemas","request","ctx","schema","result","CmsSchemaExecutor","BenchmarkAbstraction","HttpRoute","RequestContainer","GraphQLContextualSchema"],"mappings":";;;;AASA,MAAMA,YAAyC;IAC3C,QAAQ;IACR,MAAM;IACN,SAAS;AACb;AAQO,SAASC,eAAeC,IAAiB;IAC5C,MAAMC;QAOF,YACWC,SAAoB,EACpBC,iBAA6C,CACtD;iBAFSD,SAAS,GAATA;iBACAC,iBAAiB,GAAjBA;iBARF,MAAM,GAAG;iBACT,IAAI,GAAGL,SAAS,CAACE,KAAK;QAQ5B;QAEH,MAAM,OAAOI,OAAqB,EAA0B;YACxD,MAAMC,MAA2B;gBAAE,WAAW,IAAI,CAAC,SAAS;YAAC;YAC7D,KAAK,MAAMC,UAAU,IAAI,CAAC,iBAAiB,CACvC,MAAMA,OAAO,KAAK,CAACD;YAEvB,MAAME,SAAS,MAAM,IAAI,CAAC,SAAS,CAC9B,OAAO,CAACC,mBACR,OAAO,CAACR,MAAMI,QAAQ,IAAI;YAE/B,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAACK,sBAAsB,MAAM;YACzD,OAAO;gBACH,YAAY;gBACZ,SAAS;oBAAE,gBAAgB;gBAAmB;gBAC9C,MAAMF;YACV;QACJ;IACJ;IAEA,OAAOG,UAAU,oBAAoB,CAAC;QAClC,gBAAgBT;QAChB,cAAc;YAACU;YAAkB;gBAACC;gBAAyB;oBAAE,UAAU;gBAAK;aAAE;SAAC;IACnF;AACJ"}
1
+ {"version":3,"file":"createCmsRoute.js","sources":["../src/createCmsRoute.ts"],"sourcesContent":["import type { Container } from \"@webiny/di\";\nimport {\n HttpRouteDefinition,\n HttpRouteHandler,\n RequestContainer\n} from \"@webiny/event-handler-core\";\nimport type { IHttpRequest, IHttpResponse } from \"@webiny/event-handler-core\";\nimport { GraphQLContextualSchema } from \"@webiny/api-graphql\";\nimport type { IGraphQLContextualSchema } from \"@webiny/api-graphql\";\nimport { BenchmarkAbstraction } from \"@webiny/api\";\nimport { CmsSchemaExecutor } from \"~/graphql/CmsSchemaExecutor.js\";\nimport type { ApiEndpoint } from \"~/types/index.js\";\n\nconst CMS_PATHS: Record<ApiEndpoint, string> = {\n manage: \"/cms/manage\",\n read: \"/cms/read\",\n preview: \"/cms/preview\"\n};\n\n/**\n * The HTTP route for a CMS GraphQL endpoint (manage/read/preview). Per request it runs the\n * contextual schemas, then executes the CMS sub-schema via CmsSchemaExecutor.\n */\nexport function createCmsRoute(type: ApiEndpoint) {\n class CmsGraphQLRoute implements HttpRouteHandler.Interface {\n // public (not private): this class is returned from an exported factory, so its members\n // must be declarable in the emitted .d.ts — private parameter-properties on an exported\n // anonymous class type are a TS4094 error.\n constructor(\n public container: Container,\n public contextualSchemas: IGraphQLContextualSchema[]\n ) {}\n\n async handle(request: IHttpRequest): Promise<IHttpResponse> {\n const ctx: Record<string, any> = { container: this.container };\n for (const schema of this.contextualSchemas) {\n await schema.build(ctx);\n }\n const result = await this.container\n .resolve(CmsSchemaExecutor)\n .execute(type, request.body);\n // Flush benchmark measurements (no-op unless benchmarking was enabled for the request).\n await this.container.resolve(BenchmarkAbstraction).output();\n return {\n statusCode: 200,\n headers: { \"Content-Type\": \"application/json\" },\n body: result\n };\n }\n }\n\n const implementation = HttpRouteHandler.createImplementation({\n implementation: CmsGraphQLRoute,\n dependencies: [RequestContainer, [GraphQLContextualSchema, { multiple: true }]]\n });\n\n class CmsRouteDefinition implements HttpRouteDefinition.Interface {\n readonly name = `cms-${type}`;\n readonly method = \"POST\";\n readonly path = CMS_PATHS[type];\n readonly handler = implementation;\n }\n\n return HttpRouteDefinition.createImplementation({\n implementation: CmsRouteDefinition,\n dependencies: []\n });\n}\n"],"names":["CMS_PATHS","createCmsRoute","type","CmsGraphQLRoute","container","contextualSchemas","request","ctx","schema","result","CmsSchemaExecutor","BenchmarkAbstraction","implementation","HttpRouteHandler","RequestContainer","GraphQLContextualSchema","CmsRouteDefinition","HttpRouteDefinition"],"mappings":";;;;AAaA,MAAMA,YAAyC;IAC3C,QAAQ;IACR,MAAM;IACN,SAAS;AACb;AAMO,SAASC,eAAeC,IAAiB;IAC5C,MAAMC;QAIF,YACWC,SAAoB,EACpBC,iBAA6C,CACtD;iBAFSD,SAAS,GAATA;iBACAC,iBAAiB,GAAjBA;QACR;QAEH,MAAM,OAAOC,OAAqB,EAA0B;YACxD,MAAMC,MAA2B;gBAAE,WAAW,IAAI,CAAC,SAAS;YAAC;YAC7D,KAAK,MAAMC,UAAU,IAAI,CAAC,iBAAiB,CACvC,MAAMA,OAAO,KAAK,CAACD;YAEvB,MAAME,SAAS,MAAM,IAAI,CAAC,SAAS,CAC9B,OAAO,CAACC,mBACR,OAAO,CAACR,MAAMI,QAAQ,IAAI;YAE/B,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAACK,sBAAsB,MAAM;YACzD,OAAO;gBACH,YAAY;gBACZ,SAAS;oBAAE,gBAAgB;gBAAmB;gBAC9C,MAAMF;YACV;QACJ;IACJ;IAEA,MAAMG,iBAAiBC,iBAAiB,oBAAoB,CAAC;QACzD,gBAAgBV;QAChB,cAAc;YAACW;YAAkB;gBAACC;gBAAyB;oBAAE,UAAU;gBAAK;aAAE;SAAC;IACnF;IAEA,MAAMC;;iBACO,IAAI,GAAG,CAAC,IAAI,EAAEd,MAAM;iBACpB,MAAM,GAAG;iBACT,IAAI,GAAGF,SAAS,CAACE,KAAK;iBACtB,OAAO,GAAGU;;IACvB;IAEA,OAAOK,oBAAoB,oBAAoB,CAAC;QAC5C,gBAAgBD;QAChB,cAAc,EAAE;IACpB;AACJ"}
@@ -33,6 +33,29 @@ const validatePredefinedValue = (field, value)=>{
33
33
  for (const predefinedValue of predefinedValues)if (predefinedValue.value == value) return null;
34
34
  return "Value sent does not match any of the available predefined values.";
35
35
  };
36
+ const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
37
+ const TIME_RE = /^\d{2}:\d{2}(:\d{2})?$/;
38
+ const DATETIME_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/;
39
+ const validateDatetimeFormat = (field, value)=>{
40
+ if ("datetime" !== field.type) return null;
41
+ if (null == value || "" === value) return null;
42
+ if ("string" != typeof value) return null;
43
+ const dateType = field.settings?.type;
44
+ switch(dateType){
45
+ case "date":
46
+ if (!DATE_RE.test(value)) return `Invalid date format for field "${field.fieldId}". Expected YYYY-MM-DD.`;
47
+ return null;
48
+ case "time":
49
+ if (!TIME_RE.test(value)) return `Invalid time format for field "${field.fieldId}". Expected HH:mm or HH:mm:ss.`;
50
+ return null;
51
+ case "dateTimeWithTimezone":
52
+ case "dateTimeWithoutTimezone":
53
+ if (!DATETIME_RE.test(value)) return `Invalid dateTime format for field "${field.fieldId}". Expected ISO 8601 dateTime.`;
54
+ return null;
55
+ default:
56
+ return null;
57
+ }
58
+ };
36
59
  const getFieldValidation = (listValidation)=>{
37
60
  if (!listValidation?.length) return [];
38
61
  return listValidation.filter((item)=>"dynamicZone" !== item.name);
@@ -44,6 +67,8 @@ const runFieldMultipleValuesValidations = async (params)=>{
44
67
  if (valuesError) return valuesError;
45
68
  if (null == values) return null;
46
69
  for (const value of values){
70
+ const datetimeError = validateDatetimeFormat(field, value);
71
+ if (datetimeError) return datetimeError;
47
72
  const valueError = await validateValue(params, getFieldValidation(field.validation), value);
48
73
  if (valueError) return valueError;
49
74
  const predefinedValueError = validatePredefinedValue(field, value);
@@ -54,6 +79,8 @@ const runFieldMultipleValuesValidations = async (params)=>{
54
79
  const runFieldValueValidations = async (params)=>{
55
80
  const { values, field } = params;
56
81
  const value = values[field.fieldId];
82
+ const datetimeError = validateDatetimeFormat(field, value);
83
+ if (datetimeError) return datetimeError;
57
84
  const error = await validateValue(params, field.validation || [], value);
58
85
  if (error) return error;
59
86
  return validatePredefinedValue(field, value);
@@ -1 +1 @@
1
- {"version":3,"file":"crud/contentEntry/entryDataValidation.js","sources":["../../../src/crud/contentEntry/entryDataValidation.ts"],"sourcesContent":["import type {\n CmsContext,\n CmsDynamicZoneTemplate,\n CmsEntry,\n CmsEntryValues,\n CmsModel,\n CmsModelField,\n CmsModelFieldValidation\n} from \"~/types/index.js\";\nimport { EntryValidationError } from \"~/domain/contentEntry/errors.js\";\nimport {\n type CmsModelFieldValidator,\n CmsModelFieldValidatorRegistry\n} from \"~/features/validation/index.js\";\n\ntype PluginValidationCallable = (\n params: CmsModelFieldValidator.Params\n) => CmsModelFieldValidator.Response;\ntype PluginValidationList = Record<string, PluginValidationCallable[]>;\n\ninterface ExecuteValidationParams<TValues extends CmsEntryValues = CmsEntryValues> {\n validatorList: PluginValidationList;\n field: CmsModelField;\n model: CmsModel;\n values: TValues;\n context: CmsContext;\n entry?: CmsEntry<TValues>;\n}\n\ntype PossibleValue = boolean | number | string | null | undefined;\n\nconst validateValue = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: ExecuteValidationParams<TValues>,\n fieldValidators: CmsModelFieldValidation[],\n value: PossibleValue | PossibleValue[]\n): Promise<string | null> => {\n if (!fieldValidators) {\n return null;\n }\n const { validatorList, context, field, model, entry } = params;\n try {\n for (const fieldValidator of fieldValidators) {\n const name = fieldValidator.name;\n const validations = validatorList[name];\n if (!validations || validations.length === 0) {\n return `There are no \"${name}\" validators defined.`;\n }\n for (const validate of validations) {\n const result = await validate({\n value,\n context,\n validator: fieldValidator,\n field,\n model,\n entry\n });\n if (!result) {\n return fieldValidator.message;\n }\n }\n }\n } catch (ex) {\n return ex.message;\n }\n\n return null;\n};\n\nconst validatePredefinedValue = (field: CmsModelField, value: any | any[]): string | null => {\n const { enabled = false, values: predefinedValues = [] } = field.predefinedValues || {};\n if (!enabled) {\n return null;\n } else if (Array.isArray(predefinedValues) === false || predefinedValues.length === 0) {\n return \"Missing predefined values to validate against.\";\n } else if (value === \"\" || value === null || value === undefined) {\n return null;\n }\n for (const predefinedValue of predefinedValues) {\n /**\n * No strict compare because the value sent can be 12345 (number) and predefinedValue can be \"12345\" (string),\n * and we want it to match.\n */\n if (predefinedValue.value == value) {\n return null;\n }\n }\n return \"Value sent does not match any of the available predefined values.\";\n};\n\nconst getFieldValidation = (\n listValidation?: CmsModelFieldValidation[]\n): CmsModelFieldValidation[] => {\n if (!listValidation?.length) {\n return [];\n }\n return listValidation.filter(item => item.name !== \"dynamicZone\");\n};\n/**\n * When multiple values is selected we must run validations on the array containing the values\n * And then on each value in the array\n */\nconst runFieldMultipleValuesValidations = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: ExecuteValidationParams<TValues>\n): Promise<string | null> => {\n const { field, values: initialValues } = params;\n const values = initialValues[field.fieldId as keyof TValues] as\n | PossibleValue[]\n | null\n | undefined;\n const valuesError = await validateValue(\n params,\n getFieldValidation(field.listValidation),\n values\n );\n if (valuesError) {\n return valuesError;\n }\n if (values === null || values === undefined) {\n return null;\n }\n for (const value of values) {\n const valueError = await validateValue(params, getFieldValidation(field.validation), value);\n if (valueError) {\n return valueError;\n }\n const predefinedValueError = validatePredefinedValue(field, value);\n if (predefinedValueError) {\n return predefinedValueError;\n }\n }\n return null;\n};\n/**\n * Runs validation on given value.\n */\nconst runFieldValueValidations = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: ExecuteValidationParams<TValues>\n): Promise<string | null> => {\n const { values, field } = params;\n const value = values[field.fieldId as keyof TValues];\n const error = await validateValue(params, field.validation || [], value);\n if (error) {\n return error;\n }\n return validatePredefinedValue(field, value);\n};\n\nconst execValidation = async (params: ExecuteValidationParams): Promise<string | null> => {\n const { field } = params;\n if (field.list) {\n return await runFieldMultipleValuesValidations(params);\n }\n return await runFieldValueValidations(params);\n};\n\ninterface IValidateModelEntryDataParams<TValues extends CmsEntryValues = CmsEntryValues> {\n context: CmsContext;\n model: CmsModel;\n values: TValues;\n entry?: CmsEntry<TValues>;\n skipValidation?: boolean;\n}\n\nexport const validateModelEntryData = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: IValidateModelEntryDataParams<TValues>\n) => {\n const { context, model, entry, values, skipValidation } = params;\n\n if (skipValidation) {\n return [];\n }\n\n const validatorList: PluginValidationList = {};\n const registry = context.container.resolve(CmsModelFieldValidatorRegistry);\n const validators = registry.getAll();\n for (const validator of validators) {\n const name = validator.name;\n if (!validatorList[name]) {\n validatorList[name] = [];\n }\n validatorList[name].push(params => {\n return validator.validate(params);\n });\n }\n\n return await validate<TValues>({\n validatorList,\n context,\n model,\n entry,\n parents: [],\n fields: model.fields,\n values: {\n ...entry?.values,\n ...values\n }\n });\n};\n\nexport const validateModelEntryDataOrThrow = async <\n TValues extends CmsEntryValues = CmsEntryValues\n>(\n params: IValidateModelEntryDataParams<TValues>\n) => {\n const invalidFields = await validateModelEntryData(params);\n if (invalidFields.length === 0) {\n return;\n }\n throw new EntryValidationError(\"Validation failed.\", invalidFields);\n};\n\n/**\n *\n */\ninterface FieldError {\n id: string;\n fieldId: string;\n storageId: string;\n error: any;\n parents: string[];\n}\n\ninterface ValidateFieldParams<TValues extends CmsEntryValues = CmsEntryValues> {\n validatorList: PluginValidationList;\n parents: string[];\n model: CmsModel;\n values: TValues;\n context: CmsContext;\n field: CmsModelField;\n entry?: CmsEntry<TValues>;\n}\n\nconst executeFieldValidation = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: ValidateFieldParams<TValues>\n): Promise<FieldError[]> => {\n // TODO put per-field validation into plugins.\n const { field } = params;\n /**\n * Object field.\n */\n if (field.type === \"object\") {\n const fields = field.settings?.fields;\n if (!Array.isArray(fields)) {\n return [];\n }\n const validations: FieldError[] = [];\n /**\n * We need to validate the object field as well.\n */\n const error = await execValidation({\n ...params,\n field\n });\n if (error) {\n validations.push({\n id: field.id,\n fieldId: field.fieldId,\n storageId: field.storageId,\n error,\n parents: params.parents\n });\n }\n const objectValue = params.values[field.fieldId as keyof TValues];\n if (!objectValue) {\n return validations;\n }\n const values = (Array.isArray(objectValue) ? objectValue : [objectValue]) as TValues[];\n for (const index in values) {\n const parents = field.list ? [field.fieldId, index] : [field.fieldId];\n const value = values[index] as TValues;\n for (const childField of fields) {\n const errors = await executeFieldValidation<typeof value>({\n ...params,\n parents: params.parents.concat(parents),\n field: childField,\n values: value\n });\n if (errors.length === 0) {\n continue;\n }\n validations.push(...errors);\n }\n }\n return validations;\n }\n /**\n * Dynamic Zone Field\n */\n //\n else if (field.type === \"dynamicZone\") {\n const validations: FieldError[] = [];\n\n const error = await execValidation({\n ...params,\n field\n });\n if (error) {\n validations.push({\n id: field.id,\n fieldId: field.fieldId,\n storageId: field.storageId,\n error,\n parents: params.parents\n });\n }\n\n const templates = (field.settings?.templates || []) as CmsDynamicZoneTemplate[];\n for (const template of templates) {\n const fields = template.fields;\n const fieldData = params.values[field.fieldId as keyof TValues];\n if (!fieldData) {\n continue;\n }\n const values: TValues[keyof TValues][] = Array.isArray(fieldData)\n ? fieldData\n : [fieldData];\n for (const index in values) {\n const templateValue = values[index]?.[template.gqlTypeName];\n if (!templateValue) {\n continue;\n }\n /**\n * Order of the parents must be\n * - fieldId\n * - index (if multiple values)\n * - gqlTypeName\n */\n const parents = [field.fieldId];\n if (field.list) {\n parents.push(index);\n }\n parents.push(template.gqlTypeName);\n for (const childField of fields) {\n const errors = await executeFieldValidation({\n ...params,\n parents: params.parents.concat(parents),\n field: childField,\n values: templateValue\n });\n if (errors.length === 0) {\n continue;\n }\n validations.push(...errors);\n }\n }\n }\n\n return validations;\n }\n const error = await execValidation({\n ...params\n });\n if (!error) {\n return [];\n }\n return [\n {\n id: field.id,\n fieldId: field.fieldId,\n storageId: field.storageId,\n error,\n parents: params.parents\n }\n ];\n};\n\ninterface ValidateFieldsParams<TValues extends CmsEntryValues = CmsEntryValues> {\n validatorList: PluginValidationList;\n parents: string[];\n model: CmsModel;\n values: TValues;\n fields: CmsModelField[];\n context: CmsContext;\n entry?: CmsEntry<TValues>;\n}\n\nconst validate = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: ValidateFieldsParams<TValues>\n): Promise<FieldError[]> => {\n const { fields } = params;\n const errors: FieldError[] = [];\n\n const results = await Promise.all(\n fields.map(async field => {\n return await executeFieldValidation<TValues>({\n ...params,\n field\n });\n })\n );\n\n for (const result of results) {\n if (result.length === 0) {\n continue;\n }\n errors.push(...result);\n }\n return errors;\n};\n"],"names":["validateValue","params","fieldValidators","value","validatorList","context","field","model","entry","fieldValidator","name","validations","validate","result","ex","validatePredefinedValue","enabled","predefinedValues","Array","predefinedValue","getFieldValidation","listValidation","item","runFieldMultipleValuesValidations","initialValues","values","valuesError","valueError","predefinedValueError","runFieldValueValidations","error","execValidation","validateModelEntryData","skipValidation","registry","CmsModelFieldValidatorRegistry","validators","validator","validateModelEntryDataOrThrow","invalidFields","EntryValidationError","executeFieldValidation","fields","objectValue","index","parents","childField","errors","templates","template","fieldData","templateValue","results","Promise"],"mappings":"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"}
1
+ {"version":3,"file":"crud/contentEntry/entryDataValidation.js","sources":["../../../src/crud/contentEntry/entryDataValidation.ts"],"sourcesContent":["import type {\n CmsContext,\n CmsDynamicZoneTemplate,\n CmsEntry,\n CmsEntryValues,\n CmsModel,\n CmsModelField,\n CmsModelFieldValidation\n} from \"~/types/index.js\";\nimport { EntryValidationError } from \"~/domain/contentEntry/errors.js\";\nimport {\n type CmsModelFieldValidator,\n CmsModelFieldValidatorRegistry\n} from \"~/features/validation/index.js\";\n\ntype PluginValidationCallable = (\n params: CmsModelFieldValidator.Params\n) => CmsModelFieldValidator.Response;\ntype PluginValidationList = Record<string, PluginValidationCallable[]>;\n\ninterface ExecuteValidationParams<TValues extends CmsEntryValues = CmsEntryValues> {\n validatorList: PluginValidationList;\n field: CmsModelField;\n model: CmsModel;\n values: TValues;\n context: CmsContext;\n entry?: CmsEntry<TValues>;\n}\n\ntype PossibleValue = boolean | number | string | null | undefined;\n\nconst validateValue = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: ExecuteValidationParams<TValues>,\n fieldValidators: CmsModelFieldValidation[],\n value: PossibleValue | PossibleValue[]\n): Promise<string | null> => {\n if (!fieldValidators) {\n return null;\n }\n const { validatorList, context, field, model, entry } = params;\n try {\n for (const fieldValidator of fieldValidators) {\n const name = fieldValidator.name;\n const validations = validatorList[name];\n if (!validations || validations.length === 0) {\n return `There are no \"${name}\" validators defined.`;\n }\n for (const validate of validations) {\n const result = await validate({\n value,\n context,\n validator: fieldValidator,\n field,\n model,\n entry\n });\n if (!result) {\n return fieldValidator.message;\n }\n }\n }\n } catch (ex) {\n return ex.message;\n }\n\n return null;\n};\n\nconst validatePredefinedValue = (field: CmsModelField, value: any | any[]): string | null => {\n const { enabled = false, values: predefinedValues = [] } = field.predefinedValues || {};\n if (!enabled) {\n return null;\n } else if (Array.isArray(predefinedValues) === false || predefinedValues.length === 0) {\n return \"Missing predefined values to validate against.\";\n } else if (value === \"\" || value === null || value === undefined) {\n return null;\n }\n for (const predefinedValue of predefinedValues) {\n /**\n * No strict compare because the value sent can be 12345 (number) and predefinedValue can be \"12345\" (string),\n * and we want it to match.\n */\n if (predefinedValue.value == value) {\n return null;\n }\n }\n return \"Value sent does not match any of the available predefined values.\";\n};\n\nconst DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst TIME_RE = /^\\d{2}:\\d{2}(:\\d{2})?$/;\nconst DATETIME_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}/;\n\nconst validateDatetimeFormat = (field: CmsModelField, value: any): string | null => {\n if (field.type !== \"datetime\") {\n return null;\n }\n if (value === null || value === undefined || value === \"\") {\n return null;\n }\n if (typeof value !== \"string\") {\n return null;\n }\n\n const dateType = field.settings?.type;\n\n switch (dateType) {\n case \"date\":\n if (!DATE_RE.test(value)) {\n return `Invalid date format for field \"${field.fieldId}\". Expected YYYY-MM-DD.`;\n }\n return null;\n case \"time\":\n if (!TIME_RE.test(value)) {\n return `Invalid time format for field \"${field.fieldId}\". Expected HH:mm or HH:mm:ss.`;\n }\n return null;\n case \"dateTimeWithTimezone\":\n case \"dateTimeWithoutTimezone\":\n if (!DATETIME_RE.test(value)) {\n return `Invalid dateTime format for field \"${field.fieldId}\". Expected ISO 8601 dateTime.`;\n }\n return null;\n default:\n return null;\n }\n};\n\nconst getFieldValidation = (\n listValidation?: CmsModelFieldValidation[]\n): CmsModelFieldValidation[] => {\n if (!listValidation?.length) {\n return [];\n }\n // Filter out the legacy \"dynamicZone\" validator that was never implemented.\n // Existing models may still have it in their persisted listValidation data.\n return listValidation.filter(item => item.name !== \"dynamicZone\");\n};\n/**\n * When multiple values is selected we must run validations on the array containing the values\n * And then on each value in the array\n */\nconst runFieldMultipleValuesValidations = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: ExecuteValidationParams<TValues>\n): Promise<string | null> => {\n const { field, values: initialValues } = params;\n const values = initialValues[field.fieldId as keyof TValues] as\n | PossibleValue[]\n | null\n | undefined;\n const valuesError = await validateValue(\n params,\n getFieldValidation(field.listValidation),\n values\n );\n if (valuesError) {\n return valuesError;\n }\n if (values === null || values === undefined) {\n return null;\n }\n for (const value of values) {\n const datetimeError = validateDatetimeFormat(field, value);\n if (datetimeError) {\n return datetimeError;\n }\n const valueError = await validateValue(params, getFieldValidation(field.validation), value);\n if (valueError) {\n return valueError;\n }\n const predefinedValueError = validatePredefinedValue(field, value);\n if (predefinedValueError) {\n return predefinedValueError;\n }\n }\n return null;\n};\n/**\n * Runs validation on given value.\n */\nconst runFieldValueValidations = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: ExecuteValidationParams<TValues>\n): Promise<string | null> => {\n const { values, field } = params;\n const value = values[field.fieldId as keyof TValues];\n const datetimeError = validateDatetimeFormat(field, value);\n if (datetimeError) {\n return datetimeError;\n }\n const error = await validateValue(params, field.validation || [], value);\n if (error) {\n return error;\n }\n return validatePredefinedValue(field, value);\n};\n\nconst execValidation = async (params: ExecuteValidationParams): Promise<string | null> => {\n const { field } = params;\n if (field.list) {\n return await runFieldMultipleValuesValidations(params);\n }\n return await runFieldValueValidations(params);\n};\n\ninterface IValidateModelEntryDataParams<TValues extends CmsEntryValues = CmsEntryValues> {\n context: CmsContext;\n model: CmsModel;\n values: TValues;\n entry?: CmsEntry<TValues>;\n skipValidation?: boolean;\n}\n\nexport const validateModelEntryData = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: IValidateModelEntryDataParams<TValues>\n) => {\n const { context, model, entry, values, skipValidation } = params;\n\n if (skipValidation) {\n return [];\n }\n\n const validatorList: PluginValidationList = {};\n const registry = context.container.resolve(CmsModelFieldValidatorRegistry);\n const validators = registry.getAll();\n for (const validator of validators) {\n const name = validator.name;\n if (!validatorList[name]) {\n validatorList[name] = [];\n }\n validatorList[name].push(params => {\n return validator.validate(params);\n });\n }\n\n return await validate<TValues>({\n validatorList,\n context,\n model,\n entry,\n parents: [],\n fields: model.fields,\n values: {\n ...entry?.values,\n ...values\n }\n });\n};\n\nexport const validateModelEntryDataOrThrow = async <\n TValues extends CmsEntryValues = CmsEntryValues\n>(\n params: IValidateModelEntryDataParams<TValues>\n) => {\n const invalidFields = await validateModelEntryData(params);\n if (invalidFields.length === 0) {\n return;\n }\n throw new EntryValidationError(\"Validation failed.\", invalidFields);\n};\n\n/**\n *\n */\ninterface FieldError {\n id: string;\n fieldId: string;\n storageId: string;\n error: any;\n parents: string[];\n}\n\ninterface ValidateFieldParams<TValues extends CmsEntryValues = CmsEntryValues> {\n validatorList: PluginValidationList;\n parents: string[];\n model: CmsModel;\n values: TValues;\n context: CmsContext;\n field: CmsModelField;\n entry?: CmsEntry<TValues>;\n}\n\nconst executeFieldValidation = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: ValidateFieldParams<TValues>\n): Promise<FieldError[]> => {\n // TODO put per-field validation into plugins.\n const { field } = params;\n /**\n * Object field.\n */\n if (field.type === \"object\") {\n const fields = field.settings?.fields;\n if (!Array.isArray(fields)) {\n return [];\n }\n const validations: FieldError[] = [];\n /**\n * We need to validate the object field as well.\n */\n const error = await execValidation({\n ...params,\n field\n });\n if (error) {\n validations.push({\n id: field.id,\n fieldId: field.fieldId,\n storageId: field.storageId,\n error,\n parents: params.parents\n });\n }\n const objectValue = params.values[field.fieldId as keyof TValues];\n if (!objectValue) {\n return validations;\n }\n const values = (Array.isArray(objectValue) ? objectValue : [objectValue]) as TValues[];\n for (const index in values) {\n const parents = field.list ? [field.fieldId, index] : [field.fieldId];\n const value = values[index] as TValues;\n for (const childField of fields) {\n const errors = await executeFieldValidation<typeof value>({\n ...params,\n parents: params.parents.concat(parents),\n field: childField,\n values: value\n });\n if (errors.length === 0) {\n continue;\n }\n validations.push(...errors);\n }\n }\n return validations;\n }\n /**\n * Dynamic Zone Field\n */\n //\n else if (field.type === \"dynamicZone\") {\n const validations: FieldError[] = [];\n\n const error = await execValidation({\n ...params,\n field\n });\n if (error) {\n validations.push({\n id: field.id,\n fieldId: field.fieldId,\n storageId: field.storageId,\n error,\n parents: params.parents\n });\n }\n\n const templates = (field.settings?.templates || []) as CmsDynamicZoneTemplate[];\n for (const template of templates) {\n const fields = template.fields;\n const fieldData = params.values[field.fieldId as keyof TValues];\n if (!fieldData) {\n continue;\n }\n const values: TValues[keyof TValues][] = Array.isArray(fieldData)\n ? fieldData\n : [fieldData];\n for (const index in values) {\n const templateValue = values[index]?.[template.gqlTypeName];\n if (!templateValue) {\n continue;\n }\n /**\n * Order of the parents must be\n * - fieldId\n * - index (if multiple values)\n * - gqlTypeName\n */\n const parents = [field.fieldId];\n if (field.list) {\n parents.push(index);\n }\n parents.push(template.gqlTypeName);\n for (const childField of fields) {\n const errors = await executeFieldValidation({\n ...params,\n parents: params.parents.concat(parents),\n field: childField,\n values: templateValue\n });\n if (errors.length === 0) {\n continue;\n }\n validations.push(...errors);\n }\n }\n }\n\n return validations;\n }\n const error = await execValidation({\n ...params\n });\n if (!error) {\n return [];\n }\n return [\n {\n id: field.id,\n fieldId: field.fieldId,\n storageId: field.storageId,\n error,\n parents: params.parents\n }\n ];\n};\n\ninterface ValidateFieldsParams<TValues extends CmsEntryValues = CmsEntryValues> {\n validatorList: PluginValidationList;\n parents: string[];\n model: CmsModel;\n values: TValues;\n fields: CmsModelField[];\n context: CmsContext;\n entry?: CmsEntry<TValues>;\n}\n\nconst validate = async <TValues extends CmsEntryValues = CmsEntryValues>(\n params: ValidateFieldsParams<TValues>\n): Promise<FieldError[]> => {\n const { fields } = params;\n const errors: FieldError[] = [];\n\n const results = await Promise.all(\n fields.map(async field => {\n return await executeFieldValidation<TValues>({\n ...params,\n field\n });\n })\n );\n\n for (const result of results) {\n if (result.length === 0) {\n continue;\n }\n errors.push(...result);\n }\n return errors;\n};\n"],"names":["validateValue","params","fieldValidators","value","validatorList","context","field","model","entry","fieldValidator","name","validations","validate","result","ex","validatePredefinedValue","enabled","predefinedValues","Array","predefinedValue","DATE_RE","TIME_RE","DATETIME_RE","validateDatetimeFormat","dateType","getFieldValidation","listValidation","item","runFieldMultipleValuesValidations","initialValues","values","valuesError","datetimeError","valueError","predefinedValueError","runFieldValueValidations","error","execValidation","validateModelEntryData","skipValidation","registry","CmsModelFieldValidatorRegistry","validators","validator","validateModelEntryDataOrThrow","invalidFields","EntryValidationError","executeFieldValidation","fields","objectValue","index","parents","childField","errors","templates","template","fieldData","templateValue","results","Promise"],"mappings":"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"}
@@ -30,13 +30,14 @@ const createDefaultFields = ()=>[
30
30
  {
31
31
  id: generateAlphaNumericLowerCaseId(8),
32
32
  fieldId: "image",
33
- type: "file",
33
+ type: "asset",
34
34
  label: "Image",
35
35
  validation: [],
36
36
  listValidation: [],
37
37
  renderer: {
38
- name: "file-input"
38
+ name: "asset-input"
39
39
  },
40
+ tags: [],
40
41
  settings: {
41
42
  imagesOnly: true
42
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"crud/contentModel/defaultFields.js","sources":["../../../src/crud/contentModel/defaultFields.ts"],"sourcesContent":["import type { CmsModelCreateInput, CmsModelFieldInput } from \"~/types/index.js\";\nimport { generateAlphaNumericLowerCaseId } from \"@webiny/utils\";\n\nconst createDefaultFields = (): CmsModelFieldInput[] => {\n return [\n {\n id: generateAlphaNumericLowerCaseId(8),\n fieldId: \"title\",\n type: \"text\",\n label: \"Title\",\n validation: [\n {\n name: \"required\",\n message: \"Title is a required field.\"\n }\n ],\n listValidation: [],\n renderer: {\n name: \"text-input\"\n }\n },\n {\n id: generateAlphaNumericLowerCaseId(8),\n fieldId: \"description\",\n type: \"long-text\",\n label: \"Description\",\n validation: [],\n listValidation: [],\n renderer: {\n name: \"long-text-text-area\"\n }\n },\n {\n id: generateAlphaNumericLowerCaseId(8),\n fieldId: \"image\",\n type: \"file\",\n label: \"Image\",\n validation: [],\n listValidation: [],\n renderer: {\n name: \"file-input\"\n },\n settings: {\n imagesOnly: true\n }\n }\n ];\n};\n\n/**\n * We only assign default fields if there are no fields in the model already.\n */\nexport const assignModelDefaultFields = (model: CmsModelCreateInput): void => {\n if (model.fields && model.fields.length !== 0) {\n return;\n }\n\n model.fields = createDefaultFields();\n model.layout = [[model.fields[0].id], [model.fields[1].id, model.fields[2].id]];\n};\n"],"names":["createDefaultFields","generateAlphaNumericLowerCaseId","assignModelDefaultFields","model"],"mappings":";AAGA,MAAMA,sBAAsB,IACjB;QACH;YACI,IAAIC,gCAAgC;YACpC,SAAS;YACT,MAAM;YACN,OAAO;YACP,YAAY;gBACR;oBACI,MAAM;oBACN,SAAS;gBACb;aACH;YACD,gBAAgB,EAAE;YAClB,UAAU;gBACN,MAAM;YACV;QACJ;QACA;YACI,IAAIA,gCAAgC;YACpC,SAAS;YACT,MAAM;YACN,OAAO;YACP,YAAY,EAAE;YACd,gBAAgB,EAAE;YAClB,UAAU;gBACN,MAAM;YACV;QACJ;QACA;YACI,IAAIA,gCAAgC;YACpC,SAAS;YACT,MAAM;YACN,OAAO;YACP,YAAY,EAAE;YACd,gBAAgB,EAAE;YAClB,UAAU;gBACN,MAAM;YACV;YACA,UAAU;gBACN,YAAY;YAChB;QACJ;KACH;AAME,MAAMC,2BAA2B,CAACC;IACrC,IAAIA,MAAM,MAAM,IAAIA,AAAwB,MAAxBA,MAAM,MAAM,CAAC,MAAM,EACnC;IAGJA,MAAM,MAAM,GAAGH;IACfG,MAAM,MAAM,GAAG;QAAC;YAACA,MAAM,MAAM,CAAC,EAAE,CAAC,EAAE;SAAC;QAAE;YAACA,MAAM,MAAM,CAAC,EAAE,CAAC,EAAE;YAAEA,MAAM,MAAM,CAAC,EAAE,CAAC,EAAE;SAAC;KAAC;AACnF"}
1
+ {"version":3,"file":"crud/contentModel/defaultFields.js","sources":["../../../src/crud/contentModel/defaultFields.ts"],"sourcesContent":["import type { CmsModelCreateInput, CmsModelFieldInput } from \"~/types/index.js\";\nimport { generateAlphaNumericLowerCaseId } from \"@webiny/utils\";\n\nconst createDefaultFields = (): CmsModelFieldInput[] => {\n return [\n {\n id: generateAlphaNumericLowerCaseId(8),\n fieldId: \"title\",\n type: \"text\",\n label: \"Title\",\n validation: [\n {\n name: \"required\",\n message: \"Title is a required field.\"\n }\n ],\n listValidation: [],\n renderer: {\n name: \"text-input\"\n }\n },\n {\n id: generateAlphaNumericLowerCaseId(8),\n fieldId: \"description\",\n type: \"long-text\",\n label: \"Description\",\n validation: [],\n listValidation: [],\n renderer: {\n name: \"long-text-text-area\"\n }\n },\n {\n id: generateAlphaNumericLowerCaseId(8),\n fieldId: \"image\",\n type: \"asset\",\n label: \"Image\",\n validation: [],\n listValidation: [],\n renderer: {\n name: \"asset-input\"\n },\n tags: [],\n settings: {\n imagesOnly: true\n }\n }\n ];\n};\n\n/**\n * We only assign default fields if there are no fields in the model already.\n */\nexport const assignModelDefaultFields = (model: CmsModelCreateInput): void => {\n if (model.fields && model.fields.length !== 0) {\n return;\n }\n\n model.fields = createDefaultFields();\n model.layout = [[model.fields[0].id], [model.fields[1].id, model.fields[2].id]];\n};\n"],"names":["createDefaultFields","generateAlphaNumericLowerCaseId","assignModelDefaultFields","model"],"mappings":";AAGA,MAAMA,sBAAsB,IACjB;QACH;YACI,IAAIC,gCAAgC;YACpC,SAAS;YACT,MAAM;YACN,OAAO;YACP,YAAY;gBACR;oBACI,MAAM;oBACN,SAAS;gBACb;aACH;YACD,gBAAgB,EAAE;YAClB,UAAU;gBACN,MAAM;YACV;QACJ;QACA;YACI,IAAIA,gCAAgC;YACpC,SAAS;YACT,MAAM;YACN,OAAO;YACP,YAAY,EAAE;YACd,gBAAgB,EAAE;YAClB,UAAU;gBACN,MAAM;YACV;QACJ;QACA;YACI,IAAIA,gCAAgC;YACpC,SAAS;YACT,MAAM;YACN,OAAO;YACP,YAAY,EAAE;YACd,gBAAgB,EAAE;YAClB,UAAU;gBACN,MAAM;YACV;YACA,MAAM,EAAE;YACR,UAAU;gBACN,YAAY;YAChB;QACJ;KACH;AAME,MAAMC,2BAA2B,CAACC;IACrC,IAAIA,MAAM,MAAM,IAAIA,AAAwB,MAAxBA,MAAM,MAAM,CAAC,MAAM,EACnC;IAGJA,MAAM,MAAM,GAAGH;IACfG,MAAM,MAAM,GAAG;QAAC;YAACA,MAAM,MAAM,CAAC,EAAE,CAAC,EAAE;SAAC;QAAE;YAACA,MAAM,MAAM,CAAC,EAAE,CAAC,EAAE;YAAEA,MAAM,MAAM,CAAC,EAAE,CAAC,EAAE;SAAC;KAAC;AACnF"}
@@ -109,20 +109,20 @@ export declare const createModelCreateValidation: () => zod.ZodObject<{
109
109
  rules: zod.ZodPipe<zod.ZodDefault<zod.ZodOptional<zod.ZodNullable<zod.ZodOptional<zod.ZodArray<zod.ZodObject<{
110
110
  type: zod.ZodEnum<{
111
111
  accessControl: "accessControl";
112
- entryValue: "entryValue";
112
+ condition: "condition";
113
113
  }>;
114
114
  target: zod.ZodString;
115
115
  operator: zod.ZodString;
116
116
  value: zod.ZodUnion<readonly [zod.ZodString, zod.ZodNumber, zod.ZodBoolean, zod.ZodNull]>;
117
117
  action: zod.ZodString;
118
118
  }, zod.core.$strip>>>>>>, zod.ZodTransform<{
119
- type: "accessControl" | "entryValue";
119
+ type: "accessControl" | "condition";
120
120
  target: string;
121
121
  operator: string;
122
122
  value: string | number | boolean | null;
123
123
  action: string;
124
124
  }[], {
125
- type: "accessControl" | "entryValue";
125
+ type: "accessControl" | "condition";
126
126
  target: string;
127
127
  operator: string;
128
128
  value: string | number | boolean | null;
@@ -135,6 +135,7 @@ export declare const createModelCreateValidation: () => zod.ZodObject<{
135
135
  descriptionFieldId: zod.ZodOptional<zod.ZodNullable<zod.ZodOptional<zod.ZodString>>>;
136
136
  imageFieldId: zod.ZodOptional<zod.ZodNullable<zod.ZodOptional<zod.ZodString>>>;
137
137
  defaultFields: zod.ZodOptional<zod.ZodNullable<zod.ZodBoolean>>;
138
+ settings: zod.ZodDefault<zod.ZodOptional<zod.ZodNullable<zod.ZodOptional<zod.ZodObject<{}, zod.core.$loose>>>>>;
138
139
  }, zod.core.$strip>;
139
140
  export declare const createModelUpdateValidation: () => zod.ZodObject<{
140
141
  name: zod.ZodOptional<zod.ZodString>;
@@ -245,20 +246,20 @@ export declare const createModelUpdateValidation: () => zod.ZodObject<{
245
246
  rules: zod.ZodPipe<zod.ZodDefault<zod.ZodOptional<zod.ZodNullable<zod.ZodOptional<zod.ZodArray<zod.ZodObject<{
246
247
  type: zod.ZodEnum<{
247
248
  accessControl: "accessControl";
248
- entryValue: "entryValue";
249
+ condition: "condition";
249
250
  }>;
250
251
  target: zod.ZodString;
251
252
  operator: zod.ZodString;
252
253
  value: zod.ZodUnion<readonly [zod.ZodString, zod.ZodNumber, zod.ZodBoolean, zod.ZodNull]>;
253
254
  action: zod.ZodString;
254
255
  }, zod.core.$strip>>>>>>, zod.ZodTransform<{
255
- type: "accessControl" | "entryValue";
256
+ type: "accessControl" | "condition";
256
257
  target: string;
257
258
  operator: string;
258
259
  value: string | number | boolean | null;
259
260
  action: string;
260
261
  }[], {
261
- type: "accessControl" | "entryValue";
262
+ type: "accessControl" | "condition";
262
263
  target: string;
263
264
  operator: string;
264
265
  value: string | number | boolean | null;
@@ -270,6 +271,7 @@ export declare const createModelUpdateValidation: () => zod.ZodObject<{
270
271
  descriptionFieldId: zod.ZodOptional<zod.ZodNullable<zod.ZodOptional<zod.ZodString>>>;
271
272
  imageFieldId: zod.ZodOptional<zod.ZodNullable<zod.ZodOptional<zod.ZodString>>>;
272
273
  tags: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
274
+ settings: zod.ZodOptional<zod.ZodNullable<zod.ZodOptional<zod.ZodObject<{}, zod.core.$loose>>>>;
273
275
  }, zod.core.$strip>;
274
276
  export declare const createModelCreateFromValidation: () => zod.ZodObject<{
275
277
  name: zod.ZodString;
@@ -64,7 +64,7 @@ const fieldSchema = zod.object({
64
64
  rules: zod.array(zod.object({
65
65
  type: zod["enum"]([
66
66
  "accessControl",
67
- "entryValue"
67
+ "condition"
68
68
  ]),
69
69
  target: shortString,
70
70
  operator: shortString,
@@ -119,7 +119,8 @@ const createModelCreateValidation = ()=>zod.object({
119
119
  titleFieldId: optionalShortString.nullish(),
120
120
  descriptionFieldId: optionalShortString.nullish(),
121
121
  imageFieldId: optionalShortString.nullish(),
122
- defaultFields: zod.boolean().nullish()
122
+ defaultFields: zod.boolean().nullish(),
123
+ settings: zod.looseObject({}).optional().nullish().default({})
123
124
  });
124
125
  const createModelUpdateValidation = ()=>zod.object({
125
126
  name: optionalShortString,
@@ -137,7 +138,8 @@ const createModelUpdateValidation = ()=>zod.object({
137
138
  titleFieldId: optionalShortString.nullish(),
138
139
  descriptionFieldId: optionalShortString.nullish(),
139
140
  imageFieldId: optionalShortString.nullish(),
140
- tags: zod.array(shortString).optional()
141
+ tags: zod.array(shortString).optional(),
142
+ settings: zod.looseObject({}).optional().nullish()
141
143
  });
142
144
  const createModelCreateFromValidation = ()=>zod.object({
143
145
  name: shortString,
@@ -1 +1 @@
1
- {"version":3,"file":"domain/contentModel/schemas.js","sources":["../../../src/domain/contentModel/schemas.ts"],"sourcesContent":["import zod from \"zod\";\nimport upperFirst from \"lodash/upperFirst.js\";\nimport camelCase from \"lodash/camelCase.js\";\n\nconst str = zod.string().trim();\nconst shortString = str.max(255);\nconst longString = str;\nconst optionalShortString = shortString.optional();\nconst optionalLongString = longString.optional();\nconst optionalNullishShortString = optionalShortString.nullish().default(null);\nconst optionalNullishLongString = optionalLongString.nullish().default(null);\n\nconst icon = zod\n .looseObject({\n type: zod.string(),\n name: zod.string(),\n value: zod.string().optional()\n })\n .optional()\n .nullish()\n .default(null)\n .transform(value => {\n if (typeof value === \"string\") {\n return {\n type: \"icon\",\n name: value\n };\n }\n return value;\n });\n\nconst fieldSchema = zod.object({\n id: shortString,\n storageId: zod\n .string()\n .optional()\n .transform(() => {\n return \"\";\n }),\n fieldId: shortString\n .max(100)\n .regex(/^!?[a-zA-Z]/, {\n message: `Must not start with a number.`\n })\n .regex(/^(^[a-zA-Z0-9]+)$/, {\n message: `Must be alphanumeric string.`\n }),\n label: shortString,\n help: optionalNullishLongString,\n description: optionalNullishShortString,\n note: optionalNullishShortString,\n placeholder: optionalNullishShortString,\n type: shortString,\n tags: zod.array(shortString).optional().default([]),\n list: zod\n .boolean()\n .optional()\n .nullish()\n .transform(value => {\n return !!value;\n })\n .default(false),\n predefinedValues: zod\n .object({\n enabled: zod.boolean(),\n values: zod\n .array(\n zod.object({\n value: shortString,\n label: shortString,\n selected: zod.boolean().optional().default(false)\n })\n )\n .default([])\n })\n .default({\n enabled: false,\n values: []\n })\n .nullish()\n .optional()\n .transform(value => {\n return value || undefined;\n }),\n renderer: zod\n .object({\n name: shortString,\n settings: zod.looseObject({}).nullish().optional()\n })\n .optional()\n .nullable()\n .default(null),\n validation: zod\n .array(\n zod.object({\n name: shortString,\n message: optionalShortString.default(\"Value is required.\"),\n settings: zod\n .looseObject({})\n .optional()\n .nullish()\n .transform(value => {\n return value || {};\n })\n .default({})\n })\n )\n .nullish()\n .optional()\n .default([])\n .transform(value => value || []),\n listValidation: zod\n .array(\n zod.object({\n name: shortString,\n message: optionalShortString.default(\"Value is required.\"),\n settings: zod\n .looseObject({})\n .optional()\n .nullish()\n .transform(value => {\n return value || {};\n })\n .default({})\n })\n )\n .nullish()\n .optional()\n .default([])\n .transform(value => value || []),\n settings: zod\n .looseObject({})\n .optional()\n .nullish()\n .transform(value => {\n return value || {};\n })\n .default({}),\n rules: zod\n .array(\n zod.object({\n type: zod.enum([\"accessControl\", \"entryValue\"]),\n target: shortString,\n operator: shortString,\n value: zod.union([zod.string(), zod.number(), zod.boolean(), zod.null()]),\n action: shortString\n })\n )\n .optional()\n .nullish()\n .default([])\n .transform(value => value || [])\n});\n\nconst apiNameRefinementValidation = (value: string): boolean => {\n if (value.match(/^[A-Z]/) === null) {\n return false;\n }\n return value === upperFirst(camelCase(value));\n};\nconst refinementSingularValidationMessage = (value?: string) => {\n return {\n message: `The Singular API Name value \"${\n value || \"undefined\"\n }\" is not valid. It must in Upper First + Camel Cased form. For example: \"ArticleCategory\" or \"CarMake\".`\n };\n};\nconst refinementPluralValidationMessage = (value?: string) => {\n return {\n message: `The Plural API Name value \"${\n value || \"undefined\"\n }\" is not valid. It must in Upper First + Camel Cased form. For example: \"ArticleCategories\" or \"CarMakes\".`\n };\n};\n\nconst refineSingularApiName = (value: string, ctx: zod.RefinementCtx) => {\n if (!apiNameRefinementValidation(value)) {\n ctx.addIssue({\n code: zod.ZodIssueCode.custom,\n ...refinementSingularValidationMessage(value)\n });\n }\n};\n\nconst refinePluralApiName = (value: string, ctx: zod.RefinementCtx) => {\n if (!apiNameRefinementValidation(value)) {\n ctx.addIssue({\n code: zod.ZodIssueCode.custom,\n ...refinementPluralValidationMessage(value)\n });\n }\n};\n\nconst modelIdTransformation = (value?: string) => {\n if (!value) {\n return value;\n }\n const camelCasedValue = camelCase(value);\n if (camelCasedValue.toLowerCase() === value.toLowerCase()) {\n return value;\n }\n return camelCasedValue;\n};\n\nexport const createModelCreateValidation = () => {\n return zod.object({\n name: shortString,\n modelId: optionalShortString.transform(modelIdTransformation),\n singularApiName: shortString.min(1).superRefine(refineSingularApiName),\n pluralApiName: shortString.min(1).superRefine(refinePluralApiName),\n description: optionalNullishShortString.transform(value => {\n return value || \"\";\n }),\n group: shortString,\n icon,\n fields: zod.array(fieldSchema).default([]),\n layout: zod.array(zod.array(zod.any())).default([]),\n tags: zod.array(shortString).optional(),\n titleFieldId: optionalShortString.nullish(),\n descriptionFieldId: optionalShortString.nullish(),\n imageFieldId: optionalShortString.nullish(),\n defaultFields: zod.boolean().nullish()\n });\n};\n\nexport const createModelUpdateValidation = () => {\n return zod.object({\n name: optionalShortString,\n singularApiName: optionalShortString.superRefine((value, ctx) => {\n if (value) {\n refineSingularApiName(value, ctx);\n }\n }),\n pluralApiName: optionalShortString.superRefine((value, ctx) => {\n if (value) {\n refinePluralApiName(value, ctx);\n }\n }),\n description: optionalNullishShortString,\n group: optionalShortString,\n icon,\n fields: zod.array(fieldSchema),\n layout: zod.array(zod.array(zod.any())),\n titleFieldId: optionalShortString.nullish(),\n descriptionFieldId: optionalShortString.nullish(),\n imageFieldId: optionalShortString.nullish(),\n tags: zod.array(shortString).optional()\n });\n};\n\nexport const createModelCreateFromValidation = () => {\n return zod.object({\n name: shortString,\n modelId: optionalShortString.transform(modelIdTransformation),\n singularApiName: shortString.superRefine(refineSingularApiName),\n pluralApiName: shortString.superRefine(refinePluralApiName),\n description: optionalNullishShortString,\n group: shortString,\n icon\n });\n};\n"],"names":["str","zod","shortString","longString","optionalShortString","optionalLongString","optionalNullishShortString","optionalNullishLongString","icon","value","fieldSchema","undefined","apiNameRefinementValidation","upperFirst","camelCase","refinementSingularValidationMessage","refinementPluralValidationMessage","refineSingularApiName","ctx","refinePluralApiName","modelIdTransformation","camelCasedValue","createModelCreateValidation","createModelUpdateValidation","createModelCreateFromValidation"],"mappings":"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"}
1
+ {"version":3,"file":"domain/contentModel/schemas.js","sources":["../../../src/domain/contentModel/schemas.ts"],"sourcesContent":["import zod from \"zod\";\nimport upperFirst from \"lodash/upperFirst.js\";\nimport camelCase from \"lodash/camelCase.js\";\n\nconst str = zod.string().trim();\nconst shortString = str.max(255);\nconst longString = str;\nconst optionalShortString = shortString.optional();\nconst optionalLongString = longString.optional();\nconst optionalNullishShortString = optionalShortString.nullish().default(null);\nconst optionalNullishLongString = optionalLongString.nullish().default(null);\n\nconst icon = zod\n .looseObject({\n type: zod.string(),\n name: zod.string(),\n value: zod.string().optional()\n })\n .optional()\n .nullish()\n .default(null)\n .transform(value => {\n if (typeof value === \"string\") {\n return {\n type: \"icon\",\n name: value\n };\n }\n return value;\n });\n\nconst fieldSchema = zod.object({\n id: shortString,\n storageId: zod\n .string()\n .optional()\n .transform(() => {\n return \"\";\n }),\n fieldId: shortString\n .max(100)\n .regex(/^!?[a-zA-Z]/, {\n message: `Must not start with a number.`\n })\n .regex(/^(^[a-zA-Z0-9]+)$/, {\n message: `Must be alphanumeric string.`\n }),\n label: shortString,\n help: optionalNullishLongString,\n description: optionalNullishShortString,\n note: optionalNullishShortString,\n placeholder: optionalNullishShortString,\n type: shortString,\n tags: zod.array(shortString).optional().default([]),\n list: zod\n .boolean()\n .optional()\n .nullish()\n .transform(value => {\n return !!value;\n })\n .default(false),\n predefinedValues: zod\n .object({\n enabled: zod.boolean(),\n values: zod\n .array(\n zod.object({\n value: shortString,\n label: shortString,\n selected: zod.boolean().optional().default(false)\n })\n )\n .default([])\n })\n .default({\n enabled: false,\n values: []\n })\n .nullish()\n .optional()\n .transform(value => {\n return value || undefined;\n }),\n renderer: zod\n .object({\n name: shortString,\n settings: zod.looseObject({}).nullish().optional()\n })\n .optional()\n .nullable()\n .default(null),\n validation: zod\n .array(\n zod.object({\n name: shortString,\n message: optionalShortString.default(\"Value is required.\"),\n settings: zod\n .looseObject({})\n .optional()\n .nullish()\n .transform(value => {\n return value || {};\n })\n .default({})\n })\n )\n .nullish()\n .optional()\n .default([])\n .transform(value => value || []),\n listValidation: zod\n .array(\n zod.object({\n name: shortString,\n message: optionalShortString.default(\"Value is required.\"),\n settings: zod\n .looseObject({})\n .optional()\n .nullish()\n .transform(value => {\n return value || {};\n })\n .default({})\n })\n )\n .nullish()\n .optional()\n .default([])\n .transform(value => value || []),\n settings: zod\n .looseObject({})\n .optional()\n .nullish()\n .transform(value => {\n return value || {};\n })\n .default({}),\n rules: zod\n .array(\n zod.object({\n type: zod.enum([\"accessControl\", \"condition\"]),\n target: shortString,\n operator: shortString,\n value: zod.union([zod.string(), zod.number(), zod.boolean(), zod.null()]),\n action: shortString\n })\n )\n .optional()\n .nullish()\n .default([])\n .transform(value => value || [])\n});\n\nconst apiNameRefinementValidation = (value: string): boolean => {\n if (value.match(/^[A-Z]/) === null) {\n return false;\n }\n return value === upperFirst(camelCase(value));\n};\nconst refinementSingularValidationMessage = (value?: string) => {\n return {\n message: `The Singular API Name value \"${\n value || \"undefined\"\n }\" is not valid. It must in Upper First + Camel Cased form. For example: \"ArticleCategory\" or \"CarMake\".`\n };\n};\nconst refinementPluralValidationMessage = (value?: string) => {\n return {\n message: `The Plural API Name value \"${\n value || \"undefined\"\n }\" is not valid. It must in Upper First + Camel Cased form. For example: \"ArticleCategories\" or \"CarMakes\".`\n };\n};\n\nconst refineSingularApiName = (value: string, ctx: zod.RefinementCtx) => {\n if (!apiNameRefinementValidation(value)) {\n ctx.addIssue({\n code: zod.ZodIssueCode.custom,\n ...refinementSingularValidationMessage(value)\n });\n }\n};\n\nconst refinePluralApiName = (value: string, ctx: zod.RefinementCtx) => {\n if (!apiNameRefinementValidation(value)) {\n ctx.addIssue({\n code: zod.ZodIssueCode.custom,\n ...refinementPluralValidationMessage(value)\n });\n }\n};\n\nconst modelIdTransformation = (value?: string) => {\n if (!value) {\n return value;\n }\n const camelCasedValue = camelCase(value);\n if (camelCasedValue.toLowerCase() === value.toLowerCase()) {\n return value;\n }\n return camelCasedValue;\n};\n\nexport const createModelCreateValidation = () => {\n return zod.object({\n name: shortString,\n modelId: optionalShortString.transform(modelIdTransformation),\n singularApiName: shortString.min(1).superRefine(refineSingularApiName),\n pluralApiName: shortString.min(1).superRefine(refinePluralApiName),\n description: optionalNullishShortString.transform(value => {\n return value || \"\";\n }),\n group: shortString,\n icon,\n fields: zod.array(fieldSchema).default([]),\n layout: zod.array(zod.array(zod.any())).default([]),\n tags: zod.array(shortString).optional(),\n titleFieldId: optionalShortString.nullish(),\n descriptionFieldId: optionalShortString.nullish(),\n imageFieldId: optionalShortString.nullish(),\n defaultFields: zod.boolean().nullish(),\n settings: zod.looseObject({}).optional().nullish().default({})\n });\n};\n\nexport const createModelUpdateValidation = () => {\n return zod.object({\n name: optionalShortString,\n singularApiName: optionalShortString.superRefine((value, ctx) => {\n if (value) {\n refineSingularApiName(value, ctx);\n }\n }),\n pluralApiName: optionalShortString.superRefine((value, ctx) => {\n if (value) {\n refinePluralApiName(value, ctx);\n }\n }),\n description: optionalNullishShortString,\n group: optionalShortString,\n icon,\n fields: zod.array(fieldSchema),\n layout: zod.array(zod.array(zod.any())),\n titleFieldId: optionalShortString.nullish(),\n descriptionFieldId: optionalShortString.nullish(),\n imageFieldId: optionalShortString.nullish(),\n tags: zod.array(shortString).optional(),\n settings: zod.looseObject({}).optional().nullish()\n });\n};\n\nexport const createModelCreateFromValidation = () => {\n return zod.object({\n name: shortString,\n modelId: optionalShortString.transform(modelIdTransformation),\n singularApiName: shortString.superRefine(refineSingularApiName),\n pluralApiName: shortString.superRefine(refinePluralApiName),\n description: optionalNullishShortString,\n group: shortString,\n icon\n });\n};\n"],"names":["str","zod","shortString","longString","optionalShortString","optionalLongString","optionalNullishShortString","optionalNullishLongString","icon","value","fieldSchema","undefined","apiNameRefinementValidation","upperFirst","camelCase","refinementSingularValidationMessage","refinementPluralValidationMessage","refineSingularApiName","ctx","refinePluralApiName","modelIdTransformation","camelCasedValue","createModelCreateValidation","createModelUpdateValidation","createModelCreateFromValidation"],"mappings":"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"}
@@ -3,8 +3,9 @@ export { ModelBuilder } from "../../../features/modelBuilder/models/ModelBuilder
3
3
  export { DataFieldBuilder } from "../../../features/modelBuilder/fields/FieldBuilder.js";
4
4
  export { LayoutFieldBuilder } from "../../../features/modelBuilder/fields/FieldBuilder.js";
5
5
  export { FieldType } from "../../../features/modelBuilder/fields/abstractions.js";
6
+ export { type IAssetFieldBuilder } from "../../../features/modelBuilder/fields/AssetFieldType.js";
6
7
  export type { IFieldRendererRegistry } from "../../../features/modelBuilder/fields/DataFieldBuilder.js";
7
- export type { IFieldBuilderRegistry } from "../../../features/modelBuilder/abstractions.js";
8
+ export type { IFieldBuilderRegistry, IModelSettings } from "../../../features/modelBuilder/abstractions.js";
8
9
  export { LayoutBuilder } from "../../../features/modelBuilder/LayoutBuilder.js";
9
10
  export type { FieldTypeValidator } from "../../../features/modelBuilder/fields/fieldTypeValidator.js";
10
11
  export type { CmsModel } from "../../../types/model.js";
@@ -19,3 +20,5 @@ export { DeleteModelUseCase } from "../../../features/contentModel/DeleteModel/a
19
20
  export { ModelBeforeDeleteEventHandler, ModelAfterDeleteEventHandler } from "../../../features/contentModel/DeleteModel/events.js";
20
21
  export { GetModelUseCase } from "../../../features/contentModel/GetModel/abstractions.js";
21
22
  export { ListModelsUseCase } from "../../../features/contentModel/ListModels/abstractions.js";
23
+ export { ModelToAstConverter } from "../../../features/contentModel/ModelToAstConverter/index.js";
24
+ export { CmsModelToJsonSchemaConverter } from "../../../utils/index.js";