@@ -2,14 +2,19 @@ import type { PipelineStage } from 'mongoose'
2
2
3
3
import {
4
4
APIError ,
5
+ appendVersionToQueryKey ,
6
+ buildVersionCollectionFields ,
5
7
type CollectionSlug ,
8
+ combineQueries ,
6
9
type FlattenedField ,
10
+ getQueryDraftsSort ,
7
11
type JoinQuery ,
8
12
type SanitizedCollectionConfig ,
9
13
} from 'payload'
10
14
import { fieldShouldBeLocalized } from 'payload/shared'
11
15
12
16
import type { MongooseAdapter } from '../index.js'
17
+ import type { CollectionModel } from '../types.js'
13
18
14
19
import { buildQuery } from '../queries/buildQuery.js'
15
20
import { buildSortParam } from '../queries/buildSortParam.js'
@@ -19,6 +24,7 @@ type BuildJoinAggregationArgs = {
19
24
adapter : MongooseAdapter
20
25
collection : CollectionSlug
21
26
collectionConfig : SanitizedCollectionConfig
27
+ draftsEnabled ?: boolean
22
28
joins ?: JoinQuery
23
29
locale ?: string
24
30
projection ?: Record < string , true >
@@ -32,6 +38,7 @@ export const buildJoinAggregation = async ({
32
38
adapter,
33
39
collection,
34
40
collectionConfig,
41
+ draftsEnabled,
35
42
joins,
36
43
locale,
37
44
projection,
@@ -262,10 +269,27 @@ export const buildJoinAggregation = async ({
262
269
continue
263
270
}
264
271
265
- const { collectionConfig, Model : JoinModel } = getCollection ( {
266
- adapter,
267
- collectionSlug : join . field . collection as string ,
268
- } )
272
+ const collectionConfig = adapter . payload . collections [ join . field . collection as string ] ?. config
273
+
274
+ if ( ! collectionConfig ) {
275
+ throw new APIError (
276
+ `Collection config for ${ join . field . collection . toString ( ) } was not found` ,
277
+ )
278
+ }
279
+
280
+ let JoinModel : CollectionModel | undefined
281
+
282
+ const useDrafts = ( draftsEnabled || versions ) && Boolean ( collectionConfig . versions . drafts )
283
+
284
+ if ( useDrafts ) {
285
+ JoinModel = adapter . versions [ collectionConfig . slug ]
286
+ } else {
287
+ JoinModel = adapter . collections [ collectionConfig . slug ]
288
+ }
289
+
290
+ if ( ! JoinModel ) {
291
+ throw new APIError ( `Join Model was not found for ${ collectionConfig . slug } ` )
292
+ }
269
293
270
294
const {
271
295
count,
@@ -279,12 +303,16 @@ export const buildJoinAggregation = async ({
279
303
throw new Error ( 'Unreachable' )
280
304
}
281
305
306
+ const fields = useDrafts
307
+ ? buildVersionCollectionFields ( adapter . payload . config , collectionConfig , true )
308
+ : collectionConfig . flattenedFields
309
+
282
310
const sort = buildSortParam ( {
283
311
adapter,
284
312
config : adapter . payload . config ,
285
- fields : collectionConfig . flattenedFields ,
313
+ fields,
286
314
locale,
287
- sort : sortJoin ,
315
+ sort : useDrafts ? getQueryDraftsSort ( { collectionConfig , sort : sortJoin } ) : sortJoin ,
288
316
timestamps : true ,
289
317
} )
290
318
const sortProperty = Object . keys ( sort ) [ 0 ] !
@@ -293,7 +321,13 @@ export const buildJoinAggregation = async ({
293
321
const $match = await JoinModel . buildQuery ( {
294
322
locale,
295
323
payload : adapter . payload ,
296
- where : whereJoin ,
324
+ where : useDrafts
325
+ ? combineQueries ( appendVersionToQueryKey ( whereJoin ) , {
326
+ latest : {
327
+ equals : true ,
328
+ } ,
329
+ } )
330
+ : whereJoin ,
297
331
} )
298
332
299
333
const pipeline : Exclude < PipelineStage , PipelineStage . Merge | PipelineStage . Out > [ ] = [
@@ -345,6 +379,12 @@ export const buildJoinAggregation = async ({
345
379
} ,
346
380
)
347
381
382
+ let foreignFieldPrefix = ''
383
+
384
+ if ( useDrafts ) {
385
+ foreignFieldPrefix = 'version.'
386
+ }
387
+
348
388
if ( adapter . payload . config . localization && locale === 'all' ) {
349
389
adapter . payload . config . localization . localeCodes . forEach ( ( code ) => {
350
390
const as = `${ versions ? `version.${ join . joinPath } ` : join . joinPath } ${ code } `
@@ -353,7 +393,7 @@ export const buildJoinAggregation = async ({
353
393
{
354
394
$lookup : {
355
395
as : `${ as } .docs` ,
356
- foreignField : `${ join . field . on } ${ code } ${ polymorphicSuffix } ` ,
396
+ foreignField : `${ foreignFieldPrefix } ${ join . field . on } ${ code } ${ polymorphicSuffix } ` ,
357
397
from : JoinModel . collection . name ,
358
398
localField : versions ? 'parent' : '_id' ,
359
399
pipeline,
@@ -364,7 +404,7 @@ export const buildJoinAggregation = async ({
364
404
[ `${ as } .docs` ] : {
365
405
$map : {
366
406
as : 'doc' ,
367
- in : '$$doc._id' ,
407
+ in : useDrafts ? `$$doc.parent` : '$$doc._id' ,
368
408
input : `$${ as } .docs` ,
369
409
} ,
370
410
} , // Slicing the docs to match the limit
@@ -387,7 +427,10 @@ export const buildJoinAggregation = async ({
387
427
}
388
428
389
429
if ( count ) {
390
- addTotalDocsAggregation ( as , `${ join . field . on } ${ code } ${ polymorphicSuffix } ` )
430
+ addTotalDocsAggregation (
431
+ as ,
432
+ `${ foreignFieldPrefix } ${ join . field . on } ${ code } ${ polymorphicSuffix } ` ,
433
+ )
391
434
}
392
435
} )
393
436
} else {
@@ -414,7 +457,7 @@ export const buildJoinAggregation = async ({
414
457
{
415
458
$lookup : {
416
459
as : `${ as } .docs` ,
417
- foreignField,
460
+ foreignField : ` ${ foreignFieldPrefix } ${ foreignField } ` ,
418
461
from : JoinModel . collection . name ,
419
462
localField : versions ? 'parent' : '_id' ,
420
463
pipeline,
@@ -425,7 +468,7 @@ export const buildJoinAggregation = async ({
425
468
[ `${ as } .docs` ] : {
426
469
$map : {
427
470
as : 'doc' ,
428
- in : '$$doc._id' ,
471
+ in : useDrafts ? `$$doc.parent` : '$$doc._id' ,
429
472
input : `$${ as } .docs` ,
430
473
} ,
431
474
} , // Slicing the docs to match the limit
@@ -437,7 +480,7 @@ export const buildJoinAggregation = async ({
437
480
)
438
481
439
482
if ( count ) {
440
- addTotalDocsAggregation ( as , foreignField )
483
+ addTotalDocsAggregation ( as , ` ${ foreignFieldPrefix } ${ foreignField } ` )
441
484
}
442
485
443
486
if ( limitJoin > 0 ) {
0 commit comments