import BaseEntity from '../models/BaseEntity' ; import getSlothData from '../utils/getSlothData' ; import { join } from 'path' ; import getProtoData from '../utils/getProtoData' ; param prefix param propsKeys typeparam export default function SlothURI < S > ( prefix , ... propsKeys ) { return ( target , key ) => { const desc = Reflect . getOwnPropertyDescriptor ( target , key ) ; if ( desc ) { if ( desc . get || desc . set ) { throw new Error ( 'Cannot apply SlothURI on top of another decorator' ) ; } } Reflect . deleteProperty ( target , key ) ; const { uris , fields } = getProtoData ( target , true ) ; uris . push ( { name : key , prefix , propsKeys } ) ; fields . push ( { key , docKey : key } ) ; Reflect . defineProperty ( target , key , { get : function ( ) { const { slug } = getSlothData ( this ) ; return join ( prefix , ... propsKeys . map ( propKey => { const value = ( this as any ) [ propKey ] ; if ( ! value ) { throw new Error ( `Key ${ propKey } has no value, but is required for the ${ key } URI` ) ; } const { rels } = getProtoData ( target ) ; const relation = rels . find ( ( { key } ) => key === propKey ) ; if ( relation && 'belongsTo' in relation ) { const splat = ( value as string ) . split ( '/' ) ; if ( splat . length > 1 ) { return splat . slice ( 1 ) . join ( '/' ) ; } throw new Error ( `URI '${ value }' is invalid'` ) ; } return slug ( value . toString ( ) ) ; } ) ) ; } , set : function ( val ) { if ( val === '' ) { return ; } throw new Error ( `Property ${ key } is not writable` ) ; } } ) ; } ; }