import { CondOperator , QueryFilter , QuerySort , RequestQueryBuilder } from '@nestjsx/crud-request' ; import omitBy from 'lodash.omitby' ; import { DataProvider , fetchUtils } from 'ra-core' ; import { stringify } from 'querystring' ; see https example const countDiff = ( o1 , o2 ) : Record < string , any > => omitBy ( o1 , ( v , k ) => o2 [ k ] === v ) ; const composeFilter = ( paramsFilter ) : QueryFilter [ ] => { const flatFilter = fetchUtils . flattenObject ( paramsFilter ) ; return Object . keys ( flatFilter ) . map ( ( key ) => { const splitKey = key . split ( '||' ) ; let field = splitKey [ 0 ] ; let ops = splitKey [ 1 ] ; if ( ! ops ) { if ( typeof flatFilter [ key ] === 'boolean' || typeof flatFilter [ key ] === 'number' || ( typeof flatFilter [ key ] === 'string' && flatFilter [ key ] . match ( /^\d+$/ ) ) ) { ops = CondOperator . EQUALS ; } else { ops = CondOperator . CONTAINS ; } } if ( field . startsWith ( '_' ) && field . includes ( '.' ) ) { field = field . split ( /\.(.+)/ ) [ 1 ] ; } return { field , operator : ops , value : flatFilter [ key ] } as QueryFilter ; } ) ; } ; const composeQueryParams = ( queryParams = { } ) : string => { return stringify ( fetchUtils . flattenObject ( queryParams ) ) ; } ; const mergeEncodedQueries = ( ... encodedQueries ) => encodedQueries . map ( ( query ) => query ) . join ( '&' ) ; export default ( apiUrl , httpClient = fetchUtils . fetchJson ) : DataProvider => ( { getList : ( resource , params ) => { const { page , perPage } = params . pagination ; const { q : queryParams , $OR : orFilter , ... filter } = params . filter || { } ; const encodedQueryParams = composeQueryParams ( queryParams ) ; const encodedQueryFilter = RequestQueryBuilder . create ( { filter : composeFilter ( filter ) , or : composeFilter ( orFilter || { } ) } ) . setLimit ( perPage ) . setPage ( page ) . sortBy ( params . sort as QuerySort ) . setOffset ( ( page - 1 ) * perPage ) . query ( ) ; const query = mergeEncodedQueries ( encodedQueryParams , encodedQueryFilter ) ; const url = `${ apiUrl }/${ resource }?${ query }` ; return httpClient ( url ) . then ( ( { json } ) => ( { data : json . data , total : json . total , } ) ) ; } , getOne : ( resource , params ) => httpClient ( `${ apiUrl }/${ resource }/${ params . id }` ) . then ( ( { json } ) => ( { data : json , } ) ) , getMany : ( resource , params ) => { const query = RequestQueryBuilder . create ( ) . setFilter ( { field : 'id' , operator : CondOperator . IN , value : `${ params . ids }` , } ) . query ( ) ; const url = `${ apiUrl }/${ resource }?${ query }` ; return httpClient ( url ) . then ( ( { json } ) => ( { data : json . data } ) ) ; } , getManyReference : ( resource , params ) => { const { page , perPage } = params . pagination ; const { q : queryParams , ... otherFilters } = params . filter || { } ; const filter = composeFilter ( otherFilters ) ; filter . push ( { field : params . target , operator : CondOperator . EQUALS , value : params . id , } ) ; const encodedQueryParams = composeQueryParams ( queryParams ) ; const encodedQueryFilter = RequestQueryBuilder . create ( { filter } ) . sortBy ( params . sort as QuerySort ) . setLimit ( perPage ) . setOffset ( ( page - 1 ) * perPage ) . query ( ) ; const query = mergeEncodedQueries ( encodedQueryParams , encodedQueryFilter ) ; const url = `${ apiUrl }/${ resource }?${ query }` ; return httpClient ( url ) . then ( ( { json } ) => ( { data : json . data , total : json . total , } ) ) ; } , update : ( resource , params ) => { const data = countDiff ( params . data , params . previousData ) ; return httpClient ( `${ apiUrl }/${ resource }/${ params . id }` , { method : 'PATCH' , body : JSON . stringify ( data ) , } ) . then ( ( { json } ) => ( { data : json } ) ) ; } , updateMany : ( resource , params ) => Promise . all ( params . ids . map ( ( id ) => httpClient ( `${ apiUrl }/${ resource }/${ id }` , { method : 'PUT' , body : JSON . stringify ( params . data ) , } ) ) ) . then ( ( responses ) => ( { data : responses . map ( ( { json } ) => json ) , } ) ) , create : ( resource , params ) => httpClient ( `${ apiUrl }/${ resource }` , { method : 'POST' , body : JSON . stringify ( params . data ) , } ) . then ( ( { json } ) => ( { data : { ... params . data , id : json . id } , } ) ) , delete : ( resource , params ) => httpClient ( `${ apiUrl }/${ resource }/${ params . id }` , { method : 'DELETE' , } ) . then ( ( { json } ) => ( { data : { ... json , id : params . id } } ) ) , deleteMany : ( resource , params ) => Promise . all ( params . ids . map ( ( id ) => httpClient ( `${ apiUrl }/${ resource }/${ id }` , { method : 'DELETE' , } ) ) ) . then ( ( responses ) => ( { data : responses . map ( ( { json } ) => json ) } ) ) , } ) ;