@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.
- package/HeadlessCmsFeature.js +4 -1
- package/HeadlessCmsFeature.js.map +1 -1
- package/createCmsRoute.d.ts +13 -8
- package/createCmsRoute.js +14 -4
- package/createCmsRoute.js.map +1 -1
- package/crud/contentEntry/entryDataValidation.js +27 -0
- package/crud/contentEntry/entryDataValidation.js.map +1 -1
- package/crud/contentModel/defaultFields.js +3 -2
- package/crud/contentModel/defaultFields.js.map +1 -1
- package/domain/contentModel/schemas.d.ts +8 -6
- package/domain/contentModel/schemas.js +5 -3
- package/domain/contentModel/schemas.js.map +1 -1
- package/exports/api/cms/model.d.ts +4 -1
- package/exports/api/cms/model.js +2 -0
- package/features/ai/DescribeContentModelTool.d.ts +55 -0
- package/features/ai/DescribeContentModelTool.js +60 -0
- package/features/ai/DescribeContentModelTool.js.map +1 -0
- package/features/ai/ListContentModelsTool.d.ts +41 -0
- package/features/ai/ListContentModelsTool.js +44 -0
- package/features/ai/ListContentModelsTool.js.map +1 -0
- package/features/ai/QueryEntriesTool.d.ts +75 -0
- package/features/ai/QueryEntriesTool.js +90 -0
- package/features/ai/QueryEntriesTool.js.map +1 -0
- package/features/ai/feature.d.ts +8 -0
- package/features/ai/feature.js +15 -0
- package/features/ai/feature.js.map +1 -0
- package/features/ai/index.d.ts +4 -0
- package/features/ai/index.js +4 -0
- package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.d.ts +14 -0
- package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.js +32 -0
- package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.js.map +1 -0
- package/features/contentModel/ComponentMapGenerator/abstractions.d.ts +8 -0
- package/features/contentModel/ComponentMapGenerator/abstractions.js +5 -0
- package/features/contentModel/ComponentMapGenerator/abstractions.js.map +1 -0
- package/features/contentModel/ComponentMapGenerator/feature.d.ts +4 -0
- package/features/contentModel/ComponentMapGenerator/feature.js +11 -0
- package/features/contentModel/ComponentMapGenerator/feature.js.map +1 -0
- package/features/contentModel/ComponentMapGenerator/index.d.ts +2 -0
- package/features/contentModel/ComponentMapGenerator/index.js +2 -0
- package/features/contentModel/ContentModelFeature.js +4 -0
- package/features/contentModel/ContentModelFeature.js.map +1 -1
- package/features/contentModel/RefModelsGenerator/RefModelsGenerator.d.ts +19 -0
- package/features/contentModel/RefModelsGenerator/RefModelsGenerator.js +56 -0
- package/features/contentModel/RefModelsGenerator/RefModelsGenerator.js.map +1 -0
- package/features/contentModel/RefModelsGenerator/abstractions.d.ts +11 -0
- package/features/contentModel/RefModelsGenerator/abstractions.js +5 -0
- package/features/contentModel/RefModelsGenerator/abstractions.js.map +1 -0
- package/features/contentModel/RefModelsGenerator/feature.d.ts +4 -0
- package/features/contentModel/RefModelsGenerator/feature.js +11 -0
- package/features/contentModel/RefModelsGenerator/feature.js.map +1 -0
- package/features/contentModel/RefModelsGenerator/index.d.ts +2 -0
- package/features/contentModel/RefModelsGenerator/index.js +2 -0
- package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js +2 -0
- package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js.map +1 -1
- package/features/contentModelGroup/CreateGroup/CreateGroupRepository.d.ts +3 -1
- package/features/contentModelGroup/CreateGroup/CreateGroupRepository.js +6 -4
- package/features/contentModelGroup/CreateGroup/CreateGroupRepository.js.map +1 -1
- package/features/graphql/feature.js +2 -0
- package/features/graphql/feature.js.map +1 -1
- package/features/graphql/fields/base/AssetToGraphQL.d.ts +26 -0
- package/features/graphql/fields/base/AssetToGraphQL.js +148 -0
- package/features/graphql/fields/base/AssetToGraphQL.js.map +1 -0
- package/features/graphql/fields/base/DynamicZoneToGraphQL.js +5 -1
- package/features/graphql/fields/base/DynamicZoneToGraphQL.js.map +1 -1
- package/features/graphql/fields/base/ObjectToGraphQL.js +2 -2
- package/features/graphql/fields/base/ObjectToGraphQL.js.map +1 -1
- package/features/modelBuilder/abstractions.d.ts +10 -0
- package/features/modelBuilder/abstractions.js.map +1 -1
- package/features/modelBuilder/feature.js +2 -0
- package/features/modelBuilder/feature.js.map +1 -1
- package/features/modelBuilder/fields/AssetFieldType.d.ts +20 -0
- package/features/modelBuilder/fields/AssetFieldType.js +46 -0
- package/features/modelBuilder/fields/AssetFieldType.js.map +1 -0
- package/features/modelBuilder/fields/BaseFieldBuilder.d.ts +3 -1
- package/features/modelBuilder/fields/BaseFieldBuilder.js +4 -0
- package/features/modelBuilder/fields/BaseFieldBuilder.js.map +1 -1
- package/features/modelBuilder/fields/DataFieldBuilder.d.ts +42 -0
- package/features/modelBuilder/fields/DataFieldBuilder.js +5 -1
- package/features/modelBuilder/fields/DataFieldBuilder.js.map +1 -1
- package/features/modelBuilder/fields/DynamicZoneFieldType.d.ts +1 -0
- package/features/modelBuilder/fields/DynamicZoneFieldType.js +10 -9
- package/features/modelBuilder/fields/DynamicZoneFieldType.js.map +1 -1
- package/features/modelBuilder/fields/UiAlertFieldType.js +2 -1
- package/features/modelBuilder/fields/UiAlertFieldType.js.map +1 -1
- package/features/modelBuilder/fields/UiSeparatorFieldType.js +2 -1
- package/features/modelBuilder/fields/UiSeparatorFieldType.js.map +1 -1
- package/features/modelBuilder/fields/UiTabsFieldType.d.ts +2 -1
- package/features/modelBuilder/fields/UiTabsFieldType.js +6 -3
- package/features/modelBuilder/fields/UiTabsFieldType.js.map +1 -1
- package/features/modelBuilder/fields/resolveAssetUrl.d.ts +35 -0
- package/features/modelBuilder/fields/resolveAssetUrl.js +26 -0
- package/features/modelBuilder/fields/resolveAssetUrl.js.map +1 -0
- package/features/modelBuilder/index.d.ts +1 -1
- package/features/modelBuilder/models/BaseModelBuilder.d.ts +3 -1
- package/features/modelBuilder/models/BaseModelBuilder.js +7 -0
- package/features/modelBuilder/models/BaseModelBuilder.js.map +1 -1
- package/features/modelBuilder/models/PrivateModelBuilder.js +2 -1
- package/features/modelBuilder/models/PrivateModelBuilder.js.map +1 -1
- package/features/modelBuilder/models/PublicModelBuilder.js +2 -1
- package/features/modelBuilder/models/PublicModelBuilder.js.map +1 -1
- package/features/sortMapper/SortMapper.js +2 -5
- package/features/sortMapper/SortMapper.js.map +1 -1
- package/features/whereMapper/WhereMapper.js +7 -5
- package/features/whereMapper/WhereMapper.js.map +1 -1
- package/graphql/schema/cms/getEntryResolver.js +3 -2
- package/graphql/schema/cms/getEntryResolver.js.map +1 -1
- package/graphql/schema/cms/getModelResolver.d.ts +35 -0
- package/graphql/schema/cms/getModelResolver.js +49 -0
- package/graphql/schema/cms/getModelResolver.js.map +1 -0
- package/graphql/schema/cms/helpers/buildFieldsSelection.js +9 -2
- package/graphql/schema/cms/helpers/buildFieldsSelection.js.map +1 -1
- package/graphql/schema/cms/helpers/expandFieldWildcards.d.ts +2 -0
- package/graphql/schema/cms/helpers/expandFieldWildcards.js +13 -0
- package/graphql/schema/cms/helpers/expandFieldWildcards.js.map +1 -0
- package/graphql/schema/cms/helpers/index.d.ts +1 -0
- package/graphql/schema/cms/helpers/index.js +1 -0
- package/graphql/schema/cms/helpers/transformWhereToNested.js +39 -17
- package/graphql/schema/cms/helpers/transformWhereToNested.js.map +1 -1
- package/graphql/schema/cms/helpers.d.ts +1 -0
- package/graphql/schema/cms/helpers.js +1 -0
- package/graphql/schema/cms/listEntriesResolver.js +3 -2
- package/graphql/schema/cms/listEntriesResolver.js.map +1 -1
- package/graphql/schema/cms/resolvers/getModel.d.ts +8 -0
- package/graphql/schema/cms/resolvers/getModel.js +18 -0
- package/graphql/schema/cms/resolvers/getModel.js.map +1 -0
- package/graphql/schema/cms/resolvers/index.d.ts +1 -0
- package/graphql/schema/cms/resolvers/index.js +1 -0
- package/graphql/schema/cms/typeDefs/query.js +1 -0
- package/graphql/schema/cms/typeDefs/query.js.map +1 -1
- package/graphql/schema/cms/typeDefs/responses.js +5 -0
- package/graphql/schema/cms/typeDefs/responses.js.map +1 -1
- package/graphql/schema/contentModels.js +31 -0
- package/graphql/schema/contentModels.js.map +1 -1
- package/package.json +21 -22
- package/plugins/CmsModelPlugin.js +2 -1
- package/plugins/CmsModelPlugin.js.map +1 -1
- package/types/fields/dynamicZoneField.d.ts +3 -2
- package/types/model.d.ts +6 -0
- package/types/modelField.d.ts +3 -1
package/HeadlessCmsFeature.js
CHANGED
|
@@ -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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFO,MAAMA,qBAAqBC,cAAiC;IAC/D,MAAM;IACN,UAASC,SAAS,EAAEC,MAAM;QACtB,MAAM,EAAEC,IAAI,EAAE,GAAGD;QAKjBD,UAAU,QAAQ,CAACG;QACnBH,UAAU,QAAQ,CAACI;QACnBJ,UAAU,QAAQ,CAACK;QACnBL,UAAU,QAAQ,CAACM;QACnBN,UAAU,QAAQ,CAACO;QACnBP,UAAU,QAAQ,CAACQ;QACnBR,UAAU,QAAQ,CAACS;QACnBT,UAAU,QAAQ,CAACU;QACnBV,UAAU,QAAQ,CAACW;QACnBX,UAAU,QAAQ,CAACY;QACnBZ,UAAU,QAAQ,CAACa;QACnBb,UAAU,QAAQ,CAACc;QACnBd,UAAU,QAAQ,CAACe;QAEnBf,UAAU,gBAAgB,CAACgB,2BAA2B;YAClD,MAAMf,OAAO,IAAI;QACrB;QAKAgB,mBAAmB,QAAQ,CAACjB;QAC5BkB,eAAe,QAAQ,CAAClB;QACxBmB,kBAAkB,QAAQ,CAACnB;QAC3BoB,eAAe,QAAQ,CAACpB;QACxBqB,oBAAoB,QAAQ,CAACrB;QAC7BsB,sBAAsB,QAAQ,CAACtB;QAC/BuB,oBAAoB,QAAQ,CAACvB;QAC7BwB,yBAAyB,QAAQ,CAACxB;QAClCyB,oBAAoB,QAAQ,CAACzB;QAC7B0B,sBAAsB,QAAQ,CAAC1B;QAC/B2B,qBAAqB,QAAQ,CAAC3B;QAC9B4B,mBAAmB,QAAQ,CAAC5B;QAQ5B6B,wBAAwB7B;QAIxB,MAAM8B,mBAAmB,IAAIC,iBAAiB;eAAK9B,OAAO,YAAY,IAAI,EAAE;SAAE;QAC9ED,UAAU,gBAAgB,CAACgC,kCAA6BF;QAIxD,KAAK,MAAMG,UAAUH,iBAAiB,MAAM,CAAiBI,eAAe,IAAI,EAC5ElC,UAAU,gBAAgB,CAACmC,wBAAwBF;QAEvD,KAAK,MAAMA,UAAUH,iBAAiB,MAAM,CAAiBM,eAAe,IAAI,EAC5EpC,UAAU,gBAAgB,CAACqC,wBAAwBJ;QAKvD,MAAMK,oBAAoBR,iBAAiB,MAAM,CAC7CS,uBAAuB,IAAI;QAE/B,IAAID,kBAAkB,MAAM,GAAG,GAC3BtC,UAAU,gBAAgB,CAACwC,yBAAyB;YAChD,SAAS,IAAMF;QACnB;QAOJ,KAAK,MAAML,UAAUhC,OAAO,YAAY,IAAI,EAAE,CAC1C,IAAIgC,UAAU,AAAiC,cAAjC,OAAQA,OAAe,KAAK,EACrCA,OAAe,KAAK,CAAC;YAAEjC;QAAU;QAI1C,MAAMyC,YAAY,IAAIC;QACtB1C,UAAU,gBAAgB,CAAC2C,sBAAsBF;QAKjD,MAAMG,aAAa;YACf5C;YACA,SAAS8B;YACTW;QACJ;QACAzC,UAAU,gBAAgB,CAAC6C,YAAuBD;QAElD5C,UAAU,gBAAgB,CAAC8C,0BAA0B;YACjD,SAAS,OAAMC;gBACXA,QAAQ,WAAW,CAAC;gBACpBA,QAAQ,kBAAkB,CAAC;oBAAE,YAAYC;gBAAiB;gBAC1D,OAAOD;YACX;QACJ;QAEA/C,UAAU,gBAAgB,CACtBiD,yBACA,IAAIC,gCACAC,2CAA2CP;QAOnD,MAAMQ,kBAAkBpD,UAAU,OAAO,CAACqD;QAC1C,MAAMC,gBAAgBtD,UAAU,OAAO,CAACuD;QACxC,MAAMC,YAAY,IAAMF,cAAc,SAAS;QAG/C,IAAIG;QACJ,MAAMC,mBAAmB;YACrB,IAAI,CAACD,uBACDA,wBAAwB,IAAIE,cAAc;gBACtC,aAAa,UAAYP,gBAAgB,WAAW;gBACpD,sBAAsB,IAClBA,gBAAgB,cAAc,CAAC;gBACnC,sBAAsB,IAAMA,gBAAgB,cAAc,CAAC;gBAC3D,uBAAuB,IAAMA,gBAAgB,cAAc,CAAC;gBAC5D,eAAe;oBACX,MAAMQ,SAAS,MAAMR,gBAAgB,oBAAoB,CAAC,IACtDpD,UAAU,OAAO,CAAC6D,mBAAmB,OAAO;oBAEhD,IAAID,OAAO,MAAM,IACb,MAAMA,OAAO,KAAK;oBAEtB,OAAOA,OAAO,KAAK;gBACvB;YACJ;YAEJ,OAAOH;QACX;QACAzD,UAAU,eAAe,CAAC8D,+BAA0B,IAAMJ;QAI1D,IAAIK;QACJ/D,UAAU,eAAe,CAACgE,aAAa;YACnC,IAAI,CAACD,WACDA,YAAY;gBACR7D;gBACA,MAAMA,AAAS,WAATA;gBACN,SAASA,AAAS,cAATA;gBACT,QAAQA,AAAS,aAATA;gBACR,eAAewD;gBACf,GAAGO,sBAAsB;oBAAE,SAASrB;gBAAW,EAAE;gBACjD,GAAGsB,iBAAiB;oBAAE,SAAStB;gBAAW,EAAE;gBAC5C,GAAGuB,uBAAuB;oBAAE,SAASvB;gBAAW,EAAE;gBAClD,QAAQ;oBAAE,GAAGwB,iBAAiBxB,WAAW;gBAAC;gBAC1C,WAAW;oBAAE,GAAGyB,iBAAiBzB,WAAW;gBAAC;YACjD;YAEJ,OAAOmB;QACX;QACA/D,UAAU,eAAe,CAACsE,WAAW,IAAMtE,UAAU,OAAO,CAACgE,aAAa,MAAM;QAChFhE,UAAU,eAAe,CAACuE,WAAW,IAAMvE,UAAU,OAAO,CAACgE,aAAa,SAAS;QAGnFhE,UAAU,gBAAgB,CAACwE,mBAAmB;YAC1C,SAAS,OAAOC,YAAyBC;gBACrC,MAAMC,KAAK3E,UAAU,OAAO,CAAC2C;gBAC7B,MAAMiC,SAAS,MAAMD,GAAG,OAAO,CAAC,iCAAiC,IAC7DvB,gBAAgB,oBAAoB,CAAC,IACjCyB,UAAU;4BAAE,SAASjC;4BAAYY;4BAAW,MAAMiB;wBAAW;gBAGrE,MAAMK,cAAc,MAAMH,GAAG,OAAO,CAChC,yCACA,UAAYI,kBAAkBL;gBAElC,OAAOC,GAAG,OAAO,CAAC,0CAA0C,IACxDK,mBAAmBF,aAAaF,QAAQhC;YAEhD;QACJ;QAIA5C,UAAU,gBAAgB,CAACwC,yBAAyB;YAChD,SAAS,IAAMyC,wBAAwBrC;QAC3C;QACA,IAAI1C,AAAS,aAATA,MACAF,UAAU,gBAAgB,CAACwC,yBAAyB;YAChD,SAAS,IAAM;oBAAC0C;iBAAa;QACjC;QAGJlF,UAAU,gBAAgB,CAACmF,yBAAyB,CAACC,OAAOC,QACjDC,wBAAwB1C,YAAYwC,OAAOC;QAEtDrF,UAAU,gBAAgB,CAACuF,2BAA2B,CAACH,OAAOC,QACnDG,0BAA0B5C,YAAYwC,OAAOC;QAExDrF,UAAU,gBAAgB,CAACyF,0BAA0BC,CAAAA,SAC1CC,oBAAoB;gBACvB,SAAS/C;gBACT,QAAQ8C,OAAO,MAAM;gBACrB,OAAO,EAAE;YACb;QAGJ1F,UAAU,QAAQ,CAAC4F,eAAe3F,OAAO,IAAI;IACjD;AACJ"}
|
|
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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"}
|
package/createCmsRoute.d.ts
CHANGED
|
@@ -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.
|
|
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 (
|
|
10
|
+
new (): {
|
|
11
|
+
readonly name: string;
|
|
13
12
|
readonly method: "POST";
|
|
14
13
|
readonly path: string;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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").
|
|
25
|
+
__abstraction: import("@webiny/di").Abstraction<import("@webiny/event-handler-core").IHttpRouteDefinition>;
|
|
21
26
|
};
|
package/createCmsRoute.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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
|
|
package/createCmsRoute.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createCmsRoute.js","sources":["../src/createCmsRoute.ts"],"sourcesContent":["import type { Container } from \"@webiny/di\";\nimport {
|
|
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: "
|
|
33
|
+
type: "asset",
|
|
34
34
|
label: "Image",
|
|
35
35
|
validation: [],
|
|
36
36
|
listValidation: [],
|
|
37
37
|
renderer: {
|
|
38
|
-
name: "
|
|
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: \"
|
|
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
|
-
|
|
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" | "
|
|
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" | "
|
|
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
|
-
|
|
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" | "
|
|
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" | "
|
|
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
|
-
"
|
|
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":";;;AAIA,MAAMA,MAAMC,IAAI,MAAM,GAAG,IAAI;AAC7B,MAAMC,cAAcF,IAAI,GAAG,CAAC;AAC5B,MAAMG,aAAaH;AACnB,MAAMI,sBAAsBF,YAAY,QAAQ;AAChD,MAAMG,qBAAqBF,WAAW,QAAQ;AAC9C,MAAMG,6BAA6BF,oBAAoB,OAAO,GAAG,OAAO,CAAC;AACzE,MAAMG,4BAA4BF,mBAAmB,OAAO,GAAG,OAAO,CAAC;AAEvE,MAAMG,OAAOP,IAAAA,WACG,CAAC;IACT,MAAMA,IAAI,MAAM;IAChB,MAAMA,IAAI,MAAM;IAChB,OAAOA,IAAI,MAAM,GAAG,QAAQ;AAChC,GACC,QAAQ,GACR,OAAO,GACP,OAAO,CAAC,MACR,SAAS,CAACQ,CAAAA;IACP,IAAI,AAAiB,YAAjB,OAAOA,OACP,OAAO;QACH,MAAM;QACN,MAAMA;IACV;IAEJ,OAAOA;AACX;AAEJ,MAAMC,cAAcT,IAAI,MAAM,CAAC;IAC3B,IAAIC;IACJ,WAAWD,IAAAA,MACA,GACN,QAAQ,GACR,SAAS,CAAC,IACA;IAEf,SAASC,YACJ,GAAG,CAAC,KACJ,KAAK,CAAC,eAAe;QAClB,SAAS;IACb,GACC,KAAK,CAAC,qBAAqB;QACxB,SAAS;IACb;IACJ,OAAOA;IACP,MAAMK;IACN,aAAaD;IACb,MAAMA;IACN,aAAaA;IACb,MAAMJ;IACN,MAAMD,IAAI,KAAK,CAACC,aAAa,QAAQ,GAAG,OAAO,CAAC,EAAE;IAClD,MAAMD,IAAAA,OACM,GACP,QAAQ,GACR,OAAO,GACP,SAAS,CAACQ,CAAAA,QACA,CAAC,CAACA,OAEZ,OAAO,CAAC;IACb,kBAAkBR,IAAAA,MACP,CAAC;QACJ,SAASA,IAAI,OAAO;QACpB,QAAQA,IAAAA,KACE,CACFA,IAAI,MAAM,CAAC;YACP,OAAOC;YACP,OAAOA;YACP,UAAUD,IAAI,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;QAC/C,IAEH,OAAO,CAAC,EAAE;IACnB,GACC,OAAO,CAAC;QACL,SAAS;QACT,QAAQ,EAAE;IACd,GACC,OAAO,GACP,QAAQ,GACR,SAAS,CAACQ,CAAAA,QACAA,SAASE;IAExB,UAAUV,IAAAA,MACC,CAAC;QACJ,MAAMC;QACN,UAAUD,IAAI,WAAW,CAAC,CAAC,GAAG,OAAO,GAAG,QAAQ;IACpD,GACC,QAAQ,GACR,QAAQ,GACR,OAAO,CAAC;IACb,YAAYA,IAAAA,KACF,CACFA,IAAI,MAAM,CAAC;QACP,MAAMC;QACN,SAASE,oBAAoB,OAAO,CAAC;QACrC,UAAUH,IAAAA,WACM,CAAC,CAAC,GACb,QAAQ,GACR,OAAO,GACP,SAAS,CAACQ,CAAAA,QACAA,SAAS,CAAC,GAEpB,OAAO,CAAC,CAAC;IAClB,IAEH,OAAO,GACP,QAAQ,GACR,OAAO,CAAC,EAAE,EACV,SAAS,CAACA,CAAAA,QAASA,SAAS,EAAE;IACnC,gBAAgBR,IAAAA,KACN,CACFA,IAAI,MAAM,CAAC;QACP,MAAMC;QACN,SAASE,oBAAoB,OAAO,CAAC;QACrC,UAAUH,IAAAA,WACM,CAAC,CAAC,GACb,QAAQ,GACR,OAAO,GACP,SAAS,CAACQ,CAAAA,QACAA,SAAS,CAAC,GAEpB,OAAO,CAAC,CAAC;IAClB,IAEH,OAAO,GACP,QAAQ,GACR,OAAO,CAAC,EAAE,EACV,SAAS,CAACA,CAAAA,QAASA,SAAS,EAAE;IACnC,UAAUR,IAAAA,WACM,CAAC,CAAC,GACb,QAAQ,GACR,OAAO,GACP,SAAS,CAACQ,CAAAA,QACAA,SAAS,CAAC,GAEpB,OAAO,CAAC,CAAC;IACd,OAAOR,IAAAA,KACG,CACFA,IAAI,MAAM,CAAC;QACP,MAAMA,GAAG,CAAHA,OAAQ,CAAC;YAAC;YAAiB;SAAa;QAC9C,QAAQC;QACR,UAAUA;QACV,OAAOD,IAAI,KAAK,CAAC;YAACA,IAAI,MAAM;YAAIA,IAAI,MAAM;YAAIA,IAAI,OAAO;YAAIA,GAAG,CAAHA,OAAQ;SAAG;QACxE,QAAQC;IACZ,IAEH,QAAQ,GACR,OAAO,GACP,OAAO,CAAC,EAAE,EACV,SAAS,CAACO,CAAAA,QAASA,SAAS,EAAE;AACvC;AAEA,MAAMG,8BAA8B,CAACH;IACjC,IAAIA,AAA0B,SAA1BA,MAAM,KAAK,CAAC,WACZ,OAAO;IAEX,OAAOA,UAAUI,WAAWC,UAAUL;AAC1C;AACA,MAAMM,sCAAsC,CAACN,QAClC;QACH,SAAS,CAAC,6BAA6B,EACnCA,SAAS,YACZ,uGAAuG,CAAC;IAC7G;AAEJ,MAAMO,oCAAoC,CAACP,QAChC;QACH,SAAS,CAAC,2BAA2B,EACjCA,SAAS,YACZ,0GAA0G,CAAC;IAChH;AAGJ,MAAMQ,wBAAwB,CAACR,OAAeS;IAC1C,IAAI,CAACN,4BAA4BH,QAC7BS,IAAI,QAAQ,CAAC;QACT,MAAMjB,IAAI,YAAY,CAAC,MAAM;QAC7B,GAAGc,oCAAoCN,MAAM;IACjD;AAER;AAEA,MAAMU,sBAAsB,CAACV,OAAeS;IACxC,IAAI,CAACN,4BAA4BH,QAC7BS,IAAI,QAAQ,CAAC;QACT,MAAMjB,IAAI,YAAY,CAAC,MAAM;QAC7B,GAAGe,kCAAkCP,MAAM;IAC/C;AAER;AAEA,MAAMW,wBAAwB,CAACX;IAC3B,IAAI,CAACA,OACD,OAAOA;IAEX,MAAMY,kBAAkBP,UAAUL;IAClC,IAAIY,gBAAgB,WAAW,OAAOZ,MAAM,WAAW,IACnD,OAAOA;IAEX,OAAOY;AACX;AAEO,MAAMC,8BAA8B,IAChCrB,IAAI,MAAM,CAAC;QACd,MAAMC;QACN,SAASE,oBAAoB,SAAS,CAACgB;QACvC,iBAAiBlB,YAAY,GAAG,CAAC,GAAG,WAAW,CAACe;QAChD,eAAef,YAAY,GAAG,CAAC,GAAG,WAAW,CAACiB;QAC9C,aAAab,2BAA2B,SAAS,CAACG,CAAAA,QACvCA,SAAS;QAEpB,OAAOP;QACPM,MAAAA;QACA,QAAQP,IAAI,KAAK,CAACS,aAAa,OAAO,CAAC,EAAE;QACzC,QAAQT,IAAI,KAAK,CAACA,IAAI,KAAK,CAACA,IAAI,GAAG,KAAK,OAAO,CAAC,EAAE;QAClD,MAAMA,IAAI,KAAK,CAACC,aAAa,QAAQ;QACrC,cAAcE,oBAAoB,OAAO;QACzC,oBAAoBA,oBAAoB,OAAO;QAC/C,cAAcA,oBAAoB,OAAO;QACzC,eAAeH,IAAI,OAAO,GAAG,OAAO;IACxC;AAGG,MAAMsB,8BAA8B,IAChCtB,IAAI,MAAM,CAAC;QACd,MAAMG;QACN,iBAAiBA,oBAAoB,WAAW,CAAC,CAACK,OAAOS;YACrD,IAAIT,OACAQ,sBAAsBR,OAAOS;QAErC;QACA,eAAed,oBAAoB,WAAW,CAAC,CAACK,OAAOS;YACnD,IAAIT,OACAU,oBAAoBV,OAAOS;QAEnC;QACA,aAAaZ;QACb,OAAOF;QACPI,MAAAA;QACA,QAAQP,IAAI,KAAK,CAACS;QAClB,QAAQT,IAAI,KAAK,CAACA,IAAI,KAAK,CAACA,IAAI,GAAG;QACnC,cAAcG,oBAAoB,OAAO;QACzC,oBAAoBA,oBAAoB,OAAO;QAC/C,cAAcA,oBAAoB,OAAO;QACzC,MAAMH,IAAI,KAAK,CAACC,aAAa,QAAQ;IACzC;AAGG,MAAMsB,kCAAkC,IACpCvB,IAAI,MAAM,CAAC;QACd,MAAMC;QACN,SAASE,oBAAoB,SAAS,CAACgB;QACvC,iBAAiBlB,YAAY,WAAW,CAACe;QACzC,eAAef,YAAY,WAAW,CAACiB;QACvC,aAAab;QACb,OAAOJ;QACPM,MAAAA;IACJ"}
|
|
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";
|