import Error from "@webiny/error" ; import { CmsEntry , CmsModel , CmsModelField , CmsContext } from "~/types" ; import { StorageTransformPlugin } from "~/content/plugins/storage/StorageTransformPlugin" ; interface GetStoragePluginFactory { ( context ) : ( fieldType : string ) => StorageTransformPlugin < any > ; } const getStoragePluginFactory = context => { let defaultStoragePlugin ; const plugins = context . plugins . byType < StorageTransformPlugin > ( StorageTransformPlugin . type ) . reverse ( ) . reduce ( ( collection , plugin ) => { if ( plugin . fieldType === "*" && ! defaultStoragePlugin ) { defaultStoragePlugin = plugin ; return collection ; } /**
         * either existing plugin added or plugin fieldType does not exist in current model
         * this is to iterate a bit less later
         */ if ( ! collection [ plugin . fieldType ] ) { collection [ plugin . fieldType ] = plugin ; } return collection ; } , { } ) ; return ( fieldType ) => { return plugins [ fieldType ] || defaultStoragePlugin ; } ; } ; /**
 * This should be used when transforming the whole entry.
 */ const entryStorageTransform = async ( context , model , operation , entry ) : Promise < CmsEntry > => { const getStoragePlugin = getStoragePluginFactory ( context ) ; const transformedValues = { } ; for ( const field of model . fields ) { const plugin = getStoragePlugin ( field . type ) ; if ( typeof plugin [ operation ] !== "function" ) { throw new Error ( `Missing "${ operation }" function in storage plugin "${ plugin . name }" for field type "${ field . type }"` ) ; } transformedValues [ field . fieldId ] = await plugin [ operation ] ( { plugins : context . plugins , model , field , value : entry . values [ field . fieldId ] , getStoragePlugin } ) ; } return { ... entry , values : transformedValues } ; } ; /**
 * A function that is used in crud to transform entry into the storage type.
 */ export const entryToStorageTransform = async ( context , model , entry ) : Promise < CmsEntry > => { return entryStorageTransform ( context , model , "toStorage" , entry ) ; } ; /**
 * A function that is used to transform the whole entry from storage into its native form.
 */ export const entryFromStorageTransform = async ( context , model , entry ? ) : Promise < CmsEntry > => { if ( ! entry ) { return null ; } return entryStorageTransform ( context , model , "fromStorage" , entry ) ; } ; interface EntryFieldFromStorageTransformParams { context : CmsContext ; model : CmsModel ; field : CmsModelField ; value : any ; } export const entryFieldFromStorageTransform = async ( params ) : Promise < any > => { const { context , model , field , value } = params ; const getStoragePlugin = getStoragePluginFactory ( context ) ; const plugin = getStoragePlugin ( field . type ) ; if ( typeof plugin . fromStorage !== "function" ) { throw new Error ( `Missing "fromStorage" function in storage plugin "${ plugin . name }" for field type "${ field . type }"` ) ; } return plugin . fromStorage ( { plugins : context . plugins , model , field , value , getStoragePlugin } ) ; } ;