import { getModelRelations , Model , model } from '@loopback/repository' ; import { JSONSchema7 as JsonSchema , JSONSchema7Definition } from 'json-schema' ; export interface FilterSchemaOptions { /**
     * Set this flag if you want the schema to set generated title property.
     *
     * By default the setting is enabled. (e.g. {setTitle: true})
     *
     */ setTitle ? : boolean ; /**
     * To exclude one or more property from `filter`
     */ exclude ? : string [ ] | string ; } export const AnyScopeFilterSchema = { type : 'array' , items : { type : 'object' , properties : { } , additionalProperties : true , } , } ; param modelCtor export function getScopeFilterJsonSchemaFor ( modelCtor , options = { } ) { @ model ( { settings : { strict : false } } ) class EmptyModel extends Model { } const schema = { type : 'object' , ... getFilterJsonSchemaFor ( EmptyModel , { setTitle : false , } ) , ... ( options . setTitle !== false && { title : `${ modelCtor . modelName }.ScopeFilter` , } ) , } ; schema . properties ! . include = { ... AnyScopeFilterSchema } ; return schema ; } param modelCtor param options export function getFilterJsonSchemaFor ( modelCtor , options = { } ) { let excluded ; if ( typeof options . exclude === 'string' ) { excluded = [ options . exclude ] ; } else { excluded = options . exclude ?? [ ] ; } const properties = { offset : { type : 'integer' , minimum : 0 , } , limit : { type : 'integer' , minimum : 1 , examples : [ 100 ] , } , skip : { type : 'integer' , minimum : 0 , } , order : { oneOf : [ { type : 'string' , } , { type : 'array' , items : { type : 'string' , } , } , ] , } , } ; if ( ! excluded . includes ( 'where' ) ) { properties . where = getWhereJsonSchemaFor ( modelCtor , options ) ; } if ( ! excluded . includes ( 'fields' ) ) { properties . fields = getFieldsJsonSchemaFor ( modelCtor , options ) ; } for ( const p of excluded ) { delete properties [ p ] ; } const schema = { type : 'object' , ... ( options . setTitle !== false && { title : `${ modelCtor . modelName }.Filter` , } ) , properties , additionalProperties : false , } ; const modelRelations = getModelRelations ( modelCtor ) ; const hasRelations = Object . keys ( modelRelations ) . length > 0 ; if ( hasRelations && ! excluded . includes ( 'include' ) ) { schema . properties ! . include = { ... ( options . setTitle !== false && { title : `${ modelCtor . modelName }.IncludeFilter` , } ) , type : 'array' , items : { anyOf : [ { ... ( options . setTitle !== false && { title : `${ modelCtor . modelName }.IncludeFilter.Items` , } ) , type : 'object' , properties : { relation : { type : 'string' } , scope : getScopeFilterJsonSchemaFor ( modelCtor , options ) , } , } , { type : 'string' , } , ] , } , } ; } return schema ; } param modelCtor export function getWhereJsonSchemaFor ( modelCtor , options = { } ) { const schema = { ... ( options . setTitle !== false && { title : `${ modelCtor . modelName }.WhereFilter` , } ) , type : 'object' , additionalProperties : true , } ; return schema ; } param modelCtor export function getFieldsJsonSchemaFor ( modelCtor , options = { } ) { const schema = { oneOf : [ ] } ; if ( options . setTitle !== false ) { schema . title = `${ modelCtor . modelName }.Fields` ; } const properties = Object . keys ( modelCtor . definition . properties ) ; const additionalProperties = modelCtor . definition . settings . strict === false ; schema . oneOf ?. push ( { type : 'object' , properties : properties . reduce ( ( prev , crr ) => ( { ... prev , [ crr ] : { type : 'boolean' } } ) , { } ) , additionalProperties , } ) ; schema . oneOf ?. push ( { type : 'array' , items : { type : 'string' , enum : properties . length && ! additionalProperties ? properties : undefined , examples : properties , } , uniqueItems : true , } ) ; return schema ; }