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' ;
12
12
import {
13
13
ExtractModelPersistedAttributesType
14
14
} 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' ;
20
22
21
23
export class QueryBuilder <
22
24
M extends Model ,
@@ -33,6 +35,12 @@ export class QueryBuilder<
33
35
protected includes : string [ ] = [ ] ;
34
36
protected fetchTrashed : boolean = false ;
35
37
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 > [ ] = [ ] ;
36
44
37
45
protected scopes : Array < Scope > = [ ] ;
38
46
protected filters : Array < Filter > = [ ] ;
@@ -57,7 +65,7 @@ export class QueryBuilder<
57
65
const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
58
66
'' ,
59
67
HttpMethod . GET ,
60
- this . prepareQueryParams ( { limit, page} )
68
+ this . prepareQueryParams ( { limit, page } )
61
69
) ;
62
70
63
71
return response . data . data . map ( ( attributes : AllAttributes & Relations ) => {
@@ -69,12 +77,12 @@ export class QueryBuilder<
69
77
const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
70
78
'/search' ,
71
79
HttpMethod . POST ,
72
- this . prepareQueryParams ( { limit, page} ) ,
80
+ this . prepareQueryParams ( { limit, page } ) ,
73
81
{
74
82
scopes : this . scopes ,
75
83
filters : this . filters ,
76
- search : { value : this . searchValue } ,
77
- sort : this . sorters ,
84
+ search : { value : this . searchValue } ,
85
+ sort : this . sorters
78
86
}
79
87
) ;
80
88
@@ -109,7 +117,7 @@ export class QueryBuilder<
109
117
resources : items . map ( x => x . $attributes )
110
118
} ;
111
119
112
- const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
120
+ const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
113
121
`/batch` ,
114
122
HttpMethod . POST ,
115
123
null ,
@@ -118,7 +126,7 @@ export class QueryBuilder<
118
126
119
127
return response . data . data . map ( ( attributes ) => {
120
128
return this . hydrate ( attributes , response ) ;
121
- } )
129
+ } ) ;
122
130
}
123
131
124
132
public async update ( key : Key , attributes : Attributes ) : Promise < M > {
@@ -138,12 +146,12 @@ export class QueryBuilder<
138
146
} ;
139
147
items . forEach ( ( v ) => data . resources [ v . $getKey ( ) ] = v . $attributes ) ;
140
148
141
- const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
149
+ const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
142
150
`batch` ,
143
151
HttpMethod . PATCH ,
144
152
null ,
145
153
data
146
- )
154
+ ) ;
147
155
148
156
return response . data . data . map ( ( attributes : AllAttributes & Relations ) => {
149
157
return this . hydrate ( attributes , response ) ;
@@ -154,22 +162,21 @@ export class QueryBuilder<
154
162
const response = await this . httpClient . request < { data : AllAttributes & Relations } > (
155
163
`/${ key } ` ,
156
164
HttpMethod . DELETE ,
157
- this . prepareQueryParams ( { force} )
165
+ this . prepareQueryParams ( { force } )
158
166
) ;
159
167
160
168
return this . hydrate ( response . data . data , response ) ;
161
169
}
162
170
163
- public async batchDelete ( items : Key [ ] ) : Promise < M [ ] >
164
- {
171
+ public async batchDelete ( items : Key [ ] ) : Promise < M [ ] > {
165
172
if ( ! items . length )
166
173
return [ ] ;
167
174
168
175
const data = {
169
176
resources : items
170
177
} ;
171
178
172
- const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
179
+ const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
173
180
`/batch` ,
174
181
HttpMethod . DELETE ,
175
182
null ,
@@ -196,7 +203,7 @@ export class QueryBuilder<
196
203
resources : items
197
204
} ;
198
205
199
- const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
206
+ const response = await this . httpClient . request < { data : Array < AllAttributes & Relations > } > (
200
207
`/batch/restore` ,
201
208
HttpMethod . POST ,
202
209
null ,
@@ -209,7 +216,7 @@ export class QueryBuilder<
209
216
}
210
217
211
218
212
- public with ( relations : string [ ] ) : this {
219
+ public with ( relations : ModelRelations < Relations > [ ] ) : this {
213
220
this . includes = relations ;
214
221
215
222
return this ;
@@ -281,6 +288,101 @@ export class QueryBuilder<
281
288
return model ;
282
289
}
283
290
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
+
284
386
public getHttpClient ( ) : HttpClient {
285
387
return this . httpClient ;
286
388
}
@@ -298,6 +400,40 @@ export class QueryBuilder<
298
400
operationParams . include = this . includes . join ( ',' ) ;
299
401
}
300
402
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
+
301
437
return operationParams ;
302
438
}
303
439
}
0 commit comments