@webiny/api-headless-cms 6.4.12-beta.5 → 6.5.0-beta.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/crud/contentEntry/entryDataValidation.d.ts +1 -1
- package/crud/contentEntry/entryDataValidation.js +33 -18
- package/crud/contentEntry/entryDataValidation.js.map +1 -1
- package/crud/contentEntry.crud.js +12 -39
- package/crud/contentEntry.crud.js.map +1 -1
- package/crud/contentModel/defaultFields.js +3 -2
- package/crud/contentModel/defaultFields.js.map +1 -1
- package/crud/contentModel/validate/endingAllowed.js +1 -1
- package/crud/contentModel/validate/endingAllowed.js.map +1 -1
- package/crud/contentModel/validate/pluralApiName.js +1 -1
- package/crud/contentModel/validate/pluralApiName.js.map +1 -1
- package/crud/contentModel/validate/singularApiName.js +1 -1
- package/crud/contentModel/validate/singularApiName.js.map +1 -1
- package/crud/contentModel/validation.js +2 -2
- package/crud/contentModel/validation.js.map +1 -1
- package/domain/contentModel/schemas.d.ts +4 -0
- package/domain/contentModel/schemas.js +5 -2
- package/domain/contentModel/schemas.js.map +1 -1
- package/domain/contentModel/validation/endingAllowed.js +1 -1
- package/domain/contentModel/validation/endingAllowed.js.map +1 -1
- package/domain/contentModel/validation/pluralApiName.js +1 -1
- package/domain/contentModel/validation/pluralApiName.js.map +1 -1
- package/domain/contentModel/validation/singularApiName.js +1 -1
- package/domain/contentModel/validation/singularApiName.js.map +1 -1
- package/export/crud/exporting.js +2 -2
- package/export/crud/exporting.js.map +1 -1
- package/export/crud/imports/importGroups.js +2 -1
- package/export/crud/imports/importGroups.js.map +1 -1
- package/export/crud/imports/validateModels.js +1 -1
- package/export/crud/imports/validateModels.js.map +1 -1
- package/exports/api/cms/model.d.ts +4 -1
- package/exports/api/cms/model.js +2 -0
- package/extension.d.ts +3 -0
- package/extension.js +19 -0
- package/extension.js.map +1 -0
- package/features/contentEntry/ContentEntriesFeature.js +2 -0
- package/features/contentEntry/ContentEntriesFeature.js.map +1 -1
- package/features/contentEntry/CreateEntry/CreateEntryUseCase.js +1 -2
- package/features/contentEntry/CreateEntry/CreateEntryUseCase.js.map +1 -1
- package/features/contentEntry/CreateEntryRevisionFrom/CreateEntryRevisionFromUseCase.d.ts +1 -3
- package/features/contentEntry/CreateEntryRevisionFrom/CreateEntryRevisionFromUseCase.js +4 -12
- package/features/contentEntry/CreateEntryRevisionFrom/CreateEntryRevisionFromUseCase.js.map +1 -1
- package/features/contentEntry/CreateEntryRevisionFrom/abstractions.d.ts +2 -0
- package/features/contentEntry/CreateEntryRevisionFrom/abstractions.js.map +1 -1
- package/features/contentEntry/DeleteEntryRevision/DeleteEntryRevisionRepository.js +1 -0
- package/features/contentEntry/DeleteEntryRevision/DeleteEntryRevisionRepository.js.map +1 -1
- package/features/contentEntry/GetSingletonEntry/GetSingletonEntryUseCase.js +1 -3
- package/features/contentEntry/GetSingletonEntry/GetSingletonEntryUseCase.js.map +1 -1
- package/features/contentEntry/PublishEntry/PublishEntryUseCase.d.ts +1 -3
- package/features/contentEntry/PublishEntry/PublishEntryUseCase.js +4 -10
- package/features/contentEntry/PublishEntry/PublishEntryUseCase.js.map +1 -1
- package/features/contentEntry/RepublishEntry/RepublishEntryUseCase.js +3 -1
- package/features/contentEntry/RepublishEntry/RepublishEntryUseCase.js.map +1 -1
- package/features/contentEntry/UnpublishEntry/UnpublishEntryUseCase.js +3 -1
- package/features/contentEntry/UnpublishEntry/UnpublishEntryUseCase.js.map +1 -1
- package/features/contentEntry/UpdateEntry/UpdateEntryUseCase.js +3 -1
- package/features/contentEntry/UpdateEntry/UpdateEntryUseCase.js.map +1 -1
- package/features/contentEntry/UpdateRevision/UpdateRevisionRepository.d.ts +14 -0
- package/features/contentEntry/UpdateRevision/UpdateRevisionRepository.js +34 -0
- package/features/contentEntry/UpdateRevision/UpdateRevisionRepository.js.map +1 -0
- package/features/contentEntry/UpdateRevision/abstractions.d.ts +10 -0
- package/features/contentEntry/UpdateRevision/abstractions.js +5 -0
- package/features/contentEntry/UpdateRevision/abstractions.js.map +1 -0
- package/features/contentEntry/UpdateRevision/feature.d.ts +4 -0
- package/features/contentEntry/UpdateRevision/feature.js +11 -0
- package/features/contentEntry/UpdateRevision/feature.js.map +1 -0
- package/features/contentEntry/UpdateRevision/index.d.ts +1 -0
- package/features/contentEntry/UpdateRevision/index.js +1 -0
- package/features/contentEntry/UpdateRevisionDescription/UpdateRevisionDescriptionUseCase.d.ts +2 -2
- package/features/contentEntry/UpdateRevisionDescription/UpdateRevisionDescriptionUseCase.js +2 -2
- package/features/contentEntry/UpdateRevisionDescription/UpdateRevisionDescriptionUseCase.js.map +1 -1
- package/features/contentEntry/ensureItemIds.d.ts +13 -0
- package/features/contentEntry/ensureItemIds.js +22 -0
- package/features/contentEntry/ensureItemIds.js.map +1 -0
- package/features/contentEntry/entryDataFactories/CreateEntryDataFactory/CreateEntryDataFactory.d.ts +3 -1
- package/features/contentEntry/entryDataFactories/CreateEntryDataFactory/CreateEntryDataFactory.js +9 -3
- package/features/contentEntry/entryDataFactories/CreateEntryDataFactory/CreateEntryDataFactory.js.map +1 -1
- package/features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/CreateEntryRevisionFromDataFactory.d.ts +7 -5
- package/features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/CreateEntryRevisionFromDataFactory.js +48 -18
- package/features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/CreateEntryRevisionFromDataFactory.js.map +1 -1
- package/features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/abstractions.d.ts +17 -1
- package/features/contentEntry/entryDataFactories/CreateEntryRevisionFromDataFactory/abstractions.js.map +1 -1
- package/features/contentEntry/entryDataFactories/CreatePublishEntryDataFactory/CreatePublishEntryDataFactory.d.ts +5 -3
- package/features/contentEntry/entryDataFactories/CreatePublishEntryDataFactory/CreatePublishEntryDataFactory.js +22 -16
- package/features/contentEntry/entryDataFactories/CreatePublishEntryDataFactory/CreatePublishEntryDataFactory.js.map +1 -1
- package/features/contentEntry/entryDataFactories/CreatePublishEntryDataFactory/abstractions.d.ts +15 -1
- package/features/contentEntry/entryDataFactories/CreatePublishEntryDataFactory/abstractions.js.map +1 -1
- package/features/contentEntry/entryDataFactories/CreateRepublishEntryDataFactory/CreateRepublishEntryDataFactory.d.ts +5 -3
- package/features/contentEntry/entryDataFactories/CreateRepublishEntryDataFactory/CreateRepublishEntryDataFactory.js +17 -13
- package/features/contentEntry/entryDataFactories/CreateRepublishEntryDataFactory/CreateRepublishEntryDataFactory.js.map +1 -1
- package/features/contentEntry/entryDataFactories/CreateRepublishEntryDataFactory/abstractions.d.ts +13 -1
- package/features/contentEntry/entryDataFactories/CreateRepublishEntryDataFactory/abstractions.js.map +1 -1
- package/features/contentEntry/entryDataFactories/CreateUnpublishEntryDataFactory/CreateUnpublishEntryDataFactory.d.ts +6 -6
- package/features/contentEntry/entryDataFactories/CreateUnpublishEntryDataFactory/CreateUnpublishEntryDataFactory.js +17 -18
- package/features/contentEntry/entryDataFactories/CreateUnpublishEntryDataFactory/CreateUnpublishEntryDataFactory.js.map +1 -1
- package/features/contentEntry/entryDataFactories/CreateUnpublishEntryDataFactory/abstractions.d.ts +14 -2
- package/features/contentEntry/entryDataFactories/CreateUnpublishEntryDataFactory/abstractions.js.map +1 -1
- package/features/contentEntry/entryDataFactories/UpdateEntryDataFactory/UpdateEntryDataFactory.d.ts +7 -3
- package/features/contentEntry/entryDataFactories/UpdateEntryDataFactory/UpdateEntryDataFactory.js +73 -30
- package/features/contentEntry/entryDataFactories/UpdateEntryDataFactory/UpdateEntryDataFactory.js.map +1 -1
- package/features/contentEntry/entryDataFactories/UpdateEntryDataFactory/abstractions.d.ts +15 -1
- package/features/contentEntry/entryDataFactories/UpdateEntryDataFactory/abstractions.js.map +1 -1
- package/features/contentEntry/entryDataFactories/expiresAt.js +2 -2
- package/features/contentEntry/entryDataFactories/expiresAt.js.map +1 -1
- package/features/contentEntry/entryDataFactories/hasEntryContentChanged.d.ts +24 -0
- package/features/contentEntry/entryDataFactories/hasEntryContentChanged.js +13 -0
- package/features/contentEntry/entryDataFactories/hasEntryContentChanged.js.map +1 -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 +6 -0
- package/features/contentModel/ContentModelFeature.js.map +1 -1
- package/features/contentModel/CreateModel/CreateModelRepository.js +2 -1
- package/features/contentModel/CreateModel/CreateModelRepository.js.map +1 -1
- package/features/contentModel/CreateModelFrom/CreateModelFromRepository.js +2 -1
- package/features/contentModel/CreateModelFrom/CreateModelFromRepository.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.d.ts +16 -0
- package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js +54 -0
- package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js.map +1 -0
- package/features/contentModel/ValuesSelectionGenerator/abstractions.d.ts +8 -0
- package/features/contentModel/ValuesSelectionGenerator/abstractions.js +5 -0
- package/features/contentModel/ValuesSelectionGenerator/abstractions.js.map +1 -0
- package/features/contentModel/ValuesSelectionGenerator/feature.d.ts +4 -0
- package/features/contentModel/ValuesSelectionGenerator/feature.js +11 -0
- package/features/contentModel/ValuesSelectionGenerator/feature.js.map +1 -0
- package/features/contentModel/ValuesSelectionGenerator/index.d.ts +1 -0
- package/features/contentModel/ValuesSelectionGenerator/index.js +1 -0
- 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 +153 -0
- package/features/graphql/fields/base/AssetToGraphQL.js.map +1 -0
- package/features/graphql/fields/base/DynamicZoneToGraphQL.js +12 -2
- package/features/graphql/fields/base/DynamicZoneToGraphQL.js.map +1 -1
- package/features/graphql/fields/base/ObjectToGraphQL.js +8 -5
- package/features/graphql/fields/base/ObjectToGraphQL.js.map +1 -1
- package/features/modelBuilder/abstractions.d.ts +9 -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/DataFieldBuilder.d.ts +62 -18
- package/features/modelBuilder/fields/DataFieldBuilder.js +8 -0
- package/features/modelBuilder/fields/DataFieldBuilder.js.map +1 -1
- package/features/modelBuilder/fields/DynamicZoneFieldType.d.ts +1 -0
- package/features/modelBuilder/fields/DynamicZoneFieldType.js +2 -6
- package/features/modelBuilder/fields/DynamicZoneFieldType.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/storage/fields/CompressedTextStorageTransform.js +1 -1
- package/features/storage/fields/CompressedTextStorageTransform.js.map +1 -1
- package/features/storage/fields/DateStorageTransform.js +4 -3
- package/features/storage/fields/DateStorageTransform.js.map +1 -1
- package/features/storage/fields/DynamicZoneStorageTransform.js +2 -2
- package/features/storage/fields/DynamicZoneStorageTransform.js.map +1 -1
- package/features/storage/fields/JsonStorageTransform.js +1 -1
- package/features/storage/fields/JsonStorageTransform.js.map +1 -1
- package/features/storage/fields/LongTextStorageTransform.js +1 -1
- package/features/storage/fields/LongTextStorageTransform.js.map +1 -1
- package/features/storage/fields/ObjectStorageTransform.js +27 -7
- package/features/storage/fields/ObjectStorageTransform.js.map +1 -1
- package/features/storage/fields/RichTextStorageTransform.js +1 -1
- package/features/storage/fields/RichTextStorageTransform.js.map +1 -1
- package/features/validation/validators/DateGteValidator.js +1 -1
- package/features/validation/validators/DateGteValidator.js.map +1 -1
- package/features/validation/validators/DateLteValidator.js +1 -1
- package/features/validation/validators/DateLteValidator.js.map +1 -1
- package/features/validation/validators/PatternValidator.js +1 -1
- package/features/validation/validators/PatternValidator.js.map +1 -1
- package/features/whereMapper/WhereMapper.js +10 -7
- package/features/whereMapper/WhereMapper.js.map +1 -1
- package/fieldConverters/CmsModelDynamicZoneFieldConverterPlugin.js +8 -2
- package/fieldConverters/CmsModelDynamicZoneFieldConverterPlugin.js.map +1 -1
- package/fieldConverters/CmsModelObjectFieldConverterPlugin.js +8 -2
- package/fieldConverters/CmsModelObjectFieldConverterPlugin.js.map +1 -1
- package/fieldConverters/index.d.ts +1 -1
- package/graphql/getSchema/generateCacheKey.js +1 -1
- package/graphql/getSchema/generateCacheKey.js.map +1 -1
- package/graphql/scalars/RevisionId.js +1 -1
- package/graphql/scalars/RevisionId.js.map +1 -1
- package/graphql/schema/baseSchema.js +5 -25
- package/graphql/schema/baseSchema.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.d.ts +1 -0
- package/graphql/schema/cms/helpers.js +1 -0
- package/graphql/schema/cms/index.js +2 -1
- package/graphql/schema/cms/index.js.map +1 -1
- 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 +40 -1
- package/graphql/schema/contentModels.js.map +1 -1
- package/graphql/schema/createFieldResolvers.js +1 -1
- package/graphql/schema/createFieldResolvers.js.map +1 -1
- package/index.d.ts +2 -5
- package/index.js +1 -21
- package/package.json +27 -30
- package/plugins/CmsModelPlugin.js +12 -10
- package/plugins/CmsModelPlugin.js.map +1 -1
- package/types/fields/dynamicZoneField.d.ts +1 -0
- package/types/model.d.ts +6 -0
- package/types/modelField.d.ts +13 -0
- package/types/types.d.ts +8 -4
- package/types/types.js.map +1 -1
- package/utils/caching/Cache.js +1 -1
- package/utils/caching/Cache.js.map +1 -1
- package/utils/contentModelToJsonSchema/CmsModelToJsonSchemaConverter.d.ts +28 -0
- package/utils/contentModelToJsonSchema/CmsModelToJsonSchemaConverter.js +324 -0
- package/utils/contentModelToJsonSchema/CmsModelToJsonSchemaConverter.js.map +1 -0
- package/utils/contentModelToJsonSchema/index.d.ts +2 -0
- package/utils/contentModelToJsonSchema/index.js +1 -0
- package/utils/contentModelToJsonSchema/types.d.ts +24 -0
- package/utils/contentModelToJsonSchema/types.js +0 -0
- package/utils/createModelField.js +2 -1
- package/utils/createModelField.js.map +1 -1
- package/utils/date.js +1 -1
- package/utils/date.js.map +1 -1
- package/utils/entryStorage.js +1 -1
- package/utils/entryStorage.js.map +1 -1
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/renderFields.js +1 -1
- package/utils/renderFields.js.map +1 -1
- package/index.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/modelBuilder/fields/DataFieldBuilder.js","sources":["../../../../src/features/modelBuilder/fields/DataFieldBuilder.ts"],"sourcesContent":["import camelCase from \"lodash/camelCase.js\";\nimport type {\n CmsModelField,\n CmsModelFieldPredefinedValues,\n CmsModelFieldValidation\n} from \"~/types/index.js\";\nimport { getBaseFieldType } from \"~/utils/getBaseFieldType.js\";\nimport { BaseFieldBuilder, type DataFieldBuildResult } from \"./BaseFieldBuilder.js\";\n\nexport interface FieldBuilderConfig extends Omit<\n CmsModelField,\n \"id\" | \"fieldId\" | \"storageId\" | \"type\"\n> {\n _storageId?: string;\n _fieldId?: string;\n description?: string | null;\n note?: string | null;\n}\n\n/**\n * Augmentable renderer registry. Each entry maps a renderer name to its applicable field type(s) and settings.\n */\nexport interface IFieldRendererRegistry {\n switch: {\n fieldType: \"boolean\";\n settings: undefined;\n };\n checkboxes: {\n fieldType: \"text\" | \"number\";\n settings: undefined;\n };\n dateTimeInput: {\n fieldType: \"datetime\";\n settings: undefined;\n };\n dateTimeInputs: {\n fieldType: \"datetime\";\n settings?: {\n multiValue?: {\n addValueButtonLabel?: string;\n };\n };\n };\n dynamicZone: {\n fieldType: \"dynamicZone\";\n settings?: {\n open?: boolean;\n };\n };\n hidden: {\n fieldType: string;\n settings: undefined;\n };\n lexicalEditor: {\n fieldType: \"rich-text\";\n settings: undefined;\n };\n lexicalEditors: {\n fieldType: \"rich-text\";\n settings?: {\n multiValue?: {\n addValueButtonLabel?: string;\n };\n };\n };\n textarea: {\n fieldType: \"long-text\";\n settings: undefined;\n };\n textareas: {\n fieldType: \"long-text\";\n settings: {\n multiValue?: {\n addValueButtonLabel?: string;\n };\n };\n };\n numberInput: {\n fieldType: \"number\";\n settings: undefined;\n };\n numberInputs: {\n fieldType: \"number\";\n settings?: {\n multiValue?: {\n addValueButtonLabel?: string;\n };\n };\n };\n objectAccordionSingle: {\n fieldType: \"object\";\n settings?: {\n open?: boolean;\n };\n };\n objectAccordionMultiple: {\n fieldType: \"object\";\n settings?: {\n open?: boolean;\n multiValue?: {\n addValueButtonLabel?: string;\n };\n };\n };\n passthrough: {\n fieldType: string;\n settings: undefined;\n };\n radioButtons: {\n fieldType: \"text\" | \"number\";\n settings: undefined;\n };\n refDialogSingle: {\n fieldType: \"ref\";\n settings: undefined;\n };\n refDialogMultiple: {\n fieldType: \"ref\";\n settings?: {\n newItemPosition?: \"first\" | \"last\";\n };\n };\n refAutocompleteSingle: {\n fieldType: \"ref\";\n settings: undefined;\n };\n refAutocompleteMultiple: {\n fieldType: \"ref\";\n settings: undefined;\n };\n refCheckboxes: {\n fieldType: \"ref\";\n settings: undefined;\n };\n refRadioButtons: {\n fieldType: \"ref\";\n settings: undefined;\n };\n dropdown: {\n fieldType: \"text\" | \"number\";\n settings: undefined;\n };\n tags: {\n fieldType: \"text\";\n settings: undefined;\n };\n textInput: {\n fieldType: \"text\";\n settings: undefined;\n };\n textInputs: {\n fieldType: \"text\";\n settings?: {\n multiValue?: {\n addValueButtonLabel?: string;\n };\n };\n };\n file: {\n fieldType: \"file\";\n settings?: {\n imagesOnly?: boolean;\n };\n };\n files: {\n fieldType: \"file\";\n settings?: {\n imagesOnly?: boolean;\n };\n };\n uiSeparator: {\n fieldType: \"ui\";\n settings: undefined;\n };\n uiAlert: {\n fieldType: \"ui\";\n settings: {\n type: \"info\" | \"success\" | \"warning\" | \"danger\";\n };\n };\n uiTabs: {\n fieldType: \"ui\";\n settings: undefined;\n };\n}\n\n/**\n * Maps camelCase renderer names (used in the builder API) to the\n * kebab-case names expected by the frontend renderer registry.\n */\nconst rendererNameMap: Record<keyof IFieldRendererRegistry, string> = {\n switch: \"boolean-input\",\n checkboxes: \"checkboxes\",\n dateTimeInput: \"date-time-input\",\n dateTimeInputs: \"date-time-inputs\",\n dynamicZone: \"dynamicZone\",\n hidden: \"hidden\",\n lexicalEditor: \"lexical-text-input\",\n lexicalEditors: \"lexical-text-inputs\",\n textarea: \"long-text-text-area\",\n textareas: \"long-text-inputs\",\n numberInput: \"number-input\",\n numberInputs: \"number-inputs\",\n objectAccordionSingle: \"object-accordion\",\n objectAccordionMultiple: \"objects-accordion\",\n passthrough: \"passthrough\",\n radioButtons: \"radio-buttons\",\n refDialogSingle: \"ref-advanced-single\",\n refDialogMultiple: \"ref-advanced-multiple\",\n refAutocompleteSingle: \"ref-input\",\n refAutocompleteMultiple: \"ref-inputs\",\n refCheckboxes: \"ref-simple-multiple\",\n refRadioButtons: \"ref-simple-single\",\n dropdown: \"select-box\",\n tags: \"tags\",\n textInput: \"text-input\",\n textInputs: \"text-inputs\",\n file: \"file-input\",\n files: \"file-inputs\",\n uiSeparator: \"uiSeparator\",\n uiAlert: \"uiAlert\",\n uiTabs: \"uiTabs\"\n};\n\n/**\n * Resolves a camelCase renderer name to the kebab-case name used by the frontend.\n */\nfunction resolveRendererName(name: string): string {\n return rendererNameMap[name as keyof IFieldRendererRegistry] ?? name;\n}\n\n/**\n * Extracts renderer names valid for the given field type.\n * When TType is a broad `string`, all renderer names are returned.\n */\nexport type FieldRendererName<TType extends string = string> = string extends TType\n ? keyof IFieldRendererRegistry & string\n : {\n [K in keyof IFieldRendererRegistry]: TType extends IFieldRendererRegistry[K][\"fieldType\"]\n ? K\n : never;\n }[keyof IFieldRendererRegistry] &\n string;\n\nexport type FieldRendererSettings<TName extends string> = TName extends keyof IFieldRendererRegistry\n ? IFieldRendererRegistry[TName][\"settings\"]\n : Record<string, any> | undefined;\n\n/**\n * DataFieldBuilder class for data fields that produce CmsModelField instances.\n * Provides storageId, list, validation, renderer, and other data-field methods.\n */\nexport class DataFieldBuilder<TType extends string = string> extends BaseFieldBuilder<TType> {\n protected override config: FieldBuilderConfig;\n\n public constructor(type: TType, label?: string) {\n super(type, label);\n this.config = {\n label: label || \"\",\n validation: [],\n listValidation: [],\n list: false,\n predefinedValues: {\n enabled: false,\n values: []\n },\n help: null,\n placeholder: null,\n description: null,\n note: null,\n renderer: null,\n settings: {},\n tags: []\n };\n }\n\n placeholder(text: string): this {\n this.config.placeholder = text;\n return this;\n }\n\n storageId(id: string): this {\n // We do not allow developers to specify the field type!\n this.config._storageId = id.split(\"@\").pop();\n return this;\n }\n\n defaultValue(value: any): this {\n this.config.settings = { ...this.config.settings, defaultValue: value };\n return this;\n }\n\n list(): this {\n this.config.list = true;\n return this as this;\n }\n\n tags(tags: string[]): this {\n this.config.tags = tags;\n return this;\n }\n\n /**\n * List validators - these methods are available after calling list()\n */\n listMinLength(value: number, message?: string): this {\n return this.listValidation({\n name: \"minLength\",\n message: message || `At least ${value} item(s) required.`,\n settings: { value }\n });\n }\n\n listMaxLength(value: number, message?: string): this {\n return this.listValidation({\n name: \"maxLength\",\n message: message || `At most ${value} item(s) allowed.`,\n settings: { value }\n });\n }\n\n /**\n * Add a validation rule to this field.\n * This method is protected and should only be used by field-specific validator methods.\n * @internal\n */\n protected validation(validation: CmsModelFieldValidation): this {\n this.config.validation = this.config.validation || [];\n this.config.validation.push(validation);\n return this;\n }\n\n /**\n * Add a list validation rule to this field (for list fields).\n * This method is protected and should only be used by field-specific validator methods.\n * @internal\n */\n protected listValidation(validation: CmsModelFieldValidation): this {\n this.config.listValidation = this.config.listValidation || [];\n this.config.listValidation.push(validation);\n return this;\n }\n\n predefinedValues(values: CmsModelFieldPredefinedValues[\"values\"]): this {\n this.config.predefinedValues = {\n enabled: true,\n values\n };\n return this;\n }\n\n renderer<TName extends FieldRendererName<TType>>(\n name: TName,\n ...args: undefined extends FieldRendererSettings<TName>\n ? [settings?: FieldRendererSettings<TName>]\n : FieldRendererSettings<TName> extends undefined\n ? []\n : [settings: FieldRendererSettings<TName>]\n ): this {\n this.config.renderer = {\n name: resolveRendererName(name),\n settings: args[0] ?? null\n };\n return this;\n }\n\n settings(settings: Record<string, any>): this {\n this.config.settings = { ...this.config.settings, ...settings };\n return this;\n }\n\n /**\n * Build the final CmsModelField\n * @internal\n */\n build(): DataFieldBuildResult {\n const fieldId = this.config._fieldId || camelCase(this.config.label);\n const baseType = getBaseFieldType({\n type: this.type\n });\n const storageId = `${baseType}@${this.config._storageId ?? fieldId}`;\n\n return {\n type: \"data\",\n field: {\n id: fieldId,\n fieldId,\n storageId,\n type: this.getFieldType(),\n label: this.config.label,\n validation: this.config.validation || [],\n listValidation: this.config.listValidation || [],\n list: this.config.list || false,\n predefinedValues: this.config.predefinedValues || {\n enabled: false,\n values: []\n },\n help: this.config.help || null,\n placeholder: this.config.placeholder || null,\n description: this.config.description || null,\n note: this.config.note || null,\n renderer: this.config.renderer || null,\n settings: this.config.settings || {},\n tags: this.config.tags || [],\n rules: this.config.rules\n }\n };\n }\n\n private getFieldType(): string {\n if (!this.subType?.length) {\n return this.type;\n }\n return `${this.type}:${this.subType}`;\n }\n}\n"],"names":["rendererNameMap","resolveRendererName","name","DataFieldBuilder","BaseFieldBuilder","type","label","text","id","value","tags","message","validation","values","args","settings","fieldId","camelCase","baseType","getBaseFieldType","storageId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"features/modelBuilder/fields/DataFieldBuilder.js","sources":["../../../../src/features/modelBuilder/fields/DataFieldBuilder.ts"],"sourcesContent":["import camelCase from \"lodash/camelCase.js\";\nimport type {\n CmsModelField,\n CmsModelFieldPredefinedValues,\n CmsModelFieldValidation\n} from \"~/types/index.js\";\nimport { getBaseFieldType } from \"~/utils/getBaseFieldType.js\";\nimport { BaseFieldBuilder, type DataFieldBuildResult } from \"./BaseFieldBuilder.js\";\n\nexport interface FieldBuilderConfig extends Omit<\n CmsModelField,\n \"id\" | \"fieldId\" | \"storageId\" | \"type\"\n> {\n _storageId?: string;\n _fieldId?: string;\n description?: string | null;\n note?: string | null;\n}\n\n/**\n * Augmentable renderer registry. Each entry maps a renderer name to its applicable field type(s) and settings.\n */\nexport interface IFieldRendererRegistry {\n switch: {\n fieldType: \"boolean\";\n settings: undefined;\n };\n checkboxes: {\n fieldType: \"text\" | \"number\";\n settings: undefined;\n };\n dateTimeInput: {\n fieldType: \"datetime\";\n settings: undefined;\n };\n dateTimeInputs: {\n fieldType: \"datetime\";\n settings?: {\n addItemLabel?: string;\n };\n };\n dynamicZone: {\n fieldType: \"dynamicZone\";\n settings?: {\n /** Whether the accordion is expanded by default. */\n open?: boolean;\n /** Wrap the zone in a container panel. Set to `false` for a flat inline layout. */\n container?: boolean;\n /** Label for the \"add item\" button (defaults to \"Add Item\"). */\n addItemLabel?: string;\n };\n };\n hidden: {\n fieldType: string;\n settings: undefined;\n };\n lexicalEditor: {\n fieldType: \"rich-text\";\n settings: undefined;\n };\n lexicalEditors: {\n fieldType: \"rich-text\";\n settings?: {\n addItemLabel?: string;\n };\n };\n textarea: {\n fieldType: \"long-text\";\n settings: undefined;\n };\n textareas: {\n fieldType: \"long-text\";\n settings: {\n addItemLabel?: string;\n };\n };\n numberInput: {\n fieldType: \"number\";\n settings: undefined;\n };\n numberInputs: {\n fieldType: \"number\";\n settings?: {\n addItemLabel?: string;\n };\n };\n objectAccordionSingle: {\n fieldType: \"object\";\n settings?: {\n /** Whether the accordion is expanded by default. */\n open?: boolean;\n /** Wrap the object in a container panel. Set to `false` for a flat inline layout. */\n container?: boolean;\n /** Field ID whose value is used as the accordion title, or a function receiving the object data. */\n itemTitle?: string;\n /** Field ID whose value is used as the accordion description, or a function receiving the object data. */\n itemDescription?: string;\n };\n };\n objectAccordionMultiple: {\n fieldType: \"object\";\n settings?: {\n /** Whether each accordion item is expanded by default. */\n open?: boolean;\n /** Wrap the list in a container panel. Set to `false` for a flat inline layout. */\n container?: boolean;\n /** Field ID whose value is used as each item's accordion title. */\n itemTitle?: string;\n /** Field ID whose value is used as each item's accordion description. */\n itemDescription?: string;\n /** Label for the \"add item\" button (defaults to \"Add {fieldLabel}\"). */\n addItemLabel?: string;\n };\n };\n passthrough: {\n fieldType: string;\n settings: undefined;\n };\n radioButtons: {\n fieldType: \"text\" | \"number\";\n settings: undefined;\n };\n refDialogSingle: {\n fieldType: \"ref\";\n settings: undefined;\n };\n refDialogMultiple: {\n fieldType: \"ref\";\n settings?: {\n /** Where newly picked references are inserted: `\"first\"` (top) or `\"last\"` (bottom, default). */\n newItemPosition?: \"first\" | \"last\";\n };\n };\n refAutocompleteSingle: {\n fieldType: \"ref\";\n settings: undefined;\n };\n refAutocompleteMultiple: {\n fieldType: \"ref\";\n settings: undefined;\n };\n refCheckboxes: {\n fieldType: \"ref\";\n settings: undefined;\n };\n refRadioButtons: {\n fieldType: \"ref\";\n settings: undefined;\n };\n select: {\n fieldType: \"text\" | \"number\";\n settings: undefined;\n };\n /** @deprecated Use \"select\" instead. */\n dropdown: {\n fieldType: \"text\" | \"number\";\n settings: undefined;\n };\n tags: {\n fieldType: \"text\";\n settings: undefined;\n };\n textInput: {\n fieldType: \"text\";\n settings: undefined;\n };\n textInputs: {\n fieldType: \"text\";\n settings?: {\n addItemLabel?: string;\n };\n };\n /** @deprecated Use `assetField` instead. */\n file: {\n fieldType: \"file\";\n settings?: {\n /** Only allow image files to be selected. */\n imagesOnly?: boolean;\n };\n };\n /** @deprecated Use `assetFields` instead. */\n files: {\n fieldType: \"file\";\n settings?: {\n /** Only allow image files to be selected. */\n imagesOnly?: boolean;\n };\n };\n assetField: {\n fieldType: \"asset\";\n settings?: {\n /** Only allow image files to be selected. */\n imagesOnly?: boolean;\n /** MIME types or extensions to allow (e.g. `[\"image/png\", \"application/pdf\"]`). Leave empty to allow all. */\n accept?: string[];\n };\n };\n assetFields: {\n fieldType: \"asset\";\n settings?: {\n /** Only allow image files to be selected. */\n imagesOnly?: boolean;\n /** MIME types or extensions to allow (e.g. `[\"image/png\", \"application/pdf\"]`). Leave empty to allow all. */\n accept?: string[];\n };\n };\n uiSeparator: {\n fieldType: \"ui\";\n settings: undefined;\n };\n uiAlert: {\n fieldType: \"ui\";\n settings: {\n type: \"info\" | \"success\" | \"warning\" | \"danger\";\n };\n };\n uiTabs: {\n fieldType: \"ui\";\n settings: undefined;\n };\n}\n\n/**\n * Maps camelCase renderer names (used in the builder API) to the\n * kebab-case names expected by the frontend renderer registry.\n */\nconst rendererNameMap: Record<keyof IFieldRendererRegistry, string> = {\n switch: \"boolean-input\",\n checkboxes: \"checkboxes\",\n dateTimeInput: \"date-time-input\",\n dateTimeInputs: \"date-time-inputs\",\n dynamicZone: \"dynamicZone\",\n hidden: \"hidden\",\n lexicalEditor: \"lexical-text-input\",\n lexicalEditors: \"lexical-text-inputs\",\n textarea: \"long-text-text-area\",\n textareas: \"long-text-inputs\",\n numberInput: \"number-input\",\n numberInputs: \"number-inputs\",\n objectAccordionSingle: \"object-accordion\",\n objectAccordionMultiple: \"objects-accordion\",\n passthrough: \"passthrough\",\n radioButtons: \"radio-buttons\",\n refDialogSingle: \"ref-advanced-single\",\n refDialogMultiple: \"ref-advanced-multiple\",\n refAutocompleteSingle: \"ref-input\",\n refAutocompleteMultiple: \"ref-inputs\",\n refCheckboxes: \"ref-simple-multiple\",\n refRadioButtons: \"ref-simple-single\",\n select: \"select-box\",\n dropdown: \"select-box\",\n tags: \"tags\",\n textInput: \"text-input\",\n textInputs: \"text-inputs\",\n file: \"file-input\",\n files: \"file-inputs\",\n assetField: \"asset-input\",\n assetFields: \"asset-inputs\",\n uiSeparator: \"uiSeparator\",\n uiAlert: \"uiAlert\",\n uiTabs: \"uiTabs\"\n};\n\n/**\n * Resolves a camelCase renderer name to the kebab-case name used by the frontend.\n */\nfunction resolveRendererName(name: string): string {\n return rendererNameMap[name as keyof IFieldRendererRegistry] ?? name;\n}\n\n/**\n * Extracts renderer names valid for the given field type.\n * When TType is a broad `string`, all renderer names are returned.\n */\nexport type FieldRendererName<TType extends string = string> = string extends TType\n ? keyof IFieldRendererRegistry & string\n : {\n [K in keyof IFieldRendererRegistry]: TType extends IFieldRendererRegistry[K][\"fieldType\"]\n ? K\n : never;\n }[keyof IFieldRendererRegistry] &\n string;\n\nexport type FieldRendererSettings<TName extends string> = TName extends keyof IFieldRendererRegistry\n ? IFieldRendererRegistry[TName][\"settings\"]\n : Record<string, any> | undefined;\n\n/**\n * DataFieldBuilder class for data fields that produce CmsModelField instances.\n * Provides storageId, list, validation, renderer, and other data-field methods.\n */\nexport class DataFieldBuilder<TType extends string = string> extends BaseFieldBuilder<TType> {\n protected override config: FieldBuilderConfig;\n\n public constructor(type: TType, label?: string) {\n super(type, label);\n this.config = {\n label: label || \"\",\n validation: [],\n listValidation: [],\n list: false,\n predefinedValues: {\n enabled: false,\n values: []\n },\n help: null,\n placeholder: null,\n description: null,\n note: null,\n renderer: null,\n settings: {},\n tags: []\n };\n }\n\n placeholder(text: string): this {\n this.config.placeholder = text;\n return this;\n }\n\n storageId(id: string): this {\n // We do not allow developers to specify the field type!\n this.config._storageId = id.split(\"@\").pop();\n return this;\n }\n\n defaultValue(value: any): this {\n this.config.settings = { ...this.config.settings, defaultValue: value };\n return this;\n }\n\n list(): this {\n this.config.list = true;\n return this as this;\n }\n\n /**\n * Renders the field in the admin app, but doesn't let anyone edit its value.\n * Handy for values your own code owns, like an external ID or a generated slug.\n *\n * Only the admin app honours this. The API doesn't check it, so the field can\n * still be written to over GraphQL.\n */\n disabled(value = true): this {\n this.config.disabled = value;\n return this;\n }\n\n tags(tags: string[]): this {\n this.config.tags = tags;\n return this;\n }\n\n /**\n * List validators - these methods are available after calling list()\n */\n listMinLength(value: number, message?: string): this {\n return this.listValidation({\n name: \"minLength\",\n message: message || `At least ${value} item(s) required.`,\n settings: { value }\n });\n }\n\n listMaxLength(value: number, message?: string): this {\n return this.listValidation({\n name: \"maxLength\",\n message: message || `At most ${value} item(s) allowed.`,\n settings: { value }\n });\n }\n\n /**\n * Add a validation rule to this field.\n * This method is protected and should only be used by field-specific validator methods.\n * @internal\n */\n protected validation(validation: CmsModelFieldValidation): this {\n this.config.validation = this.config.validation || [];\n this.config.validation.push(validation);\n return this;\n }\n\n /**\n * Add a list validation rule to this field (for list fields).\n * This method is protected and should only be used by field-specific validator methods.\n * @internal\n */\n protected listValidation(validation: CmsModelFieldValidation): this {\n this.config.listValidation = this.config.listValidation || [];\n this.config.listValidation.push(validation);\n return this;\n }\n\n predefinedValues(values: CmsModelFieldPredefinedValues[\"values\"]): this {\n this.config.predefinedValues = {\n enabled: true,\n values\n };\n return this;\n }\n\n renderer<TName extends FieldRendererName<TType>>(\n name: TName,\n ...args: undefined extends FieldRendererSettings<TName>\n ? [settings?: FieldRendererSettings<TName>]\n : FieldRendererSettings<TName> extends undefined\n ? []\n : [settings: FieldRendererSettings<TName>]\n ): this {\n this.config.renderer = {\n name: resolveRendererName(name),\n settings: args[0] ?? null\n };\n return this;\n }\n\n settings(settings: Record<string, any>): this {\n this.config.settings = { ...this.config.settings, ...settings };\n return this;\n }\n\n /**\n * Build the final CmsModelField\n * @internal\n */\n build(): DataFieldBuildResult {\n const fieldId = this.config._fieldId || camelCase(this.config.label);\n const baseType = getBaseFieldType({\n type: this.type\n });\n const storageId = `${baseType}@${this.config._storageId ?? fieldId}`;\n\n return {\n type: \"data\",\n field: {\n id: fieldId,\n fieldId,\n storageId,\n type: this.getFieldType(),\n label: this.config.label,\n validation: this.config.validation || [],\n listValidation: this.config.listValidation || [],\n list: this.config.list || false,\n disabled: this.config.disabled || false,\n predefinedValues: this.config.predefinedValues || {\n enabled: false,\n values: []\n },\n help: this.config.help || null,\n placeholder: this.config.placeholder || null,\n description: this.config.description || null,\n note: this.config.note || null,\n renderer: this.config.renderer || null,\n settings: this.config.settings || {},\n tags: this.config.tags || [],\n rules: this.config.rules\n }\n };\n }\n\n private getFieldType(): string {\n if (!this.subType?.length) {\n return this.type;\n }\n return `${this.type}:${this.subType}`;\n }\n}\n"],"names":["rendererNameMap","resolveRendererName","name","DataFieldBuilder","BaseFieldBuilder","type","label","text","id","value","tags","message","validation","values","args","settings","fieldId","camelCase","baseType","getBaseFieldType","storageId"],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ export interface IDynamicZoneFieldBuilder extends DataFieldBuilder<"dynamicZone"
|
|
|
9
9
|
gqlTypeName: string;
|
|
10
10
|
icon?: CmsIcon;
|
|
11
11
|
description?: string;
|
|
12
|
+
componentName?: string;
|
|
12
13
|
fields: (registry: IFieldBuilderRegistry) => Record<string, BaseFieldBuilder<any>>;
|
|
13
14
|
layout?: string[][];
|
|
14
15
|
}): this;
|
|
@@ -31,6 +31,7 @@ class DynamicZoneFieldBuilder extends DataFieldBuilder {
|
|
|
31
31
|
gqlTypeName: config.gqlTypeName,
|
|
32
32
|
icon: config.icon,
|
|
33
33
|
description: config.description || "",
|
|
34
|
+
componentName: config.componentName,
|
|
34
35
|
fields,
|
|
35
36
|
layout,
|
|
36
37
|
validation: []
|
|
@@ -40,12 +41,7 @@ class DynamicZoneFieldBuilder extends DataFieldBuilder {
|
|
|
40
41
|
build() {
|
|
41
42
|
this.config.settings = this.config.settings || {};
|
|
42
43
|
this.config.settings.templates = this.templates;
|
|
43
|
-
this.config.listValidation = [
|
|
44
|
-
{
|
|
45
|
-
name: "dynamicZone",
|
|
46
|
-
message: ""
|
|
47
|
-
}
|
|
48
|
-
];
|
|
44
|
+
this.config.listValidation = [];
|
|
49
45
|
return super.build();
|
|
50
46
|
}
|
|
51
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/modelBuilder/fields/DynamicZoneFieldType.js","sources":["../../../../src/features/modelBuilder/fields/DynamicZoneFieldType.ts"],"sourcesContent":["import { FieldType, type IFieldTypeFactory } from \"./abstractions.js\";\nimport { type FieldBuildResult } from \"./BaseFieldBuilder.js\";\nimport { DataFieldBuilder, type BaseFieldBuilder } from \"./FieldBuilder.js\";\nimport { type IFieldBuilderRegistry } from \"../abstractions.js\";\nimport type {\n CmsIcon,\n CmsModelField,\n CmsModelFieldValidation,\n CmsModelLayoutCell\n} from \"~/types/index.js\";\n\ninterface IDynamicZoneTemplate {\n id: string;\n name: string;\n gqlTypeName: string;\n icon: CmsIcon | undefined;\n description: string;\n fields: any[];\n layout: CmsModelLayoutCell[][];\n validation: CmsModelFieldValidation[];\n}\n\nexport interface IDynamicZoneFieldBuilder extends DataFieldBuilder<\"dynamicZone\"> {\n required(message?: string): this;\n template(\n id: string,\n config: {\n name: string;\n gqlTypeName: string;\n icon?: CmsIcon;\n description?: string;\n fields: (registry: IFieldBuilderRegistry) => Record<string, BaseFieldBuilder<any>>;\n layout?: string[][];\n }\n ): this;\n}\n\ninterface IDynamicZoneFieldBuilderTemplateConfig {\n name: string;\n gqlTypeName: string;\n icon?: CmsIcon;\n description?: string;\n fields: (registry: IFieldBuilderRegistry) => Record<string, BaseFieldBuilder<any>>;\n layout?: string[][];\n}\n\nclass DynamicZoneFieldBuilder\n extends DataFieldBuilder<\"dynamicZone\">\n implements IDynamicZoneFieldBuilder\n{\n private readonly templates: IDynamicZoneTemplate[] = [];\n\n public constructor(private registry: IFieldBuilderRegistry) {\n super(\"dynamicZone\");\n }\n\n public required(message?: string): this {\n return this.validation({\n name: \"required\",\n message: message || \"Field is required\",\n settings: {}\n });\n }\n\n public template(id: string, config: IDynamicZoneFieldBuilderTemplateConfig): this {\n const fieldBuilders = config.fields(this.registry);\n const fields: CmsModelField[] = [];\n const layoutReplacements = new Map<string, CmsModelLayoutCell>();\n\n for (const [key, fieldBuilder] of Object.entries(fieldBuilders)) {\n fieldBuilder.fieldId(key);\n const result: FieldBuildResult = (fieldBuilder as any).build();\n if (result.type === \"layout\") {\n layoutReplacements.set(key, result.layoutCell);\n if (result.fields) {\n fields.push(...result.fields);\n }\n } else {\n fields.push(result.field);\n }\n }\n\n const rawLayout: string[][] = config.layout || [];\n const layout = rawLayout.map(row => row.map(cell => layoutReplacements.get(cell) ?? cell));\n\n this.templates.push({\n id,\n name: config.name,\n gqlTypeName: config.gqlTypeName,\n icon: config.icon,\n description: config.description || \"\",\n fields,\n layout,\n validation: []\n });\n\n return this;\n }\n\n public override build() {\n // Set templates in settings before building\n this.config.settings = this.config.settings || {};\n this.config.settings.templates = this.templates;\n this.config.listValidation = [
|
|
1
|
+
{"version":3,"file":"features/modelBuilder/fields/DynamicZoneFieldType.js","sources":["../../../../src/features/modelBuilder/fields/DynamicZoneFieldType.ts"],"sourcesContent":["import { FieldType, type IFieldTypeFactory } from \"./abstractions.js\";\nimport { type FieldBuildResult } from \"./BaseFieldBuilder.js\";\nimport { DataFieldBuilder, type BaseFieldBuilder } from \"./FieldBuilder.js\";\nimport { type IFieldBuilderRegistry } from \"../abstractions.js\";\nimport type {\n CmsIcon,\n CmsModelField,\n CmsModelFieldValidation,\n CmsModelLayoutCell\n} from \"~/types/index.js\";\n\ninterface IDynamicZoneTemplate {\n id: string;\n name: string;\n gqlTypeName: string;\n icon: CmsIcon | undefined;\n description: string;\n componentName?: string;\n fields: any[];\n layout: CmsModelLayoutCell[][];\n validation: CmsModelFieldValidation[];\n}\n\nexport interface IDynamicZoneFieldBuilder extends DataFieldBuilder<\"dynamicZone\"> {\n required(message?: string): this;\n\n template(\n id: string,\n config: {\n name: string;\n gqlTypeName: string;\n icon?: CmsIcon;\n description?: string;\n componentName?: string;\n fields: (registry: IFieldBuilderRegistry) => Record<string, BaseFieldBuilder<any>>;\n layout?: string[][];\n }\n ): this;\n}\n\ninterface IDynamicZoneFieldBuilderTemplateConfig {\n name: string;\n gqlTypeName: string;\n icon?: CmsIcon;\n description?: string;\n componentName?: string;\n fields: (registry: IFieldBuilderRegistry) => Record<string, BaseFieldBuilder<any>>;\n layout?: string[][];\n}\n\nclass DynamicZoneFieldBuilder\n extends DataFieldBuilder<\"dynamicZone\">\n implements IDynamicZoneFieldBuilder\n{\n private readonly templates: IDynamicZoneTemplate[] = [];\n\n public constructor(private registry: IFieldBuilderRegistry) {\n super(\"dynamicZone\");\n }\n\n public required(message?: string): this {\n return this.validation({\n name: \"required\",\n message: message || \"Field is required\",\n settings: {}\n });\n }\n\n public template(id: string, config: IDynamicZoneFieldBuilderTemplateConfig): this {\n const fieldBuilders = config.fields(this.registry);\n const fields: CmsModelField[] = [];\n const layoutReplacements = new Map<string, CmsModelLayoutCell>();\n\n for (const [key, fieldBuilder] of Object.entries(fieldBuilders)) {\n fieldBuilder.fieldId(key);\n const result: FieldBuildResult = (fieldBuilder as any).build();\n if (result.type === \"layout\") {\n layoutReplacements.set(key, result.layoutCell);\n if (result.fields) {\n fields.push(...result.fields);\n }\n } else {\n fields.push(result.field);\n }\n }\n\n const rawLayout: string[][] = config.layout || [];\n const layout = rawLayout.map(row => row.map(cell => layoutReplacements.get(cell) ?? cell));\n\n this.templates.push({\n id,\n name: config.name,\n gqlTypeName: config.gqlTypeName,\n icon: config.icon,\n description: config.description || \"\",\n componentName: config.componentName,\n fields,\n layout,\n validation: []\n });\n\n return this;\n }\n\n public override build() {\n // Set templates in settings before building\n this.config.settings = this.config.settings || {};\n this.config.settings.templates = this.templates;\n this.config.listValidation = [];\n return super.build();\n }\n}\n\nclass DynamicZoneFieldTypeFactory implements IFieldTypeFactory {\n public readonly type = \"dynamicZone\";\n\n public create(registry: IFieldBuilderRegistry): IDynamicZoneFieldBuilder {\n return new DynamicZoneFieldBuilder(registry);\n }\n}\n\nexport const DynamicZoneFieldType = FieldType.createImplementation({\n implementation: DynamicZoneFieldTypeFactory,\n dependencies: []\n});\n\n// Module augmentation for TypeScript autocomplete\ndeclare module \"../abstractions.js\" {\n interface IFieldBuilderRegistry {\n dynamicZone(): IDynamicZoneFieldBuilder;\n }\n}\n"],"names":["DynamicZoneFieldBuilder","DataFieldBuilder","registry","message","id","config","fieldBuilders","fields","layoutReplacements","Map","key","fieldBuilder","Object","result","rawLayout","layout","row","cell","DynamicZoneFieldTypeFactory","DynamicZoneFieldType","FieldType"],"mappings":";;AAkDA,MAAMA,gCACMC;IAKR,YAA2BC,QAA+B,CAAE;QACxD,KAAK,CAAC,qBADiBA,QAAQ,GAARA,UAAAA,IAAAA,CAFV,SAAS,GAA2B,EAAE;IAIvD;IAEO,SAASC,OAAgB,EAAQ;QACpC,OAAO,IAAI,CAAC,UAAU,CAAC;YACnB,MAAM;YACN,SAASA,WAAW;YACpB,UAAU,CAAC;QACf;IACJ;IAEO,SAASC,EAAU,EAAEC,MAA8C,EAAQ;QAC9E,MAAMC,gBAAgBD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ;QACjD,MAAME,SAA0B,EAAE;QAClC,MAAMC,qBAAqB,IAAIC;QAE/B,KAAK,MAAM,CAACC,KAAKC,aAAa,IAAIC,OAAO,OAAO,CAACN,eAAgB;YAC7DK,aAAa,OAAO,CAACD;YACrB,MAAMG,SAA4BF,aAAqB,KAAK;YAC5D,IAAIE,AAAgB,aAAhBA,OAAO,IAAI,EAAe;gBAC1BL,mBAAmB,GAAG,CAACE,KAAKG,OAAO,UAAU;gBAC7C,IAAIA,OAAO,MAAM,EACbN,OAAO,IAAI,IAAIM,OAAO,MAAM;YAEpC,OACIN,OAAO,IAAI,CAACM,OAAO,KAAK;QAEhC;QAEA,MAAMC,YAAwBT,OAAO,MAAM,IAAI,EAAE;QACjD,MAAMU,SAASD,UAAU,GAAG,CAACE,CAAAA,MAAOA,IAAI,GAAG,CAACC,CAAAA,OAAQT,mBAAmB,GAAG,CAACS,SAASA;QAEpF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAChBb;YACA,MAAMC,OAAO,IAAI;YACjB,aAAaA,OAAO,WAAW;YAC/B,MAAMA,OAAO,IAAI;YACjB,aAAaA,OAAO,WAAW,IAAI;YACnC,eAAeA,OAAO,aAAa;YACnCE;YACAQ;YACA,YAAY,EAAE;QAClB;QAEA,OAAO,IAAI;IACf;IAEgB,QAAQ;QAEpB,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS;QAC/C,IAAI,CAAC,MAAM,CAAC,cAAc,GAAG,EAAE;QAC/B,OAAO,KAAK,CAAC;IACjB;AACJ;AAEA,MAAMG;IAGK,OAAOhB,QAA+B,EAA4B;QACrE,OAAO,IAAIF,wBAAwBE;IACvC;;aAJgB,IAAI,GAAG;;AAK3B;AAEO,MAAMiB,uBAAuBC,UAAU,oBAAoB,CAAC;IAC/D,gBAAgBF;IAChB,cAAc,EAAE;AACpB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the turnkey delivery URL for a stored Asset field value.
|
|
3
|
+
*
|
|
4
|
+
* The Asset field stores `src` as the file's **base delivery URL** (the pristine
|
|
5
|
+
* original) with the per-usage crop kept beside it in `image.crop`. The delivery
|
|
6
|
+
* pipeline frames the image only when the URL carries a `?crop=` param, so a raw
|
|
7
|
+
* `src` never reflects the per-usage crop. This helper bakes that crop into the URL
|
|
8
|
+
* — it is what the generated `url` field on the Asset GraphQL type resolves to, so a
|
|
9
|
+
* headless consumer (any framework) gets a ready-to-use URL without having to know
|
|
10
|
+
* the delivery param contract.
|
|
11
|
+
*
|
|
12
|
+
* Note: only the per-usage crop is added here. Any **asset-level** crop (set in File
|
|
13
|
+
* Manager, stored on the file's metadata) is already baked in by the delivery on any
|
|
14
|
+
* GET of the base `src`, and a per-usage crop replaces — not composes with — it, so
|
|
15
|
+
* `src` + `?crop=<per-usage>` is the correct combined result.
|
|
16
|
+
*/
|
|
17
|
+
interface AssetImageCrop {
|
|
18
|
+
top?: number | null;
|
|
19
|
+
left?: number | null;
|
|
20
|
+
bottom?: number | null;
|
|
21
|
+
right?: number | null;
|
|
22
|
+
}
|
|
23
|
+
interface AssetValue {
|
|
24
|
+
src?: string | null;
|
|
25
|
+
image?: {
|
|
26
|
+
crop?: AssetImageCrop | null;
|
|
27
|
+
} | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The stored `src` with the per-usage crop baked in as a `?crop=` delivery param.
|
|
31
|
+
* Returns `src` unchanged when there is no per-usage crop, and `null` when the value
|
|
32
|
+
* has no source.
|
|
33
|
+
*/
|
|
34
|
+
export declare const resolveAssetUrl: (asset: AssetValue | null | undefined) => string | null;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const round = (n)=>Math.round(10000 * n) / 10000;
|
|
2
|
+
const cropParam = (crop)=>{
|
|
3
|
+
if (!crop) return;
|
|
4
|
+
const top = crop.top ?? 0;
|
|
5
|
+
const left = crop.left ?? 0;
|
|
6
|
+
const bottom = crop.bottom ?? 0;
|
|
7
|
+
const right = crop.right ?? 0;
|
|
8
|
+
if (0 === top && 0 === left && 0 === bottom && 0 === right) return;
|
|
9
|
+
return [
|
|
10
|
+
top,
|
|
11
|
+
left,
|
|
12
|
+
bottom,
|
|
13
|
+
right
|
|
14
|
+
].map(round).join(",");
|
|
15
|
+
};
|
|
16
|
+
const resolveAssetUrl = (asset)=>{
|
|
17
|
+
const src = asset?.src;
|
|
18
|
+
if (!src) return null;
|
|
19
|
+
const param = cropParam(asset?.image?.crop);
|
|
20
|
+
if (!param) return src;
|
|
21
|
+
const separator = src.includes("?") ? "&" : "?";
|
|
22
|
+
return `${src}${separator}crop=${param}`;
|
|
23
|
+
};
|
|
24
|
+
export { resolveAssetUrl };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=resolveAssetUrl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/modelBuilder/fields/resolveAssetUrl.js","sources":["../../../../src/features/modelBuilder/fields/resolveAssetUrl.ts"],"sourcesContent":["/**\n * Build the turnkey delivery URL for a stored Asset field value.\n *\n * The Asset field stores `src` as the file's **base delivery URL** (the pristine\n * original) with the per-usage crop kept beside it in `image.crop`. The delivery\n * pipeline frames the image only when the URL carries a `?crop=` param, so a raw\n * `src` never reflects the per-usage crop. This helper bakes that crop into the URL\n * — it is what the generated `url` field on the Asset GraphQL type resolves to, so a\n * headless consumer (any framework) gets a ready-to-use URL without having to know\n * the delivery param contract.\n *\n * Note: only the per-usage crop is added here. Any **asset-level** crop (set in File\n * Manager, stored on the file's metadata) is already baked in by the delivery on any\n * GET of the base `src`, and a per-usage crop replaces — not composes with — it, so\n * `src` + `?crop=<per-usage>` is the correct combined result.\n */\n\ninterface AssetImageCrop {\n top?: number | null;\n left?: number | null;\n bottom?: number | null;\n right?: number | null;\n}\n\ninterface AssetValue {\n src?: string | null;\n image?: { crop?: AssetImageCrop | null } | null;\n}\n\nconst round = (n: number): number => Math.round(n * 10000) / 10000;\n\n/** `top,left,bottom,right` crop param, or `undefined` for a missing/full (no-op) crop. */\nconst cropParam = (crop: AssetImageCrop | null | undefined): string | undefined => {\n if (!crop) {\n return undefined;\n }\n const top = crop.top ?? 0;\n const left = crop.left ?? 0;\n const bottom = crop.bottom ?? 0;\n const right = crop.right ?? 0;\n if (top === 0 && left === 0 && bottom === 0 && right === 0) {\n return undefined;\n }\n return [top, left, bottom, right].map(round).join(\",\");\n};\n\n/**\n * The stored `src` with the per-usage crop baked in as a `?crop=` delivery param.\n * Returns `src` unchanged when there is no per-usage crop, and `null` when the value\n * has no source.\n */\nexport const resolveAssetUrl = (asset: AssetValue | null | undefined): string | null => {\n const src = asset?.src;\n if (!src) {\n return null;\n }\n const param = cropParam(asset?.image?.crop);\n if (!param) {\n return src;\n }\n const separator = src.includes(\"?\") ? \"&\" : \"?\";\n return `${src}${separator}crop=${param}`;\n};\n"],"names":["round","n","Math","cropParam","crop","top","left","bottom","right","resolveAssetUrl","asset","src","param","separator"],"mappings":"AA6BA,MAAMA,QAAQ,CAACC,IAAsBC,KAAK,KAAK,CAACD,AAAI,QAAJA,KAAa;AAG7D,MAAME,YAAY,CAACC;IACf,IAAI,CAACA,MACD;IAEJ,MAAMC,MAAMD,KAAK,GAAG,IAAI;IACxB,MAAME,OAAOF,KAAK,IAAI,IAAI;IAC1B,MAAMG,SAASH,KAAK,MAAM,IAAI;IAC9B,MAAMI,QAAQJ,KAAK,KAAK,IAAI;IAC5B,IAAIC,AAAQ,MAARA,OAAaC,AAAS,MAATA,QAAcC,AAAW,MAAXA,UAAgBC,AAAU,MAAVA,OAC3C;IAEJ,OAAO;QAACH;QAAKC;QAAMC;QAAQC;KAAM,CAAC,GAAG,CAACR,OAAO,IAAI,CAAC;AACtD;AAOO,MAAMS,kBAAkB,CAACC;IAC5B,MAAMC,MAAMD,OAAO;IACnB,IAAI,CAACC,KACD,OAAO;IAEX,MAAMC,QAAQT,UAAUO,OAAO,OAAO;IACtC,IAAI,CAACE,OACD,OAAOD;IAEX,MAAME,YAAYF,IAAI,QAAQ,CAAC,OAAO,MAAM;IAC5C,OAAO,GAAGA,MAAME,UAAU,KAAK,EAAED,OAAO;AAC5C"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseFieldBuilder } from "../../../features/modelBuilder/index.js";
|
|
2
2
|
import { CmsModelPlugin } from "../../../plugins/CmsModelPlugin.js";
|
|
3
|
-
import { FieldBuilderRegistry } from "../abstractions.js";
|
|
3
|
+
import { FieldBuilderRegistry, type IModelSettings } from "../abstractions.js";
|
|
4
4
|
import type { CmsModelField, CmsModelLayoutCell } from "../../../types/index.js";
|
|
5
5
|
/**
|
|
6
6
|
* Base class for all model builders, containing shared logic.
|
|
@@ -12,6 +12,7 @@ export declare abstract class BaseModelBuilder<TBuild = CmsModelPlugin> {
|
|
|
12
12
|
modelId?: string;
|
|
13
13
|
name?: string;
|
|
14
14
|
tags?: string[];
|
|
15
|
+
settings?: IModelSettings;
|
|
15
16
|
};
|
|
16
17
|
protected isSingleEntry: boolean;
|
|
17
18
|
protected fieldBuildersMap: Map<string, BaseFieldBuilder<any>>;
|
|
@@ -20,6 +21,7 @@ export declare abstract class BaseModelBuilder<TBuild = CmsModelPlugin> {
|
|
|
20
21
|
name(name: string): this;
|
|
21
22
|
singleEntry(): this;
|
|
22
23
|
tags(tags: string[]): this;
|
|
24
|
+
settings(settings: Partial<IModelSettings>): this;
|
|
23
25
|
fields(builder: (registry: FieldBuilderRegistry.Interface) => Record<string, BaseFieldBuilder<any>>): this;
|
|
24
26
|
/**
|
|
25
27
|
* Merge field operations from extension builder into existing builder.
|
|
@@ -21,6 +21,13 @@ class BaseModelBuilder {
|
|
|
21
21
|
this.config.tags = tags;
|
|
22
22
|
return this;
|
|
23
23
|
}
|
|
24
|
+
settings(settings) {
|
|
25
|
+
this.config.settings = {
|
|
26
|
+
...this.config.settings || {},
|
|
27
|
+
...settings
|
|
28
|
+
};
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
24
31
|
fields(builder) {
|
|
25
32
|
this.registry.existingFields = this.fieldBuildersMap;
|
|
26
33
|
const fieldBuilders = builder(this.registry);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/modelBuilder/models/BaseModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/BaseModelBuilder.ts"],"sourcesContent":["import { BaseFieldBuilder } from \"~/features/modelBuilder/index.js\";\nimport { CmsModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { FieldBuilderRegistry } from \"../abstractions.js\";\nimport type { CmsModelField, CmsModelLayoutCell } from \"~/types/index.js\";\n\n/**\n * Base class for all model builders, containing shared logic.\n * Concrete builders (PrivateModelBuilder, PublicModelBuilder) extend this.\n */\nexport abstract class BaseModelBuilder<TBuild = CmsModelPlugin> {\n protected config: {\n modelId?: string;\n name?: string;\n tags?: string[];\n } = {};\n\n protected isSingleEntry = false;\n protected fieldBuildersMap = new Map<string, BaseFieldBuilder<any>>();\n\n public constructor(protected registry: FieldBuilderRegistry.Interface) {}\n\n modelId(id: string): this {\n this.config.modelId = id;\n return this;\n }\n\n name(name: string): this {\n this.config.name = name;\n return this;\n }\n\n singleEntry(): this {\n this.isSingleEntry = true;\n return this;\n }\n\n tags(tags: string[]): this {\n this.config.tags = tags;\n return this;\n }\n\n fields(\n builder: (registry: FieldBuilderRegistry.Interface) => Record<string, BaseFieldBuilder<any>>\n ): this {\n // Pass existing fields to registry so it can return them when extending\n (this.registry as any).existingFields = this.fieldBuildersMap;\n\n const fieldBuilders = builder(this.registry);\n\n for (const [key, fieldBuilder] of Object.entries(fieldBuilders)) {\n // Set the fieldId from the object key\n fieldBuilder.fieldId(key);\n\n const existingBuilder = this.fieldBuildersMap.get(key);\n const isExtendMode = (fieldBuilder as any)._extendMode;\n\n if (isExtendMode && existingBuilder) {\n // Extension mode - validate type and merge operations\n if (existingBuilder.type !== fieldBuilder.type) {\n throw new Error(\n `Cannot extend field \"${key}\": type mismatch. Expected \"${existingBuilder.type}\", got \"${fieldBuilder.type}\".`\n );\n }\n // Merge operations from temporary new builder into existing builder\n this.mergeFieldOperations(key, existingBuilder, fieldBuilder);\n } else if (existingBuilder && !isExtendMode) {\n // Replacement mode - validate type\n if (existingBuilder.type !== fieldBuilder.type) {\n throw new Error(\n `Cannot redefine field \"${key}\": type mismatch. Expected \"${existingBuilder.type}\", got \"${fieldBuilder.type}\".`\n );\n }\n // Replace with new builder\n this.fieldBuildersMap.set(key, fieldBuilder);\n } else if (!existingBuilder && !isExtendMode) {\n // New field - store builder\n this.fieldBuildersMap.set(key, fieldBuilder);\n } else {\n // isExtendMode but no existingBuilder - this is an error\n throw new Error(\n `Cannot extend field \"${key}\": field does not exist. Use .extend() only for existing fields.`\n );\n }\n }\n\n return this;\n }\n\n /**\n * Merge field operations from extension builder into existing builder.\n * This handles the case where multiple fields of the same type exist,\n * and we need to transfer operations from the temporary new builder\n * to the existing builder.\n * @internal\n */\n private mergeFieldOperations(\n fieldId: string,\n existing: BaseFieldBuilder<any>,\n extension: BaseFieldBuilder<any>\n ): void {\n // For object fields, merge nested fields and layout operations\n if (existing.type === \"object\" && extension.type === \"object\") {\n const existingFieldMap = (existing as any).fieldBuildersMap;\n const extensionFieldMap = (extension as any).fieldBuildersMap;\n\n // Merge nested field builders\n if (extensionFieldMap) {\n for (const [nestedKey, nestedBuilder] of extensionFieldMap.entries()) {\n existingFieldMap.set(nestedKey, nestedBuilder);\n }\n }\n\n // Merge layout operations\n const existingLayoutBuilder = (existing as any).layoutBuilder;\n const extensionLayoutBuilder = (extension as any).layoutBuilder;\n\n if (extensionLayoutBuilder) {\n const snapshot = extensionLayoutBuilder.getSnapshot();\n\n // If extension called setLayout() with an array, apply it to existing\n // We detect this by checking if there's a layout but no modifiers\n if (snapshot.layout.length > 0 && snapshot.modifiers.length === 0) {\n existingLayoutBuilder.setLayout(snapshot.layout);\n }\n\n // Apply all modifiers from extension to existing\n for (const modifier of snapshot.modifiers) {\n existingLayoutBuilder.addModifier(modifier);\n }\n }\n }\n }\n\n protected buildFields(): {\n fields: CmsModelField[];\n layoutReplacements: Map<string, CmsModelLayoutCell>;\n } {\n const fields: CmsModelField[] = [];\n const layoutReplacements = new Map<string, CmsModelLayoutCell>();\n\n for (const [fieldId, builder] of this.fieldBuildersMap) {\n const result = builder.build();\n if (result.type === \"layout\") {\n layoutReplacements.set(fieldId, result.layoutCell);\n if (result.fields) {\n fields.push(...result.fields);\n }\n } else {\n fields.push(result.field);\n }\n }\n\n return { fields, layoutReplacements };\n }\n\n /**\n * Get tags with common defaults applied.\n * Always includes \"type:model\" and optionally \"singleEntry\".\n */\n protected getTags(): string[] {\n const tagsSet = new Set(this.config.tags || []);\n tagsSet.add(\"type:model\");\n if (this.isSingleEntry) {\n tagsSet.add(\"singleEntry\");\n }\n return Array.from(tagsSet);\n }\n\n /**\n * Build the final model configuration.\n * Must be implemented by concrete builders.\n */\n abstract build(): TBuild;\n}\n"],"names":["BaseModelBuilder","registry","Map","id","name","tags","builder","fieldBuilders","key","fieldBuilder","Object","existingBuilder","isExtendMode","Error","fieldId","existing","extension","existingFieldMap","extensionFieldMap","nestedKey","nestedBuilder","existingLayoutBuilder","extensionLayoutBuilder","snapshot","modifier","fields","layoutReplacements","result","tagsSet","Set","Array"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"features/modelBuilder/models/BaseModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/BaseModelBuilder.ts"],"sourcesContent":["import { BaseFieldBuilder } from \"~/features/modelBuilder/index.js\";\nimport { CmsModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { FieldBuilderRegistry, type IModelSettings } from \"../abstractions.js\";\nimport type { CmsModelField, CmsModelLayoutCell } from \"~/types/index.js\";\n\n/**\n * Base class for all model builders, containing shared logic.\n * Concrete builders (PrivateModelBuilder, PublicModelBuilder) extend this.\n */\nexport abstract class BaseModelBuilder<TBuild = CmsModelPlugin> {\n protected config: {\n modelId?: string;\n name?: string;\n tags?: string[];\n settings?: IModelSettings;\n } = {};\n\n protected isSingleEntry = false;\n protected fieldBuildersMap = new Map<string, BaseFieldBuilder<any>>();\n\n public constructor(protected registry: FieldBuilderRegistry.Interface) {}\n\n modelId(id: string): this {\n this.config.modelId = id;\n return this;\n }\n\n name(name: string): this {\n this.config.name = name;\n return this;\n }\n\n singleEntry(): this {\n this.isSingleEntry = true;\n return this;\n }\n\n tags(tags: string[]): this {\n this.config.tags = tags;\n return this;\n }\n\n settings(settings: Partial<IModelSettings>): this {\n this.config.settings = { ...(this.config.settings || {}), ...settings };\n return this;\n }\n\n fields(\n builder: (registry: FieldBuilderRegistry.Interface) => Record<string, BaseFieldBuilder<any>>\n ): this {\n // Pass existing fields to registry so it can return them when extending\n (this.registry as any).existingFields = this.fieldBuildersMap;\n\n const fieldBuilders = builder(this.registry);\n\n for (const [key, fieldBuilder] of Object.entries(fieldBuilders)) {\n // Set the fieldId from the object key\n fieldBuilder.fieldId(key);\n\n const existingBuilder = this.fieldBuildersMap.get(key);\n const isExtendMode = (fieldBuilder as any)._extendMode;\n\n if (isExtendMode && existingBuilder) {\n // Extension mode - validate type and merge operations\n if (existingBuilder.type !== fieldBuilder.type) {\n throw new Error(\n `Cannot extend field \"${key}\": type mismatch. Expected \"${existingBuilder.type}\", got \"${fieldBuilder.type}\".`\n );\n }\n // Merge operations from temporary new builder into existing builder\n this.mergeFieldOperations(key, existingBuilder, fieldBuilder);\n } else if (existingBuilder && !isExtendMode) {\n // Replacement mode - validate type\n if (existingBuilder.type !== fieldBuilder.type) {\n throw new Error(\n `Cannot redefine field \"${key}\": type mismatch. Expected \"${existingBuilder.type}\", got \"${fieldBuilder.type}\".`\n );\n }\n // Replace with new builder\n this.fieldBuildersMap.set(key, fieldBuilder);\n } else if (!existingBuilder && !isExtendMode) {\n // New field - store builder\n this.fieldBuildersMap.set(key, fieldBuilder);\n } else {\n // isExtendMode but no existingBuilder - this is an error\n throw new Error(\n `Cannot extend field \"${key}\": field does not exist. Use .extend() only for existing fields.`\n );\n }\n }\n\n return this;\n }\n\n /**\n * Merge field operations from extension builder into existing builder.\n * This handles the case where multiple fields of the same type exist,\n * and we need to transfer operations from the temporary new builder\n * to the existing builder.\n * @internal\n */\n private mergeFieldOperations(\n fieldId: string,\n existing: BaseFieldBuilder<any>,\n extension: BaseFieldBuilder<any>\n ): void {\n // For object fields, merge nested fields and layout operations\n if (existing.type === \"object\" && extension.type === \"object\") {\n const existingFieldMap = (existing as any).fieldBuildersMap;\n const extensionFieldMap = (extension as any).fieldBuildersMap;\n\n // Merge nested field builders\n if (extensionFieldMap) {\n for (const [nestedKey, nestedBuilder] of extensionFieldMap.entries()) {\n existingFieldMap.set(nestedKey, nestedBuilder);\n }\n }\n\n // Merge layout operations\n const existingLayoutBuilder = (existing as any).layoutBuilder;\n const extensionLayoutBuilder = (extension as any).layoutBuilder;\n\n if (extensionLayoutBuilder) {\n const snapshot = extensionLayoutBuilder.getSnapshot();\n\n // If extension called setLayout() with an array, apply it to existing\n // We detect this by checking if there's a layout but no modifiers\n if (snapshot.layout.length > 0 && snapshot.modifiers.length === 0) {\n existingLayoutBuilder.setLayout(snapshot.layout);\n }\n\n // Apply all modifiers from extension to existing\n for (const modifier of snapshot.modifiers) {\n existingLayoutBuilder.addModifier(modifier);\n }\n }\n }\n }\n\n protected buildFields(): {\n fields: CmsModelField[];\n layoutReplacements: Map<string, CmsModelLayoutCell>;\n } {\n const fields: CmsModelField[] = [];\n const layoutReplacements = new Map<string, CmsModelLayoutCell>();\n\n for (const [fieldId, builder] of this.fieldBuildersMap) {\n const result = builder.build();\n if (result.type === \"layout\") {\n layoutReplacements.set(fieldId, result.layoutCell);\n if (result.fields) {\n fields.push(...result.fields);\n }\n } else {\n fields.push(result.field);\n }\n }\n\n return { fields, layoutReplacements };\n }\n\n /**\n * Get tags with common defaults applied.\n * Always includes \"type:model\" and optionally \"singleEntry\".\n */\n protected getTags(): string[] {\n const tagsSet = new Set(this.config.tags || []);\n tagsSet.add(\"type:model\");\n if (this.isSingleEntry) {\n tagsSet.add(\"singleEntry\");\n }\n return Array.from(tagsSet);\n }\n\n /**\n * Build the final model configuration.\n * Must be implemented by concrete builders.\n */\n abstract build(): TBuild;\n}\n"],"names":["BaseModelBuilder","registry","Map","id","name","tags","settings","builder","fieldBuilders","key","fieldBuilder","Object","existingBuilder","isExtendMode","Error","fieldId","existing","extension","existingFieldMap","extensionFieldMap","nestedKey","nestedBuilder","existingLayoutBuilder","extensionLayoutBuilder","snapshot","modifier","fields","layoutReplacements","result","tagsSet","Set","Array"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/modelBuilder/models/PrivateModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/PrivateModelBuilder.ts"],"sourcesContent":["import { createPrivateModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { BaseModelBuilder } from \"./BaseModelBuilder.js\";\n\nexport class PrivateModelBuilder extends BaseModelBuilder {\n public build() {\n if (!this.config.modelId) {\n throw new Error(\"modelId is required\");\n }\n if (!this.config.name) {\n throw new Error(\"name is required\");\n }\n if (this.fieldBuildersMap.size === 0) {\n throw new Error(\"fields are required\");\n }\n\n // Build all fields from field builders (layout replacements ignored for private models)\n const { fields } = this.buildFields();\n\n return createPrivateModelPlugin({\n modelId: this.config.modelId,\n name: this.config.name,\n fields,\n authorization: false,\n noValidate: true,\n tags: this.getTags()\n });\n }\n}\n"],"names":["PrivateModelBuilder","BaseModelBuilder","Error","fields","createPrivateModelPlugin"],"mappings":";;AAGO,MAAMA,4BAA4BC;IAC9B,QAAQ;QACX,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EACpB,MAAM,IAAIC,MAAM;QAEpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EACjB,MAAM,IAAIA,MAAM;QAEpB,IAAI,AAA+B,MAA/B,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAC1B,MAAM,IAAIA,MAAM;QAIpB,MAAM,EAAEC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW;QAEnC,OAAOC,yBAAyB;YAC5B,SAAS,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI;YACtBD;YACA,eAAe;YACf,YAAY;YACZ,MAAM,IAAI,CAAC,OAAO;
|
|
1
|
+
{"version":3,"file":"features/modelBuilder/models/PrivateModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/PrivateModelBuilder.ts"],"sourcesContent":["import { createPrivateModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { BaseModelBuilder } from \"./BaseModelBuilder.js\";\n\nexport class PrivateModelBuilder extends BaseModelBuilder {\n public build() {\n if (!this.config.modelId) {\n throw new Error(\"modelId is required\");\n }\n if (!this.config.name) {\n throw new Error(\"name is required\");\n }\n if (this.fieldBuildersMap.size === 0) {\n throw new Error(\"fields are required\");\n }\n\n // Build all fields from field builders (layout replacements ignored for private models)\n const { fields } = this.buildFields();\n\n return createPrivateModelPlugin({\n modelId: this.config.modelId,\n name: this.config.name,\n fields,\n authorization: false,\n noValidate: true,\n tags: this.getTags(),\n settings: this.config.settings || {}\n });\n }\n}\n"],"names":["PrivateModelBuilder","BaseModelBuilder","Error","fields","createPrivateModelPlugin"],"mappings":";;AAGO,MAAMA,4BAA4BC;IAC9B,QAAQ;QACX,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EACpB,MAAM,IAAIC,MAAM;QAEpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EACjB,MAAM,IAAIA,MAAM;QAEpB,IAAI,AAA+B,MAA/B,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAC1B,MAAM,IAAIA,MAAM;QAIpB,MAAM,EAAEC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW;QAEnC,OAAOC,yBAAyB;YAC5B,SAAS,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI;YACtBD;YACA,eAAe;YACf,YAAY;YACZ,MAAM,IAAI,CAAC,OAAO;YAClB,UAAU,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC;QACvC;IACJ;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/modelBuilder/models/PublicModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/PublicModelBuilder.ts"],"sourcesContent":["import upperFirst from \"lodash/upperFirst.js\";\nimport camelCase from \"lodash/camelCase.js\";\nimport pluralize from \"pluralize\";\nimport { createModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { BaseModelBuilder } from \"./BaseModelBuilder.js\";\nimport type { CmsIcon, CmsModelField } from \"~/types/index.js\";\nimport { LayoutBuilder } from \"../LayoutBuilder.js\";\n\nconst createApiName = (name: string) => {\n return upperFirst(camelCase(name));\n};\n\nconst createPluralApiName = (name: string) => {\n return pluralize(createApiName(name));\n};\n\nclass Icon {\n static from(icon: string | CmsIcon): CmsIcon {\n if (typeof icon === \"string\") {\n return {\n type: \"icon\",\n name: icon\n };\n }\n\n return icon;\n }\n}\n\nexport class PublicModelBuilder extends BaseModelBuilder {\n private publicConfig: {\n singularApiName?: string;\n pluralApiName?: string;\n group?: string;\n icon?: CmsIcon;\n description?: string;\n titleFieldId?: string;\n descriptionFieldId?: string;\n imageFieldId?: string;\n } = {};\n private layoutBuilder: LayoutBuilder;\n\n singularApiName(name: string): this {\n this.publicConfig.singularApiName = name;\n return this;\n }\n\n pluralApiName(name: string): this {\n this.publicConfig.pluralApiName = name;\n return this;\n }\n\n group(slug: string): this {\n this.publicConfig.group = slug;\n return this;\n }\n\n icon(icon: string | CmsIcon): this {\n this.publicConfig.icon = Icon.from(icon);\n return this;\n }\n\n description(description: string): this {\n this.publicConfig.description = description;\n return this;\n }\n\n titleFieldId(fieldId: string): this {\n this.publicConfig.titleFieldId = fieldId;\n return this;\n }\n\n descriptionFieldId(fieldId: string): this {\n this.publicConfig.descriptionFieldId = fieldId;\n return this;\n }\n\n imageFieldId(fieldId: string): this {\n this.publicConfig.imageFieldId = fieldId;\n return this;\n }\n /**\n * It just creates problems if we import the FieldBuilderRegistry.\n * TODO: figure out\n */\n constructor(registry: any) {\n super(registry);\n this.layoutBuilder = new LayoutBuilder();\n }\n\n layout(layoutOrBuilder: string[][] | ((builder: LayoutBuilder) => void)): this {\n if (Array.isArray(layoutOrBuilder)) {\n // Replace layout with array\n this.layoutBuilder.setLayout(layoutOrBuilder);\n } else {\n // Queue the modifier callback\n this.layoutBuilder.addModifier(layoutOrBuilder);\n }\n return this;\n }\n\n build() {\n if (!this.config.modelId) {\n throw new Error(\"modelId is required\");\n }\n if (!this.config.name) {\n throw new Error(\"name is required\");\n }\n if (this.fieldBuildersMap.size === 0) {\n this.fields(builder => ({\n alert: builder\n .uiAlert()\n .label(\n \"No fields defined in the code content model. Please ensure you have the fields property correctly defined.\"\n ),\n emptyPlaceholder: builder.text().label(\"Empty\").renderer(\"hidden\")\n }));\n this.titleFieldId(\"emptyPlaceholder\");\n this.layoutBuilder.setLayout([[\"alert\"], [\"emptyPlaceholder\"]]);\n }\n if (!this.publicConfig.group) {\n throw new Error(\"group is required\");\n }\n\n // Build all fields from field builders, separating data and layout results\n const { fields, layoutReplacements } = this.buildFields();\n\n // Build and apply layout replacements (tabs → rich descriptors)\n const rawLayout = this.layoutBuilder.build();\n const layout = rawLayout.map(row => row.map(cell => layoutReplacements.get(cell) ?? cell));\n\n return createModelPlugin(\n {\n modelId: this.config.modelId,\n name: this.config.name,\n singularApiName:\n this.publicConfig.singularApiName || createApiName(this.config.name),\n pluralApiName:\n this.publicConfig.pluralApiName || createPluralApiName(this.config.name),\n group: this.publicConfig.group,\n icon: this.publicConfig.icon ?? null,\n description: this.publicConfig.description || null,\n titleFieldId:\n this.publicConfig.titleFieldId ?? this.findFirstFieldId(fields, \"text\"),\n descriptionFieldId: this.publicConfig.descriptionFieldId,\n imageFieldId: this.publicConfig.imageFieldId,\n layout,\n fields,\n tags: this.getTags()\n },\n { validateLayout: false }\n );\n }\n\n private findFirstFieldId(fields: CmsModelField[], type: string): string {\n for (const field of fields) {\n if (field.type === type) {\n return field.fieldId;\n }\n }\n return fields.find(field => field.type === \"text\")?.fieldId || \"\";\n }\n}\n"],"names":["createApiName","name","upperFirst","camelCase","createPluralApiName","pluralize","Icon","icon","PublicModelBuilder","BaseModelBuilder","slug","description","fieldId","registry","LayoutBuilder","layoutOrBuilder","Array","Error","builder","fields","layoutReplacements","rawLayout","layout","row","cell","createModelPlugin","type","field"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"features/modelBuilder/models/PublicModelBuilder.js","sources":["../../../../src/features/modelBuilder/models/PublicModelBuilder.ts"],"sourcesContent":["import upperFirst from \"lodash/upperFirst.js\";\nimport camelCase from \"lodash/camelCase.js\";\nimport pluralize from \"pluralize\";\nimport { createModelPlugin } from \"~/plugins/CmsModelPlugin.js\";\nimport { BaseModelBuilder } from \"./BaseModelBuilder.js\";\nimport type { CmsIcon, CmsModelField } from \"~/types/index.js\";\nimport { LayoutBuilder } from \"../LayoutBuilder.js\";\n\nconst createApiName = (name: string) => {\n return upperFirst(camelCase(name));\n};\n\nconst createPluralApiName = (name: string) => {\n return pluralize(createApiName(name));\n};\n\nclass Icon {\n static from(icon: string | CmsIcon): CmsIcon {\n if (typeof icon === \"string\") {\n return {\n type: \"icon\",\n name: icon\n };\n }\n\n return icon;\n }\n}\n\nexport class PublicModelBuilder extends BaseModelBuilder {\n private publicConfig: {\n singularApiName?: string;\n pluralApiName?: string;\n group?: string;\n icon?: CmsIcon;\n description?: string;\n titleFieldId?: string;\n descriptionFieldId?: string;\n imageFieldId?: string;\n } = {};\n private layoutBuilder: LayoutBuilder;\n\n singularApiName(name: string): this {\n this.publicConfig.singularApiName = name;\n return this;\n }\n\n pluralApiName(name: string): this {\n this.publicConfig.pluralApiName = name;\n return this;\n }\n\n group(slug: string): this {\n this.publicConfig.group = slug;\n return this;\n }\n\n icon(icon: string | CmsIcon): this {\n this.publicConfig.icon = Icon.from(icon);\n return this;\n }\n\n description(description: string): this {\n this.publicConfig.description = description;\n return this;\n }\n\n titleFieldId(fieldId: string): this {\n this.publicConfig.titleFieldId = fieldId;\n return this;\n }\n\n descriptionFieldId(fieldId: string): this {\n this.publicConfig.descriptionFieldId = fieldId;\n return this;\n }\n\n imageFieldId(fieldId: string): this {\n this.publicConfig.imageFieldId = fieldId;\n return this;\n }\n /**\n * It just creates problems if we import the FieldBuilderRegistry.\n * TODO: figure out\n */\n constructor(registry: any) {\n super(registry);\n this.layoutBuilder = new LayoutBuilder();\n }\n\n layout(layoutOrBuilder: string[][] | ((builder: LayoutBuilder) => void)): this {\n if (Array.isArray(layoutOrBuilder)) {\n // Replace layout with array\n this.layoutBuilder.setLayout(layoutOrBuilder);\n } else {\n // Queue the modifier callback\n this.layoutBuilder.addModifier(layoutOrBuilder);\n }\n return this;\n }\n\n build() {\n if (!this.config.modelId) {\n throw new Error(\"modelId is required\");\n }\n if (!this.config.name) {\n throw new Error(\"name is required\");\n }\n if (this.fieldBuildersMap.size === 0) {\n this.fields(builder => ({\n alert: builder\n .uiAlert()\n .label(\n \"No fields defined in the code content model. Please ensure you have the fields property correctly defined.\"\n ),\n emptyPlaceholder: builder.text().label(\"Empty\").renderer(\"hidden\")\n }));\n this.titleFieldId(\"emptyPlaceholder\");\n this.layoutBuilder.setLayout([[\"alert\"], [\"emptyPlaceholder\"]]);\n }\n if (!this.publicConfig.group) {\n throw new Error(\"group is required\");\n }\n\n // Build all fields from field builders, separating data and layout results\n const { fields, layoutReplacements } = this.buildFields();\n\n // Build and apply layout replacements (tabs → rich descriptors)\n const rawLayout = this.layoutBuilder.build();\n const layout = rawLayout.map(row => row.map(cell => layoutReplacements.get(cell) ?? cell));\n\n return createModelPlugin(\n {\n modelId: this.config.modelId,\n name: this.config.name,\n singularApiName:\n this.publicConfig.singularApiName || createApiName(this.config.name),\n pluralApiName:\n this.publicConfig.pluralApiName || createPluralApiName(this.config.name),\n group: this.publicConfig.group,\n icon: this.publicConfig.icon ?? null,\n description: this.publicConfig.description || null,\n titleFieldId:\n this.publicConfig.titleFieldId ?? this.findFirstFieldId(fields, \"text\"),\n descriptionFieldId: this.publicConfig.descriptionFieldId,\n imageFieldId: this.publicConfig.imageFieldId,\n layout,\n fields,\n tags: this.getTags(),\n settings: this.config.settings || {}\n },\n { validateLayout: false }\n );\n }\n\n private findFirstFieldId(fields: CmsModelField[], type: string): string {\n for (const field of fields) {\n if (field.type === type) {\n return field.fieldId;\n }\n }\n return fields.find(field => field.type === \"text\")?.fieldId || \"\";\n }\n}\n"],"names":["createApiName","name","upperFirst","camelCase","createPluralApiName","pluralize","Icon","icon","PublicModelBuilder","BaseModelBuilder","slug","description","fieldId","registry","LayoutBuilder","layoutOrBuilder","Array","Error","builder","fields","layoutReplacements","rawLayout","layout","row","cell","createModelPlugin","type","field"],"mappings":";;;;;;AAQA,MAAMA,gBAAgB,CAACC,OACZC,WAAWC,UAAUF;AAGhC,MAAMG,sBAAsB,CAACH,OAClBI,UAAUL,cAAcC;AAGnC,MAAMK;IACF,OAAO,KAAKC,IAAsB,EAAW;QACzC,IAAI,AAAgB,YAAhB,OAAOA,MACP,OAAO;YACH,MAAM;YACN,MAAMA;QACV;QAGJ,OAAOA;IACX;AACJ;AAEO,MAAMC,2BAA2BC;IAapC,gBAAgBR,IAAY,EAAQ;QAChC,IAAI,CAAC,YAAY,CAAC,eAAe,GAAGA;QACpC,OAAO,IAAI;IACf;IAEA,cAAcA,IAAY,EAAQ;QAC9B,IAAI,CAAC,YAAY,CAAC,aAAa,GAAGA;QAClC,OAAO,IAAI;IACf;IAEA,MAAMS,IAAY,EAAQ;QACtB,IAAI,CAAC,YAAY,CAAC,KAAK,GAAGA;QAC1B,OAAO,IAAI;IACf;IAEA,KAAKH,IAAsB,EAAQ;QAC/B,IAAI,CAAC,YAAY,CAAC,IAAI,GAAGD,KAAK,IAAI,CAACC;QACnC,OAAO,IAAI;IACf;IAEA,YAAYI,WAAmB,EAAQ;QACnC,IAAI,CAAC,YAAY,CAAC,WAAW,GAAGA;QAChC,OAAO,IAAI;IACf;IAEA,aAAaC,OAAe,EAAQ;QAChC,IAAI,CAAC,YAAY,CAAC,YAAY,GAAGA;QACjC,OAAO,IAAI;IACf;IAEA,mBAAmBA,OAAe,EAAQ;QACtC,IAAI,CAAC,YAAY,CAAC,kBAAkB,GAAGA;QACvC,OAAO,IAAI;IACf;IAEA,aAAaA,OAAe,EAAQ;QAChC,IAAI,CAAC,YAAY,CAAC,YAAY,GAAGA;QACjC,OAAO,IAAI;IACf;IAKA,YAAYC,QAAa,CAAE;QACvB,KAAK,CAACA,WAAAA,IAAAA,CAxDF,YAAY,GAShB,CAAC;QAgDD,IAAI,CAAC,aAAa,GAAG,IAAIC;IAC7B;IAEA,OAAOC,eAAgE,EAAQ;QAC3E,IAAIC,MAAM,OAAO,CAACD,kBAEd,IAAI,CAAC,aAAa,CAAC,SAAS,CAACA;aAG7B,IAAI,CAAC,aAAa,CAAC,WAAW,CAACA;QAEnC,OAAO,IAAI;IACf;IAEA,QAAQ;QACJ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EACpB,MAAM,IAAIE,MAAM;QAEpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EACjB,MAAM,IAAIA,MAAM;QAEpB,IAAI,AAA+B,MAA/B,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAQ;YAClC,IAAI,CAAC,MAAM,CAACC,CAAAA,UAAY;oBACpB,OAAOA,QACF,OAAO,GACP,KAAK,CACF;oBAER,kBAAkBA,QAAQ,IAAI,GAAG,KAAK,CAAC,SAAS,QAAQ,CAAC;gBAC7D;YACA,IAAI,CAAC,YAAY,CAAC;YAClB,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;gBAAC;oBAAC;iBAAQ;gBAAE;oBAAC;iBAAmB;aAAC;QAClE;QACA,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EACxB,MAAM,IAAID,MAAM;QAIpB,MAAM,EAAEE,MAAM,EAAEC,kBAAkB,EAAE,GAAG,IAAI,CAAC,WAAW;QAGvD,MAAMC,YAAY,IAAI,CAAC,aAAa,CAAC,KAAK;QAC1C,MAAMC,SAASD,UAAU,GAAG,CAACE,CAAAA,MAAOA,IAAI,GAAG,CAACC,CAAAA,OAAQJ,mBAAmB,GAAG,CAACI,SAASA;QAEpF,OAAOC,kBACH;YACI,SAAS,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI;YACtB,iBACI,IAAI,CAAC,YAAY,CAAC,eAAe,IAAIzB,cAAc,IAAI,CAAC,MAAM,CAAC,IAAI;YACvE,eACI,IAAI,CAAC,YAAY,CAAC,aAAa,IAAII,oBAAoB,IAAI,CAAC,MAAM,CAAC,IAAI;YAC3E,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK;YAC9B,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI;YAChC,aAAa,IAAI,CAAC,YAAY,CAAC,WAAW,IAAI;YAC9C,cACI,IAAI,CAAC,YAAY,CAAC,YAAY,IAAI,IAAI,CAAC,gBAAgB,CAACe,QAAQ;YACpE,oBAAoB,IAAI,CAAC,YAAY,CAAC,kBAAkB;YACxD,cAAc,IAAI,CAAC,YAAY,CAAC,YAAY;YAC5CG;YACAH;YACA,MAAM,IAAI,CAAC,OAAO;YAClB,UAAU,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC;QACvC,GACA;YAAE,gBAAgB;QAAM;IAEhC;IAEQ,iBAAiBA,MAAuB,EAAEO,IAAY,EAAU;QACpE,KAAK,MAAMC,SAASR,OAChB,IAAIQ,MAAM,IAAI,KAAKD,MACf,OAAOC,MAAM,OAAO;QAG5B,OAAOR,OAAO,IAAI,CAACQ,CAAAA,QAASA,AAAe,WAAfA,MAAM,IAAI,GAAc,WAAW;IACnE;AACJ"}
|
|
@@ -4,10 +4,7 @@ class SortImpl {
|
|
|
4
4
|
const { fields: modelFields, input } = params;
|
|
5
5
|
if (!input) return;
|
|
6
6
|
const fields = modelFields.map((field)=>field.fieldId);
|
|
7
|
-
const isField = (key)=>
|
|
8
|
-
const field = key.split("_")[0];
|
|
9
|
-
return fields.includes(field);
|
|
10
|
-
};
|
|
7
|
+
const isField = (key)=>fields.includes(key);
|
|
11
8
|
return this.mapSort({
|
|
12
9
|
input,
|
|
13
10
|
isField
|
|
@@ -16,7 +13,7 @@ class SortImpl {
|
|
|
16
13
|
mapSort(params) {
|
|
17
14
|
const { input, isField } = params;
|
|
18
15
|
return input.map((sort)=>{
|
|
19
|
-
const match = sort.match(/^(values_)?([a-zA-Z][a-zA-Z0-
|
|
16
|
+
const match = sort.match(/^(values_)?([a-zA-Z][a-zA-Z0-9_]*)_(ASC|DESC)$/);
|
|
20
17
|
if (!match) return null;
|
|
21
18
|
const [, hasValues, field, direction] = match;
|
|
22
19
|
if (hasValues) return sort;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/sortMapper/SortMapper.js","sources":["../../../src/features/sortMapper/SortMapper.ts"],"sourcesContent":["/**\n * Used to map sorting for custom CMS Models.\n */\nimport { type CmsEntryListSort } from \"~/types/types.js\";\nimport { CmsSortMapper, ICmsSortMapperParams } from \"./abstractions.js\";\n\ninterface IMapSortParams {\n input: CmsEntryListSort;\n isField: (key: string) => boolean;\n}\n\nclass SortImpl implements CmsSortMapper.Interface {\n map(params: ICmsSortMapperParams): CmsEntryListSort | undefined {\n const { fields: modelFields, input } = params;\n if (!input) {\n return undefined;\n }\n\n const fields = modelFields.map(field => {\n return field.fieldId;\n });\n\n const isField = (key: string): boolean => {\n
|
|
1
|
+
{"version":3,"file":"features/sortMapper/SortMapper.js","sources":["../../../src/features/sortMapper/SortMapper.ts"],"sourcesContent":["/**\n * Used to map sorting for custom CMS Models.\n */\nimport { type CmsEntryListSort } from \"~/types/types.js\";\nimport { CmsSortMapper, ICmsSortMapperParams } from \"./abstractions.js\";\n\ninterface IMapSortParams {\n input: CmsEntryListSort;\n isField: (key: string) => boolean;\n}\n\nclass SortImpl implements CmsSortMapper.Interface {\n map(params: ICmsSortMapperParams): CmsEntryListSort | undefined {\n const { fields: modelFields, input } = params;\n if (!input) {\n return undefined;\n }\n\n const fields = modelFields.map(field => {\n return field.fieldId;\n });\n\n /*\n * `mapSort` has already stripped the direction, so what arrives here is a bare fieldId and\n * is compared whole. Taking the segment before the first `_` would fail every fieldId that\n * contains one: `on_sale` would be looked up as `on`.\n */\n const isField = (key: string): boolean => {\n return fields.includes(key);\n };\n\n return this.mapSort({\n input,\n isField\n });\n }\n\n private mapSort(params: IMapSortParams): CmsEntryListSort {\n const { input, isField } = params;\n\n return input\n .map(sort => {\n // `_` is allowed inside the fieldId: excluding it made `on_sale_DESC` unmatchable,\n // and an unmatched directive is dropped from the sort entirely.\n const match = sort.match(/^(values_)?([a-zA-Z][a-zA-Z0-9_]*)_(ASC|DESC)$/);\n if (!match) {\n return null;\n }\n\n const [, hasValues, field, direction] = match;\n\n if (hasValues) {\n return sort;\n }\n\n if (isField(field)) {\n return `values_${field}_${direction}` as unknown as CmsEntryListSort[0];\n }\n\n return sort;\n })\n .filter((item): item is CmsEntryListSort[0] => !!item);\n }\n}\n\nexport const SortMapper = CmsSortMapper.createImplementation({\n implementation: SortImpl,\n dependencies: []\n});\n"],"names":["SortImpl","params","modelFields","input","fields","field","isField","key","sort","match","hasValues","direction","item","SortMapper","CmsSortMapper"],"mappings":";AAWA,MAAMA;IACF,IAAIC,MAA4B,EAAgC;QAC5D,MAAM,EAAE,QAAQC,WAAW,EAAEC,KAAK,EAAE,GAAGF;QACvC,IAAI,CAACE,OACD;QAGJ,MAAMC,SAASF,YAAY,GAAG,CAACG,CAAAA,QACpBA,MAAM,OAAO;QAQxB,MAAMC,UAAU,CAACC,MACNH,OAAO,QAAQ,CAACG;QAG3B,OAAO,IAAI,CAAC,OAAO,CAAC;YAChBJ;YACAG;QACJ;IACJ;IAEQ,QAAQL,MAAsB,EAAoB;QACtD,MAAM,EAAEE,KAAK,EAAEG,OAAO,EAAE,GAAGL;QAE3B,OAAOE,MACF,GAAG,CAACK,CAAAA;YAGD,MAAMC,QAAQD,KAAK,KAAK,CAAC;YACzB,IAAI,CAACC,OACD,OAAO;YAGX,MAAM,GAAGC,WAAWL,OAAOM,UAAU,GAAGF;YAExC,IAAIC,WACA,OAAOF;YAGX,IAAIF,QAAQD,QACR,OAAO,CAAC,OAAO,EAAEA,MAAM,CAAC,EAAEM,WAAW;YAGzC,OAAOH;QACX,GACC,MAAM,CAAC,CAACI,OAAsC,CAAC,CAACA;IACzD;AACJ;AAEO,MAAMC,aAAaC,cAAc,oBAAoB,CAAC;IACzD,gBAAgBd;IAChB,cAAc,EAAE;AACpB"}
|
|
@@ -9,7 +9,7 @@ class CompressedTextStorageTransformImpl {
|
|
|
9
9
|
async fromStorage(params) {
|
|
10
10
|
const { value } = params;
|
|
11
11
|
if ("string" != typeof value) return value;
|
|
12
|
-
|
|
12
|
+
if (!value.includes("compression")) return value;
|
|
13
13
|
try {
|
|
14
14
|
const parsed = JSON.parse(value);
|
|
15
15
|
return await this.compressionHandler.decompress(parsed);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/storage/fields/CompressedTextStorageTransform.js","sources":["../../../../src/features/storage/fields/CompressedTextStorageTransform.ts"],"sourcesContent":["import { StorageTransform } from \"../abstractions/StorageTransform.js\";\nimport { CompressionHandler } from \"@webiny/utils/exports/api.js\";\nimport { TextFieldTypes } from \"~/features/modelBuilder/index.js\";\n\nclass CompressedTextStorageTransformImpl implements StorageTransform.Interface<string, string> {\n public readonly fieldType = TextFieldTypes.COMPRESSED;\n\n public constructor(private readonly compressionHandler: CompressionHandler.Interface) {}\n\n public async fromStorage(\n params: StorageTransform.FromStorageParams<unknown, string>\n ): StorageTransform.FromStorageResponse<string> {\n const { value } = params;\n if (typeof value !== \"string\") {\n return value as string;\n } else if (!value.includes(\"compression\")) {\n return value;\n }\n try {\n const parsed = JSON.parse(value);\n return await this.compressionHandler.decompress<string>(parsed);\n } catch {\n return value;\n }\n }\n\n public async toStorage(\n params: StorageTransform.ToStorageParams<unknown, string>\n ): StorageTransform.ToStorageResponse<string> {\n const { value } = params;\n if (typeof value !== \"string\") {\n return value as string;\n }\n\n try {\n return JSON.stringify(await this.compressionHandler.compress(value));\n } catch {\n return value;\n }\n }\n}\n\nexport const CompressedTextStorageTransform = StorageTransform.createImplementation({\n implementation: CompressedTextStorageTransformImpl,\n dependencies: [CompressionHandler]\n});\n"],"names":["CompressedTextStorageTransformImpl","compressionHandler","TextFieldTypes","params","value","parsed","JSON","CompressedTextStorageTransform","StorageTransform","CompressionHandler"],"mappings":";;;AAIA,MAAMA;IAGF,YAAoCC,kBAAgD,CAAE;aAAlDA,kBAAkB,GAAlBA;aAFpB,SAAS,GAAGC,eAAe,UAAU;IAEkC;IAEvF,MAAa,YACTC,MAA2D,EACf;QAC5C,MAAM,EAAEC,KAAK,EAAE,GAAGD;QAClB,IAAI,AAAiB,YAAjB,OAAOC,OACP,OAAOA;
|
|
1
|
+
{"version":3,"file":"features/storage/fields/CompressedTextStorageTransform.js","sources":["../../../../src/features/storage/fields/CompressedTextStorageTransform.ts"],"sourcesContent":["import { StorageTransform } from \"../abstractions/StorageTransform.js\";\nimport { CompressionHandler } from \"@webiny/utils/exports/api.js\";\nimport { TextFieldTypes } from \"~/features/modelBuilder/index.js\";\n\nclass CompressedTextStorageTransformImpl implements StorageTransform.Interface<string, string> {\n public readonly fieldType = TextFieldTypes.COMPRESSED;\n\n public constructor(private readonly compressionHandler: CompressionHandler.Interface) {}\n\n public async fromStorage(\n params: StorageTransform.FromStorageParams<unknown, string>\n ): StorageTransform.FromStorageResponse<string> {\n const { value } = params;\n if (typeof value !== \"string\") {\n return value as string;\n } else if (!value.includes(\"compression\")) {\n return value;\n }\n try {\n const parsed = JSON.parse(value);\n return await this.compressionHandler.decompress<string>(parsed);\n } catch {\n return value;\n }\n }\n\n public async toStorage(\n params: StorageTransform.ToStorageParams<unknown, string>\n ): StorageTransform.ToStorageResponse<string> {\n const { value } = params;\n if (typeof value !== \"string\") {\n return value as string;\n }\n\n try {\n return JSON.stringify(await this.compressionHandler.compress(value));\n } catch {\n return value;\n }\n }\n}\n\nexport const CompressedTextStorageTransform = StorageTransform.createImplementation({\n implementation: CompressedTextStorageTransformImpl,\n dependencies: [CompressionHandler]\n});\n"],"names":["CompressedTextStorageTransformImpl","compressionHandler","TextFieldTypes","params","value","parsed","JSON","CompressedTextStorageTransform","StorageTransform","CompressionHandler"],"mappings":";;;AAIA,MAAMA;IAGF,YAAoCC,kBAAgD,CAAE;aAAlDA,kBAAkB,GAAlBA;aAFpB,SAAS,GAAGC,eAAe,UAAU;IAEkC;IAEvF,MAAa,YACTC,MAA2D,EACf;QAC5C,MAAM,EAAEC,KAAK,EAAE,GAAGD;QAClB,IAAI,AAAiB,YAAjB,OAAOC,OACP,OAAOA;QACJ,IAAI,CAACA,MAAM,QAAQ,CAAC,gBACvB,OAAOA;QAEX,IAAI;YACA,MAAMC,SAASC,KAAK,KAAK,CAACF;YAC1B,OAAO,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAASC;QAC5D,EAAE,OAAM;YACJ,OAAOD;QACX;IACJ;IAEA,MAAa,UACTD,MAAyD,EACf;QAC1C,MAAM,EAAEC,KAAK,EAAE,GAAGD;QAClB,IAAI,AAAiB,YAAjB,OAAOC,OACP,OAAOA;QAGX,IAAI;YACA,OAAOE,KAAK,SAAS,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAACF;QACjE,EAAE,OAAM;YACJ,OAAOA;QACX;IACJ;AACJ;AAEO,MAAMG,iCAAiCC,iBAAiB,oBAAoB,CAAC;IAChF,gBAAgBR;IAChB,cAAc;QAACS;KAAmB;AACtC"}
|
|
@@ -22,7 +22,7 @@ const convertFromStorage = (value)=>{
|
|
|
22
22
|
};
|
|
23
23
|
const convertValueToStorage = (field, value)=>{
|
|
24
24
|
if (value instanceof Date || value?.toISOString) return value.toISOString();
|
|
25
|
-
|
|
25
|
+
if ("string" == typeof value) return value;
|
|
26
26
|
throw new error("Error converting value to a storage type.", "TO_STORAGE_ERROR", {
|
|
27
27
|
value: value,
|
|
28
28
|
fieldId: field.fieldId,
|
|
@@ -50,7 +50,7 @@ class DateStorageTransformImpl {
|
|
|
50
50
|
const { value, field } = params;
|
|
51
51
|
const { type } = field.settings || {};
|
|
52
52
|
if (!value || !type || excludeTypes.includes(type)) return value;
|
|
53
|
-
|
|
53
|
+
if (field.list) {
|
|
54
54
|
if (!Array.isArray(value)) return [];
|
|
55
55
|
const list = value;
|
|
56
56
|
const results = [];
|
|
@@ -59,7 +59,8 @@ class DateStorageTransformImpl {
|
|
|
59
59
|
if (isNaN(input.getTime())) continue;
|
|
60
60
|
results.push(input);
|
|
61
61
|
continue;
|
|
62
|
-
}
|
|
62
|
+
}
|
|
63
|
+
if (!input || "object" == typeof input && 0 === Object.keys(input).length) continue;
|
|
63
64
|
const output = convertFromStorage(input);
|
|
64
65
|
if (output) results.push(output);
|
|
65
66
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/storage/fields/DateStorageTransform.js","sources":["../../../../src/features/storage/fields/DateStorageTransform.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport type { CmsModelField } from \"~/types/index.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\nimport { StorageTransform } from \"../abstractions/StorageTransform.js\";\n\nconst excludeTypes = [\"time\", \"dateTimeWithTimezone\"];\n\nconst convertFromStorage = (value: unknown): Date | unknown => {\n if (!value) {\n return value === null ? null : undefined;\n }\n try {\n const output = new Date(value as string);\n if (isNaN(output.getTime())) {\n if (process.env.DEBUG !== \"true\") {\n return null;\n }\n console.warn(`Could not transform \"${value}\" to date.`);\n return null;\n }\n return output;\n } catch {\n if (process.env.DEBUG !== \"true\") {\n return null;\n }\n console.warn(`Could not transform \"${value}\" from storage for date field type.`);\n return null;\n }\n};\n\nconst convertValueToStorage = (field: CmsModelField, value: Date | string | unknown): string => {\n if (value instanceof Date || (value as GenericRecord)?.toISOString) {\n return (value as Date).toISOString();\n } else if (typeof value === \"string\") {\n return value as string;\n }\n throw new WebinyError(\"Error converting value to a storage type.\", \"TO_STORAGE_ERROR\", {\n value: value,\n fieldId: field.fieldId,\n storageId: field.storageId\n });\n};\n\nclass DateStorageTransformImpl implements StorageTransform.Interface {\n public readonly fieldType = \"datetime\";\n\n public async toStorage(\n params: StorageTransform.ToStorageParams\n ): StorageTransform.ToStorageResponse {\n const { value, field } = params;\n const { type } = field.settings || {};\n if (!value || !type || excludeTypes.includes(type)) {\n return value;\n }\n if (field.list) {\n const list = value as (string | Date | null | undefined)[];\n const results: string[] = [];\n for (const input of list) {\n if (!input) {\n continue;\n }\n const output = convertValueToStorage(field, input);\n if (!output) {\n continue;\n }\n results.push(output);\n }\n return results;\n }\n return convertValueToStorage(field, value);\n }\n\n public async fromStorage(\n params: StorageTransform.FromStorageParams\n ): StorageTransform.FromStorageResponse {\n const { value, field } = params;\n const { type } = field.settings || {};\n if (!value || !type || excludeTypes.includes(type)) {\n return value;\n } else if (field.list) {\n if (!Array.isArray(value)) {\n return [];\n }\n const list = value as unknown[];\n const results: (Date | unknown)[] = [];\n for (const input of list) {\n if (input instanceof Date) {\n if (isNaN(input.getTime())) {\n continue;\n }\n results.push(input);\n continue;\n } else if (\n !input ||\n (typeof input === \"object\" && Object.keys(input).length === 0)\n ) {\n continue;\n }\n const output = convertFromStorage(input);\n if (!output) {\n continue;\n }\n results.push(output);\n }\n return results;\n }\n return convertFromStorage(value);\n }\n}\n\nexport const DateStorageTransform = StorageTransform.createImplementation({\n implementation: DateStorageTransformImpl,\n dependencies: []\n});\n"],"names":["excludeTypes","convertFromStorage","value","undefined","output","Date","isNaN","process","console","convertValueToStorage","field","WebinyError","DateStorageTransformImpl","params","type","list","results","input","Array","Object","DateStorageTransform","StorageTransform"],"mappings":";;AAKA,MAAMA,eAAe;IAAC;IAAQ;CAAuB;AAErD,MAAMC,qBAAqB,CAACC;IACxB,IAAI,CAACA,OACD,OAAOA,AAAU,SAAVA,QAAiB,OAAOC;IAEnC,IAAI;QACA,MAAMC,SAAS,IAAIC,KAAKH;QACxB,IAAII,MAAMF,OAAO,OAAO,KAAK;YACzB,IAAIG,AAAsB,WAAtBA,QAAQ,GAAG,CAAC,KAAK,EACjB,OAAO;YAEXC,QAAQ,IAAI,CAAC,CAAC,qBAAqB,EAAEN,MAAM,UAAU,CAAC;YACtD,OAAO;QACX;QACA,OAAOE;IACX,EAAE,OAAM;QACJ,IAAIG,AAAsB,WAAtBA,QAAQ,GAAG,CAAC,KAAK,EACjB,OAAO;QAEXC,QAAQ,IAAI,CAAC,CAAC,qBAAqB,EAAEN,MAAM,mCAAmC,CAAC;QAC/E,OAAO;IACX;AACJ;AAEA,MAAMO,wBAAwB,CAACC,OAAsBR;IACjD,IAAIA,iBAAiBG,QAASH,OAAyB,aACnD,OAAQA,MAAe,WAAW;
|
|
1
|
+
{"version":3,"file":"features/storage/fields/DateStorageTransform.js","sources":["../../../../src/features/storage/fields/DateStorageTransform.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport type { CmsModelField } from \"~/types/index.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\nimport { StorageTransform } from \"../abstractions/StorageTransform.js\";\n\nconst excludeTypes = [\"time\", \"dateTimeWithTimezone\"];\n\nconst convertFromStorage = (value: unknown): Date | unknown => {\n if (!value) {\n return value === null ? null : undefined;\n }\n try {\n const output = new Date(value as string);\n if (isNaN(output.getTime())) {\n if (process.env.DEBUG !== \"true\") {\n return null;\n }\n console.warn(`Could not transform \"${value}\" to date.`);\n return null;\n }\n return output;\n } catch {\n if (process.env.DEBUG !== \"true\") {\n return null;\n }\n console.warn(`Could not transform \"${value}\" from storage for date field type.`);\n return null;\n }\n};\n\nconst convertValueToStorage = (field: CmsModelField, value: Date | string | unknown): string => {\n if (value instanceof Date || (value as GenericRecord)?.toISOString) {\n return (value as Date).toISOString();\n } else if (typeof value === \"string\") {\n return value as string;\n }\n throw new WebinyError(\"Error converting value to a storage type.\", \"TO_STORAGE_ERROR\", {\n value: value,\n fieldId: field.fieldId,\n storageId: field.storageId\n });\n};\n\nclass DateStorageTransformImpl implements StorageTransform.Interface {\n public readonly fieldType = \"datetime\";\n\n public async toStorage(\n params: StorageTransform.ToStorageParams\n ): StorageTransform.ToStorageResponse {\n const { value, field } = params;\n const { type } = field.settings || {};\n if (!value || !type || excludeTypes.includes(type)) {\n return value;\n }\n if (field.list) {\n const list = value as (string | Date | null | undefined)[];\n const results: string[] = [];\n for (const input of list) {\n if (!input) {\n continue;\n }\n const output = convertValueToStorage(field, input);\n if (!output) {\n continue;\n }\n results.push(output);\n }\n return results;\n }\n return convertValueToStorage(field, value);\n }\n\n public async fromStorage(\n params: StorageTransform.FromStorageParams\n ): StorageTransform.FromStorageResponse {\n const { value, field } = params;\n const { type } = field.settings || {};\n if (!value || !type || excludeTypes.includes(type)) {\n return value;\n } else if (field.list) {\n if (!Array.isArray(value)) {\n return [];\n }\n const list = value as unknown[];\n const results: (Date | unknown)[] = [];\n for (const input of list) {\n if (input instanceof Date) {\n if (isNaN(input.getTime())) {\n continue;\n }\n results.push(input);\n continue;\n } else if (\n !input ||\n (typeof input === \"object\" && Object.keys(input).length === 0)\n ) {\n continue;\n }\n const output = convertFromStorage(input);\n if (!output) {\n continue;\n }\n results.push(output);\n }\n return results;\n }\n return convertFromStorage(value);\n }\n}\n\nexport const DateStorageTransform = StorageTransform.createImplementation({\n implementation: DateStorageTransformImpl,\n dependencies: []\n});\n"],"names":["excludeTypes","convertFromStorage","value","undefined","output","Date","isNaN","process","console","convertValueToStorage","field","WebinyError","DateStorageTransformImpl","params","type","list","results","input","Array","Object","DateStorageTransform","StorageTransform"],"mappings":";;AAKA,MAAMA,eAAe;IAAC;IAAQ;CAAuB;AAErD,MAAMC,qBAAqB,CAACC;IACxB,IAAI,CAACA,OACD,OAAOA,AAAU,SAAVA,QAAiB,OAAOC;IAEnC,IAAI;QACA,MAAMC,SAAS,IAAIC,KAAKH;QACxB,IAAII,MAAMF,OAAO,OAAO,KAAK;YACzB,IAAIG,AAAsB,WAAtBA,QAAQ,GAAG,CAAC,KAAK,EACjB,OAAO;YAEXC,QAAQ,IAAI,CAAC,CAAC,qBAAqB,EAAEN,MAAM,UAAU,CAAC;YACtD,OAAO;QACX;QACA,OAAOE;IACX,EAAE,OAAM;QACJ,IAAIG,AAAsB,WAAtBA,QAAQ,GAAG,CAAC,KAAK,EACjB,OAAO;QAEXC,QAAQ,IAAI,CAAC,CAAC,qBAAqB,EAAEN,MAAM,mCAAmC,CAAC;QAC/E,OAAO;IACX;AACJ;AAEA,MAAMO,wBAAwB,CAACC,OAAsBR;IACjD,IAAIA,iBAAiBG,QAASH,OAAyB,aACnD,OAAQA,MAAe,WAAW;IAC/B,IAAI,AAAiB,YAAjB,OAAOA,OACd,OAAOA;IAEX,MAAM,IAAIS,MAAY,6CAA6C,oBAAoB;QACnF,OAAOT;QACP,SAASQ,MAAM,OAAO;QACtB,WAAWA,MAAM,SAAS;IAC9B;AACJ;AAEA,MAAME;IAGF,MAAa,UACTC,MAAwC,EACN;QAClC,MAAM,EAAEX,KAAK,EAAEQ,KAAK,EAAE,GAAGG;QACzB,MAAM,EAAEC,IAAI,EAAE,GAAGJ,MAAM,QAAQ,IAAI,CAAC;QACpC,IAAI,CAACR,SAAS,CAACY,QAAQd,aAAa,QAAQ,CAACc,OACzC,OAAOZ;QAEX,IAAIQ,MAAM,IAAI,EAAE;YACZ,MAAMK,OAAOb;YACb,MAAMc,UAAoB,EAAE;YAC5B,KAAK,MAAMC,SAASF,KAAM;gBACtB,IAAI,CAACE,OACD;gBAEJ,MAAMb,SAASK,sBAAsBC,OAAOO;gBAC5C,IAAKb,QAGLY,QAAQ,IAAI,CAACZ;YACjB;YACA,OAAOY;QACX;QACA,OAAOP,sBAAsBC,OAAOR;IACxC;IAEA,MAAa,YACTW,MAA0C,EACN;QACpC,MAAM,EAAEX,KAAK,EAAEQ,KAAK,EAAE,GAAGG;QACzB,MAAM,EAAEC,IAAI,EAAE,GAAGJ,MAAM,QAAQ,IAAI,CAAC;QACpC,IAAI,CAACR,SAAS,CAACY,QAAQd,aAAa,QAAQ,CAACc,OACzC,OAAOZ;QACJ,IAAIQ,MAAM,IAAI,EAAE;YACnB,IAAI,CAACQ,MAAM,OAAO,CAAChB,QACf,OAAO,EAAE;YAEb,MAAMa,OAAOb;YACb,MAAMc,UAA8B,EAAE;YACtC,KAAK,MAAMC,SAASF,KAAM;gBACtB,IAAIE,iBAAiBZ,MAAM;oBACvB,IAAIC,MAAMW,MAAM,OAAO,KACnB;oBAEJD,QAAQ,IAAI,CAACC;oBACb;gBACJ;gBAAO,IACH,CAACA,SACA,AAAiB,YAAjB,OAAOA,SAAsBE,AAA8B,MAA9BA,OAAO,IAAI,CAACF,OAAO,MAAM,EAEvD;gBAEJ,MAAMb,SAASH,mBAAmBgB;gBAClC,IAAKb,QAGLY,QAAQ,IAAI,CAACZ;YACjB;YACA,OAAOY;QACX;QACA,OAAOf,mBAAmBC;IAC9B;;aA/DgB,SAAS,GAAG;;AAgEhC;AAEO,MAAMkB,uBAAuBC,iBAAiB,oBAAoB,CAAC;IACtE,gBAAgBT;IAChB,cAAc,EAAE;AACpB"}
|
|
@@ -55,7 +55,7 @@ class DynamicZoneStorageTransformImpl {
|
|
|
55
55
|
async toStorage(params) {
|
|
56
56
|
const { value: input, field, model, getStorageTransform } = params;
|
|
57
57
|
if (!input) return input;
|
|
58
|
-
|
|
58
|
+
if (field.list) {
|
|
59
59
|
if (!Array.isArray(input)) return input;
|
|
60
60
|
const values = input;
|
|
61
61
|
return Promise.all(values.map(async (value)=>await processToStorage({
|
|
@@ -75,7 +75,7 @@ class DynamicZoneStorageTransformImpl {
|
|
|
75
75
|
async fromStorage(params) {
|
|
76
76
|
const { value: input, field, model, getStorageTransform } = params;
|
|
77
77
|
if (!input) return input;
|
|
78
|
-
|
|
78
|
+
if (field.list) {
|
|
79
79
|
if (!Array.isArray(input)) return input;
|
|
80
80
|
const values = input;
|
|
81
81
|
return await Promise.all(values.map(async (value)=>await processFromStorage({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/storage/fields/DynamicZoneStorageTransform.js","sources":["../../../../src/features/storage/fields/DynamicZoneStorageTransform.ts"],"sourcesContent":["import { StorageTransform } from \"../abstractions/StorageTransform.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\nimport type { CmsModel, CmsModelDynamicZoneField } from \"~/types/index.js\";\nimport pReduce from \"p-reduce\";\n\ninterface IProcessParams {\n model: CmsModel;\n field: CmsModelDynamicZoneField;\n value: GenericRecord;\n getStorageTransform: (fieldType: string) => StorageTransform.Interface;\n}\n\nconst processToStorage = async (params: IProcessParams): Promise<GenericRecord> => {\n const { model, field: parentField, value: input, getStorageTransform } = params;\n\n const output: GenericRecord = structuredClone(input);\n\n if (!output._templateId) {\n return output;\n }\n const template = parentField.settings.templates.find(t => t.id === output._templateId);\n if (!template || !template.fields.length) {\n return output;\n }\n\n return await pReduce(\n template.fields,\n async (values, field) => {\n const value = values[field.fieldId];\n\n if (!value) {\n values[field.fieldId] = value;\n return values;\n }\n const storageTransform = getStorageTransform(field.type);\n if (!storageTransform) {\n console.error(`Missing storage transform for field type \"${field.type}\".`);\n delete values[field.fieldId];\n return values;\n }\n values[field.fieldId] = await storageTransform.toStorage({\n getStorageTransform,\n model,\n field,\n value\n });\n\n return values;\n },\n output\n );\n};\n\nconst processFromStorage = async (params: IProcessParams): Promise<GenericRecord> => {\n const { model, field: parentField, value: input, getStorageTransform } = params;\n\n const output: GenericRecord = structuredClone(input);\n\n if (!output._templateId) {\n return output;\n }\n const template = parentField.settings.templates.find(t => t.id === output._templateId);\n if (!template || !template.fields.length) {\n return output;\n }\n\n return await pReduce(\n template.fields,\n async (values, field) => {\n const value = values[field.fieldId];\n\n if (!value) {\n return values;\n }\n const storageTransform = getStorageTransform(field.type);\n if (!storageTransform) {\n console.error(`Missing storage transform for field type \"${field.type}\".`);\n delete values[field.fieldId];\n return values;\n }\n values[field.fieldId] = await storageTransform.fromStorage({\n getStorageTransform,\n model,\n field,\n value\n });\n\n return values;\n },\n output\n );\n};\n\nclass DynamicZoneStorageTransformImpl implements StorageTransform.Interface {\n public readonly fieldType = \"dynamicZone\";\n\n public async toStorage(\n params: StorageTransform.ToStorageParams\n ): StorageTransform.ToStorageResponse {\n const { value: input, field, model, getStorageTransform } = params;\n if (!input) {\n return input;\n } else if (field.list) {\n if (!Array.isArray(input)) {\n return input;\n }\n const values = input as GenericRecord[];\n return Promise.all(\n values.map(async value => {\n return await processToStorage({\n model,\n field: field as CmsModelDynamicZoneField,\n value,\n getStorageTransform\n });\n })\n );\n }\n return await processToStorage({\n model,\n field: field as CmsModelDynamicZoneField,\n value: input,\n getStorageTransform\n });\n }\n\n public async fromStorage(\n params: StorageTransform.FromStorageParams\n ): StorageTransform.FromStorageResponse {\n const { value: input, field, model, getStorageTransform } = params;\n if (!input) {\n return input;\n } else if (field.list) {\n if (!Array.isArray(input)) {\n return input;\n }\n const values = input as GenericRecord[];\n\n return await Promise.all(\n values.map(async value => {\n return await processFromStorage({\n model,\n field: field as CmsModelDynamicZoneField,\n value,\n getStorageTransform\n });\n })\n );\n }\n return await processFromStorage({\n model,\n field: field as CmsModelDynamicZoneField,\n value: input,\n getStorageTransform\n });\n }\n}\n\nexport const DynamicZoneStorageTransform = StorageTransform.createImplementation({\n implementation: DynamicZoneStorageTransformImpl,\n dependencies: []\n});\n"],"names":["processToStorage","params","model","parentField","input","getStorageTransform","output","structuredClone","template","t","pReduce","values","field","value","storageTransform","console","processFromStorage","DynamicZoneStorageTransformImpl","Array","Promise","DynamicZoneStorageTransform","StorageTransform"],"mappings":";;AAYA,MAAMA,mBAAmB,OAAOC;IAC5B,MAAM,EAAEC,KAAK,EAAE,OAAOC,WAAW,EAAE,OAAOC,KAAK,EAAEC,mBAAmB,EAAE,GAAGJ;IAEzE,MAAMK,SAAwBC,gBAAgBH;IAE9C,IAAI,CAACE,OAAO,WAAW,EACnB,OAAOA;IAEX,MAAME,WAAWL,YAAY,QAAQ,CAAC,SAAS,CAAC,IAAI,CAACM,CAAAA,IAAKA,EAAE,EAAE,KAAKH,OAAO,WAAW;IACrF,IAAI,CAACE,YAAY,CAACA,SAAS,MAAM,CAAC,MAAM,EACpC,OAAOF;IAGX,OAAO,MAAMI,SACTF,SAAS,MAAM,EACf,OAAOG,QAAQC;QACX,MAAMC,QAAQF,MAAM,CAACC,MAAM,OAAO,CAAC;QAEnC,IAAI,CAACC,OAAO;YACRF,MAAM,CAACC,MAAM,OAAO,CAAC,GAAGC;YACxB,OAAOF;QACX;QACA,MAAMG,mBAAmBT,oBAAoBO,MAAM,IAAI;QACvD,IAAI,CAACE,kBAAkB;YACnBC,QAAQ,KAAK,CAAC,CAAC,0CAA0C,EAAEH,MAAM,IAAI,CAAC,EAAE,CAAC;YACzE,OAAOD,MAAM,CAACC,MAAM,OAAO,CAAC;YAC5B,OAAOD;QACX;QACAA,MAAM,CAACC,MAAM,OAAO,CAAC,GAAG,MAAME,iBAAiB,SAAS,CAAC;YACrDT;YACAH;YACAU;YACAC;QACJ;QAEA,OAAOF;IACX,GACAL;AAER;AAEA,MAAMU,qBAAqB,OAAOf;IAC9B,MAAM,EAAEC,KAAK,EAAE,OAAOC,WAAW,EAAE,OAAOC,KAAK,EAAEC,mBAAmB,EAAE,GAAGJ;IAEzE,MAAMK,SAAwBC,gBAAgBH;IAE9C,IAAI,CAACE,OAAO,WAAW,EACnB,OAAOA;IAEX,MAAME,WAAWL,YAAY,QAAQ,CAAC,SAAS,CAAC,IAAI,CAACM,CAAAA,IAAKA,EAAE,EAAE,KAAKH,OAAO,WAAW;IACrF,IAAI,CAACE,YAAY,CAACA,SAAS,MAAM,CAAC,MAAM,EACpC,OAAOF;IAGX,OAAO,MAAMI,SACTF,SAAS,MAAM,EACf,OAAOG,QAAQC;QACX,MAAMC,QAAQF,MAAM,CAACC,MAAM,OAAO,CAAC;QAEnC,IAAI,CAACC,OACD,OAAOF;QAEX,MAAMG,mBAAmBT,oBAAoBO,MAAM,IAAI;QACvD,IAAI,CAACE,kBAAkB;YACnBC,QAAQ,KAAK,CAAC,CAAC,0CAA0C,EAAEH,MAAM,IAAI,CAAC,EAAE,CAAC;YACzE,OAAOD,MAAM,CAACC,MAAM,OAAO,CAAC;YAC5B,OAAOD;QACX;QACAA,MAAM,CAACC,MAAM,OAAO,CAAC,GAAG,MAAME,iBAAiB,WAAW,CAAC;YACvDT;YACAH;YACAU;YACAC;QACJ;QAEA,OAAOF;IACX,GACAL;AAER;AAEA,MAAMW;IAGF,MAAa,UACThB,MAAwC,EACN;QAClC,MAAM,EAAE,OAAOG,KAAK,EAAEQ,KAAK,EAAEV,KAAK,EAAEG,mBAAmB,EAAE,GAAGJ;QAC5D,IAAI,CAACG,OACD,OAAOA;
|
|
1
|
+
{"version":3,"file":"features/storage/fields/DynamicZoneStorageTransform.js","sources":["../../../../src/features/storage/fields/DynamicZoneStorageTransform.ts"],"sourcesContent":["import { StorageTransform } from \"../abstractions/StorageTransform.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\nimport type { CmsModel, CmsModelDynamicZoneField } from \"~/types/index.js\";\nimport pReduce from \"p-reduce\";\n\ninterface IProcessParams {\n model: CmsModel;\n field: CmsModelDynamicZoneField;\n value: GenericRecord;\n getStorageTransform: (fieldType: string) => StorageTransform.Interface;\n}\n\nconst processToStorage = async (params: IProcessParams): Promise<GenericRecord> => {\n const { model, field: parentField, value: input, getStorageTransform } = params;\n\n const output: GenericRecord = structuredClone(input);\n\n if (!output._templateId) {\n return output;\n }\n const template = parentField.settings.templates.find(t => t.id === output._templateId);\n if (!template || !template.fields.length) {\n return output;\n }\n\n return await pReduce(\n template.fields,\n async (values, field) => {\n const value = values[field.fieldId];\n\n if (!value) {\n values[field.fieldId] = value;\n return values;\n }\n const storageTransform = getStorageTransform(field.type);\n if (!storageTransform) {\n console.error(`Missing storage transform for field type \"${field.type}\".`);\n delete values[field.fieldId];\n return values;\n }\n values[field.fieldId] = await storageTransform.toStorage({\n getStorageTransform,\n model,\n field,\n value\n });\n\n return values;\n },\n output\n );\n};\n\nconst processFromStorage = async (params: IProcessParams): Promise<GenericRecord> => {\n const { model, field: parentField, value: input, getStorageTransform } = params;\n\n const output: GenericRecord = structuredClone(input);\n\n if (!output._templateId) {\n return output;\n }\n const template = parentField.settings.templates.find(t => t.id === output._templateId);\n if (!template || !template.fields.length) {\n return output;\n }\n\n return await pReduce(\n template.fields,\n async (values, field) => {\n const value = values[field.fieldId];\n\n if (!value) {\n return values;\n }\n const storageTransform = getStorageTransform(field.type);\n if (!storageTransform) {\n console.error(`Missing storage transform for field type \"${field.type}\".`);\n delete values[field.fieldId];\n return values;\n }\n values[field.fieldId] = await storageTransform.fromStorage({\n getStorageTransform,\n model,\n field,\n value\n });\n\n return values;\n },\n output\n );\n};\n\nclass DynamicZoneStorageTransformImpl implements StorageTransform.Interface {\n public readonly fieldType = \"dynamicZone\";\n\n public async toStorage(\n params: StorageTransform.ToStorageParams\n ): StorageTransform.ToStorageResponse {\n const { value: input, field, model, getStorageTransform } = params;\n if (!input) {\n return input;\n } else if (field.list) {\n if (!Array.isArray(input)) {\n return input;\n }\n const values = input as GenericRecord[];\n return Promise.all(\n values.map(async value => {\n return await processToStorage({\n model,\n field: field as CmsModelDynamicZoneField,\n value,\n getStorageTransform\n });\n })\n );\n }\n return await processToStorage({\n model,\n field: field as CmsModelDynamicZoneField,\n value: input,\n getStorageTransform\n });\n }\n\n public async fromStorage(\n params: StorageTransform.FromStorageParams\n ): StorageTransform.FromStorageResponse {\n const { value: input, field, model, getStorageTransform } = params;\n if (!input) {\n return input;\n } else if (field.list) {\n if (!Array.isArray(input)) {\n return input;\n }\n const values = input as GenericRecord[];\n\n return await Promise.all(\n values.map(async value => {\n return await processFromStorage({\n model,\n field: field as CmsModelDynamicZoneField,\n value,\n getStorageTransform\n });\n })\n );\n }\n return await processFromStorage({\n model,\n field: field as CmsModelDynamicZoneField,\n value: input,\n getStorageTransform\n });\n }\n}\n\nexport const DynamicZoneStorageTransform = StorageTransform.createImplementation({\n implementation: DynamicZoneStorageTransformImpl,\n dependencies: []\n});\n"],"names":["processToStorage","params","model","parentField","input","getStorageTransform","output","structuredClone","template","t","pReduce","values","field","value","storageTransform","console","processFromStorage","DynamicZoneStorageTransformImpl","Array","Promise","DynamicZoneStorageTransform","StorageTransform"],"mappings":"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"}
|