1- import { HttpMethod } from '../enums/httpMethod' ;
2- import { Model } from '../../../model' ;
3- import { ModelConstructor } from '../../../contracts/modelConstructor' ;
4- import { Scope } from '../scope' ;
5- import { Filter } from '../filter' ;
6- import { FilterOperator } from '../enums/filterOperator' ;
7- import { FilterType } from '../enums/filterType' ;
8- import { Sorter } from '../sorter' ;
9- import { SortDirection } from '../enums/sortDirection' ;
10- import { UrlBuilder } from '../../../builders/urlBuilder' ;
11- import { ExtractModelAttributesType } from '../../../types/extractModelAttributesType' ;
1+ import { HttpMethod } from '../enums/httpMethod' ;
2+ import { Model } from '../../../model' ;
3+ import { ModelConstructor } from '../../../contracts/modelConstructor' ;
4+ import { Scope } from '../scope' ;
5+ import { Filter } from '../filter' ;
6+ import { FilterOperator } from '../enums/filterOperator' ;
7+ import { FilterType } from '../enums/filterType' ;
8+ import { Sorter } from '../sorter' ;
9+ import { SortDirection } from '../enums/sortDirection' ;
10+ import { UrlBuilder } from '../../../builders/urlBuilder' ;
11+ import { ExtractModelAttributesType } from '../../../types/extractModelAttributesType' ;
1212import {
1313 ExtractModelPersistedAttributesType
1414} from '../../../types/extractModelPersistedAttributesType' ;
15- import { ExtractModelRelationsType } from '../../../types/extractModelRelationsType' ;
16- import { HttpClient } from '../../../httpClient' ;
17- import { AxiosResponse } from 'axios' ;
18- import { Orion } from '../../../orion' ;
19- import { ExtractModelKeyType } from '../../../types/extractModelKeyType' ;
15+ import { ExtractModelRelationsType } from '../../../types/extractModelRelationsType' ;
16+ import { HttpClient } from '../../../httpClient' ;
17+ import { AxiosResponse } from 'axios' ;
18+ import { Orion } from '../../../orion' ;
19+ import { ExtractModelKeyType } from '../../../types/extractModelKeyType' ;
20+ import { AggregateItem } from '../../../types/AggregateItem' ;
21+ import { ModelRelations } from '../../../types/ModelRelations' ;
2022
2123export class QueryBuilder <
2224 M extends Model ,
@@ -33,6 +35,12 @@ export class QueryBuilder<
3335 protected includes : string [ ] = [ ] ;
3436 protected fetchTrashed : boolean = false ;
3537 protected fetchOnlyTrashed : boolean = false ;
38+ protected withCountRelations : ModelRelations < Relations > [ ] = [ ] ;
39+ protected withExistsRelations : ModelRelations < Relations > [ ] = [ ] ;
40+ protected withAvgRelations : AggregateItem < Relations > [ ] = [ ] ;
41+ protected withSumRelations : AggregateItem < Relations > [ ] = [ ] ;
42+ protected withMinRelations : AggregateItem < Relations > [ ] = [ ] ;
43+ protected withMaxRelations : AggregateItem < Relations > [ ] = [ ] ;
3644
3745 protected scopes : Array < Scope > = [ ] ;
3846 protected filters : Array < Filter > = [ ] ;
@@ -57,7 +65,7 @@ export class QueryBuilder<
5765 const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
5866 '' ,
5967 HttpMethod . GET ,
60- this . prepareQueryParams ( { limit, page} )
68+ this . prepareQueryParams ( { limit, page } )
6169 ) ;
6270
6371 return response . data . data . map ( ( attributes : AllAttributes & Relations ) => {
@@ -69,12 +77,12 @@ export class QueryBuilder<
6977 const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
7078 '/search' ,
7179 HttpMethod . POST ,
72- this . prepareQueryParams ( { limit, page} ) ,
80+ this . prepareQueryParams ( { limit, page } ) ,
7381 {
7482 scopes : this . scopes ,
7583 filters : this . filters ,
76- search : { value : this . searchValue } ,
77- sort : this . sorters ,
84+ search : { value : this . searchValue } ,
85+ sort : this . sorters
7886 }
7987 ) ;
8088
@@ -109,7 +117,7 @@ export class QueryBuilder<
109117 resources : items . map ( x => x . $attributes )
110118 } ;
111119
112- const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
120+ const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
113121 `/batch` ,
114122 HttpMethod . POST ,
115123 null ,
@@ -118,7 +126,7 @@ export class QueryBuilder<
118126
119127 return response . data . data . map ( ( attributes ) => {
120128 return this . hydrate ( attributes , response ) ;
121- } )
129+ } ) ;
122130 }
123131
124132 public async update ( key : Key , attributes : Attributes ) : Promise < M > {
@@ -138,12 +146,12 @@ export class QueryBuilder<
138146 } ;
139147 items . forEach ( ( v ) => data . resources [ v . $getKey ( ) ] = v . $attributes ) ;
140148
141- const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
149+ const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
142150 `batch` ,
143151 HttpMethod . PATCH ,
144152 null ,
145153 data
146- )
154+ ) ;
147155
148156 return response . data . data . map ( ( attributes : AllAttributes & Relations ) => {
149157 return this . hydrate ( attributes , response ) ;
@@ -154,22 +162,21 @@ export class QueryBuilder<
154162 const response = await this . httpClient . request < { data : AllAttributes & Relations } > (
155163 `/${ key } ` ,
156164 HttpMethod . DELETE ,
157- this . prepareQueryParams ( { force} )
165+ this . prepareQueryParams ( { force } )
158166 ) ;
159167
160168 return this . hydrate ( response . data . data , response ) ;
161169 }
162170
163- public async batchDelete ( items : Key [ ] ) : Promise < M [ ] >
164- {
171+ public async batchDelete ( items : Key [ ] ) : Promise < M [ ] > {
165172 if ( ! items . length )
166173 return [ ] ;
167174
168175 const data = {
169176 resources : items
170177 } ;
171178
172- const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
179+ const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
173180 `/batch` ,
174181 HttpMethod . DELETE ,
175182 null ,
@@ -196,7 +203,7 @@ export class QueryBuilder<
196203 resources : items
197204 } ;
198205
199- const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
206+ const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
200207 `/batch/restore` ,
201208 HttpMethod . POST ,
202209 null ,
@@ -209,7 +216,7 @@ export class QueryBuilder<
209216 }
210217
211218
212- public with ( relations : string [ ] ) : this {
219+ public with ( relations : ModelRelations < Relations > [ ] ) : this {
213220 this . includes = relations ;
214221
215222 return this ;
@@ -281,6 +288,101 @@ export class QueryBuilder<
281288 return model ;
282289 }
283290
291+ /**
292+ * Include the count of the specified relations.
293+ * The relations need to be whitelisted in the controller.
294+ * @link https://tailflow.github.io/laravel-orion-docs/v2.x/guide/search.html#aggregates
295+ */
296+ public withCount ( relations : ModelRelations < Relations > [ ] | ModelRelations < Relations > ) : this {
297+ if ( ! Array . isArray ( relations ) ) {
298+ relations = [ relations ] ;
299+ }
300+
301+ this . withCountRelations . push ( ...relations ) ;
302+
303+ return this ;
304+ }
305+
306+ /**
307+ * Include the exists of the specified relations.
308+ * The relations need to be whitelisted in the controller.
309+ * @link https://tailflow.github.io/laravel-orion-docs/v2.x/guide/search.html#aggregates
310+ * @param relations
311+ */
312+ public withExists ( relations : ModelRelations < Relations > [ ] | ModelRelations < Relations > ) : this {
313+ if ( ! Array . isArray ( relations ) ) {
314+ relations = [ relations ] ;
315+ }
316+
317+ this . withExistsRelations . push ( ...relations ) ;
318+
319+ return this ;
320+ }
321+
322+ /**
323+ * Include the avg of the specified relations.
324+ * The relations need to be whitelisted in the controller.
325+ * @link https://tailflow.github.io/laravel-orion-docs/v2.x/guide/search.html#aggregates
326+ * @param relations
327+ */
328+ public withAvg ( relations : AggregateItem < Relations > [ ] | AggregateItem < Relations > ) : this {
329+ if ( ! Array . isArray ( relations ) ) {
330+ relations = [ relations ] ;
331+ }
332+
333+ this . withAvgRelations . push ( ...relations ) ;
334+
335+ return this ;
336+ }
337+
338+ /**
339+ * Include the sum of the specified relations.
340+ * The relations need to be whitelisted in the controller.
341+ * @link https://tailflow.github.io/laravel-orion-docs/v2.x/guide/search.html#aggregates
342+ * @param relations
343+ */
344+ public withSum ( relations : AggregateItem < Relations > [ ] | AggregateItem < Relations > ) : this {
345+ if ( ! Array . isArray ( relations ) ) {
346+ relations = [ relations ] ;
347+ }
348+
349+ this . withSumRelations . push ( ...relations ) ;
350+
351+ return this ;
352+ }
353+
354+ /**
355+ * Include the min of the specified relations.
356+ * The relations need to be whitelisted in the controller.
357+ * @link https://tailflow.github.io/laravel-orion-docs/v2.x/guide/search.html#aggregates
358+ * @param relations
359+ */
360+ public withMin ( relations : AggregateItem < Relations > [ ] | AggregateItem < Relations > ) : this {
361+ if ( ! Array . isArray ( relations ) ) {
362+ relations = [ relations ] ;
363+ }
364+
365+ this . withMinRelations . push ( ...relations ) ;
366+
367+ return this ;
368+ }
369+
370+ /**
371+ * Include the max of the specified relations.
372+ * The relations need to be whitelisted in the controller.
373+ * @link https://tailflow.github.io/laravel-orion-docs/v2.x/guide/search.html#aggregates
374+ * @param relations
375+ */
376+ public withMax ( relations : AggregateItem < Relations > [ ] | AggregateItem < Relations > ) : this {
377+ if ( ! Array . isArray ( relations ) ) {
378+ relations = [ relations ] ;
379+ }
380+
381+ this . withMaxRelations . push ( ...relations ) ;
382+
383+ return this ;
384+ }
385+
284386 public getHttpClient ( ) : HttpClient {
285387 return this . httpClient ;
286388 }
@@ -298,6 +400,40 @@ export class QueryBuilder<
298400 operationParams . include = this . includes . join ( ',' ) ;
299401 }
300402
403+ if ( this . withCountRelations . length > 0 ) {
404+ operationParams . with_count = this . withCountRelations . join ( ',' ) ;
405+ }
406+
407+ if ( this . withExistsRelations . length > 0 ) {
408+ operationParams . with_exists = this . withExistsRelations . join ( ',' ) ;
409+ }
410+
411+ if ( this . withAvgRelations . length > 0 ) {
412+ operationParams . with_avg = this . withAvgRelations . map ( ( item ) => {
413+ return `${ item . relation } .${ item . column } ` ;
414+ } ) . join ( ',' ) ;
415+ }
416+
417+ if ( this . withSumRelations . length > 0 ) {
418+ operationParams . with_sum = this . withSumRelations . map ( ( item ) => {
419+ return `${ item . relation } .${ item . column } ` ;
420+ } ) . join ( ',' ) ;
421+ }
422+
423+ if ( this . withMinRelations . length > 0 ) {
424+ operationParams . with_min = this . withMinRelations . map ( ( item ) => {
425+ item . relation ;
426+ return `${ item . relation } .${ item . column } ` ;
427+ } ) . join ( ',' ) ;
428+ }
429+
430+ if ( this . withMaxRelations . length > 0 ) {
431+ operationParams . with_max = this . withMaxRelations . map ( ( item ) => {
432+ return `${ item . relation } .${ item . column } ` ;
433+ } ) . join ( ',' ) ;
434+ }
435+
436+
301437 return operationParams ;
302438 }
303439}
0 commit comments