@payloadcms/db-mongodb 4.0.0-internal.a2d053c → 4.0.0-internal.a5acc33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/connect.d.ts.map +1 -1
- package/dist/connect.js +1 -0
- package/dist/connect.js.map +1 -1
- package/dist/count.d.ts.map +1 -1
- package/dist/count.js +33 -4
- package/dist/count.js.map +1 -1
- package/dist/countGlobalVersions.d.ts.map +1 -1
- package/dist/countGlobalVersions.js +10 -2
- package/dist/countGlobalVersions.js.map +1 -1
- package/dist/countVersions.d.ts.map +1 -1
- package/dist/countVersions.js +36 -4
- package/dist/countVersions.js.map +1 -1
- package/dist/createGlobalVersion.d.ts +1 -1
- package/dist/createGlobalVersion.d.ts.map +1 -1
- package/dist/createGlobalVersion.js +24 -1
- package/dist/createGlobalVersion.js.map +1 -1
- package/dist/createVersion.d.ts.map +1 -1
- package/dist/createVersion.js +16 -3
- package/dist/createVersion.js.map +1 -1
- package/dist/deleteBranchGlobal.d.ts +10 -0
- package/dist/deleteBranchGlobal.d.ts.map +1 -0
- package/dist/deleteBranchGlobal.js +26 -0
- package/dist/deleteBranchGlobal.js.map +1 -0
- package/dist/deleteMany.d.ts.map +1 -1
- package/dist/deleteMany.js +1 -0
- package/dist/deleteMany.js.map +1 -1
- package/dist/deleteOne.d.ts.map +1 -1
- package/dist/deleteOne.js +20 -1
- package/dist/deleteOne.js.map +1 -1
- package/dist/deleteVersions.d.ts.map +1 -1
- package/dist/deleteVersions.js +1 -0
- package/dist/deleteVersions.js.map +1 -1
- package/dist/exports/migration-utils.d.ts +1 -0
- package/dist/exports/migration-utils.d.ts.map +1 -1
- package/dist/exports/migration-utils.js +1 -0
- package/dist/exports/migration-utils.js.map +1 -1
- package/dist/find.d.ts.map +1 -1
- package/dist/find.js +44 -8
- package/dist/find.js.map +1 -1
- package/dist/findDistinct.d.ts.map +1 -1
- package/dist/findDistinct.js +70 -11
- package/dist/findDistinct.js.map +1 -1
- package/dist/findGlobal.d.ts.map +1 -1
- package/dist/findGlobal.js +48 -9
- package/dist/findGlobal.js.map +1 -1
- package/dist/findGlobalVersions.d.ts.map +1 -1
- package/dist/findGlobalVersions.js +10 -2
- package/dist/findGlobalVersions.js.map +1 -1
- package/dist/findOne.d.ts.map +1 -1
- package/dist/findOne.js +43 -5
- package/dist/findOne.js.map +1 -1
- package/dist/findVersions.d.ts.map +1 -1
- package/dist/findVersions.js +49 -5
- package/dist/findVersions.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/models/buildGlobalModel.d.ts.map +1 -1
- package/dist/models/buildGlobalModel.js +30 -1
- package/dist/models/buildGlobalModel.js.map +1 -1
- package/dist/models/buildSchema.d.ts.map +1 -1
- package/dist/models/buildSchema.js +36 -10
- package/dist/models/buildSchema.js.map +1 -1
- package/dist/predefinedMigrations/branching.d.ts +4 -0
- package/dist/predefinedMigrations/branching.d.ts.map +1 -0
- package/dist/predefinedMigrations/branching.js +9 -0
- package/dist/predefinedMigrations/branching.js.map +1 -0
- package/dist/predefinedMigrations/migrateBranching.d.ts +17 -0
- package/dist/predefinedMigrations/migrateBranching.d.ts.map +1 -0
- package/dist/predefinedMigrations/migrateBranching.js +90 -0
- package/dist/predefinedMigrations/migrateBranching.js.map +1 -0
- package/dist/queries/buildAndOrConditions.d.ts +4 -2
- package/dist/queries/buildAndOrConditions.d.ts.map +1 -1
- package/dist/queries/buildAndOrConditions.js +3 -1
- package/dist/queries/buildAndOrConditions.js.map +1 -1
- package/dist/queries/buildBranchVisibility.d.ts +11 -0
- package/dist/queries/buildBranchVisibility.d.ts.map +1 -0
- package/dist/queries/buildBranchVisibility.js +204 -0
- package/dist/queries/buildBranchVisibility.js.map +1 -0
- package/dist/queries/buildQuery.d.ts +4 -2
- package/dist/queries/buildQuery.d.ts.map +1 -1
- package/dist/queries/buildQuery.js +3 -1
- package/dist/queries/buildQuery.js.map +1 -1
- package/dist/queries/buildRelatedQueryPipeline.d.ts +7 -0
- package/dist/queries/buildRelatedQueryPipeline.d.ts.map +1 -0
- package/dist/queries/buildRelatedQueryPipeline.js +56 -0
- package/dist/queries/buildRelatedQueryPipeline.js.map +1 -0
- package/dist/queries/buildSearchParams.d.ts +4 -2
- package/dist/queries/buildSearchParams.d.ts.map +1 -1
- package/dist/queries/buildSearchParams.js +177 -45
- package/dist/queries/buildSearchParams.js.map +1 -1
- package/dist/queries/getBuildQueryPlugin.d.ts +3 -1
- package/dist/queries/getBuildQueryPlugin.d.ts.map +1 -1
- package/dist/queries/getBuildQueryPlugin.js +3 -1
- package/dist/queries/getBuildQueryPlugin.js.map +1 -1
- package/dist/queries/parseParams.d.ts +4 -2
- package/dist/queries/parseParams.d.ts.map +1 -1
- package/dist/queries/parseParams.js +5 -1
- package/dist/queries/parseParams.js.map +1 -1
- package/dist/queryDrafts.d.ts.map +1 -1
- package/dist/queryDrafts.js +39 -7
- package/dist/queryDrafts.js.map +1 -1
- package/dist/transactions/commitTransaction.d.ts.map +1 -1
- package/dist/transactions/commitTransaction.js +69 -7
- package/dist/transactions/commitTransaction.js.map +1 -1
- package/dist/transactions/rollbackTransaction.d.ts.map +1 -1
- package/dist/transactions/rollbackTransaction.js +10 -9
- package/dist/transactions/rollbackTransaction.js.map +1 -1
- package/dist/updateGlobal.d.ts.map +1 -1
- package/dist/updateGlobal.js +89 -7
- package/dist/updateGlobal.js.map +1 -1
- package/dist/updateGlobalVersion.d.ts.map +1 -1
- package/dist/updateGlobalVersion.js +1 -0
- package/dist/updateGlobalVersion.js.map +1 -1
- package/dist/updateMany.d.ts.map +1 -1
- package/dist/updateMany.js +3 -1
- package/dist/updateMany.js.map +1 -1
- package/dist/updateOne.d.ts.map +1 -1
- package/dist/updateOne.js +28 -2
- package/dist/updateOne.js.map +1 -1
- package/dist/updateVersion.d.ts.map +1 -1
- package/dist/updateVersion.js +1 -0
- package/dist/updateVersion.js.map +1 -1
- package/dist/upsertBranchGlobalChange.d.ts +3 -0
- package/dist/upsertBranchGlobalChange.d.ts.map +1 -0
- package/dist/upsertBranchGlobalChange.js +28 -0
- package/dist/upsertBranchGlobalChange.js.map +1 -0
- package/dist/utilities/aggregatePaginate.d.ts +2 -1
- package/dist/utilities/aggregatePaginate.d.ts.map +1 -1
- package/dist/utilities/aggregatePaginate.js +18 -4
- package/dist/utilities/aggregatePaginate.js.map +1 -1
- package/dist/utilities/buildJoinAggregation.d.ts +4 -2
- package/dist/utilities/buildJoinAggregation.d.ts.map +1 -1
- package/dist/utilities/buildJoinAggregation.js +141 -11
- package/dist/utilities/buildJoinAggregation.js.map +1 -1
- package/dist/utilities/resolveJoins.d.ts +6 -2
- package/dist/utilities/resolveJoins.d.ts.map +1 -1
- package/dist/utilities/resolveJoins.js +115 -26
- package/dist/utilities/resolveJoins.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { APIError, appendVersionToQueryKey, buildVersionCollectionFields, combineQueries, getQueryDraftsSort } from 'payload';
|
|
1
|
+
import { APIError, appendVersionToQueryKey, buildVersionCollectionFields, combineQueries, getBranchPredicateSync, getQueryDraftsSort, resolveBranchReadState, resolveBranchVersionQuery, rewriteBranchIDs, rewriteBranchVersionParents } from 'payload';
|
|
2
2
|
import { fieldShouldBeLocalized, hasDraftsEnabled } from 'payload/shared';
|
|
3
|
+
import { buildBranchVisibilityStages } from '../queries/buildBranchVisibility.js';
|
|
3
4
|
import { buildQuery } from '../queries/buildQuery.js';
|
|
4
5
|
import { buildSortParam } from '../queries/buildSortParam.js';
|
|
5
6
|
import { getCollection } from './getEntity.js';
|
|
6
|
-
export const buildJoinAggregation = async ({ adapter, collection, collectionConfig, draftsEnabled, joins, locale, projection, versions })=>{
|
|
7
|
+
export const buildJoinAggregation = async ({ adapter, branch, collection, collectionConfig, draftsEnabled, joins, locale, projection, req, versions })=>{
|
|
7
8
|
if (!adapter.useJoinAggregations) {
|
|
8
9
|
return [];
|
|
9
10
|
}
|
|
@@ -15,6 +16,17 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
15
16
|
throw new APIError(`Could not retrieve sanitized join config for ${collection}.`);
|
|
16
17
|
}
|
|
17
18
|
const aggregate = [];
|
|
19
|
+
const outerBranchReadState = resolveBranchReadState({
|
|
20
|
+
branch,
|
|
21
|
+
collectionSlug: collection,
|
|
22
|
+
req
|
|
23
|
+
});
|
|
24
|
+
const canonicalParentField = '__payloadJoinParentID';
|
|
25
|
+
let localField = versions ? 'parent' : '_id';
|
|
26
|
+
if (outerBranchReadState.useBranching) {
|
|
27
|
+
localField = canonicalParentField;
|
|
28
|
+
}
|
|
29
|
+
const rootIDExpression = outerBranchReadState.useBranching ? `$${canonicalParentField}` : '$_id';
|
|
18
30
|
const polymorphicJoinsConfig = adapter.payload.collections[collection]?.config?.polymorphicJoins;
|
|
19
31
|
if (!polymorphicJoinsConfig) {
|
|
20
32
|
throw new APIError(`Could not retrieve sanitized polymorphic joins config for ${collection}.`);
|
|
@@ -49,8 +61,10 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
49
61
|
});
|
|
50
62
|
const $match = await buildQuery({
|
|
51
63
|
adapter,
|
|
64
|
+
branch,
|
|
52
65
|
fields: aggregatedFields,
|
|
53
66
|
locale,
|
|
67
|
+
req,
|
|
54
68
|
where: whereJoin
|
|
55
69
|
});
|
|
56
70
|
const sortProperty = Object.keys(sort)[0]// assert because buildSortParam always returns at least 1 key.
|
|
@@ -62,6 +76,29 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
62
76
|
for (const collectionSlug of join.field.collection){
|
|
63
77
|
const alias = `${as}.docs.${collectionSlug}`;
|
|
64
78
|
aliases.push(alias);
|
|
79
|
+
const joinBranchPredicate = getBranchPredicateSync({
|
|
80
|
+
branch,
|
|
81
|
+
collectionSlug,
|
|
82
|
+
req
|
|
83
|
+
});
|
|
84
|
+
const joinBranchReadState = resolveBranchReadState({
|
|
85
|
+
branch,
|
|
86
|
+
collectionSlug,
|
|
87
|
+
req
|
|
88
|
+
});
|
|
89
|
+
const branchMatch = joinBranchPredicate ? await buildQuery({
|
|
90
|
+
adapter,
|
|
91
|
+
branch,
|
|
92
|
+
fields: adapter.payload.collections[collectionSlug].config.flattenedFields,
|
|
93
|
+
locale,
|
|
94
|
+
req,
|
|
95
|
+
where: joinBranchPredicate
|
|
96
|
+
}) : undefined;
|
|
97
|
+
const branchVisibility = joinBranchReadState.useBranching ? buildBranchVisibilityStages({
|
|
98
|
+
adapter,
|
|
99
|
+
branch: joinBranchReadState.branch,
|
|
100
|
+
collectionSlug
|
|
101
|
+
}) : [];
|
|
65
102
|
const basePipeline = [
|
|
66
103
|
{
|
|
67
104
|
$addFields: {
|
|
@@ -81,10 +118,26 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
81
118
|
]
|
|
82
119
|
}
|
|
83
120
|
},
|
|
84
|
-
$match
|
|
121
|
+
$match,
|
|
122
|
+
...branchMatch ? [
|
|
123
|
+
branchMatch
|
|
124
|
+
] : []
|
|
85
125
|
]
|
|
86
126
|
}
|
|
87
|
-
}
|
|
127
|
+
},
|
|
128
|
+
...branchVisibility,
|
|
129
|
+
...joinBranchPredicate || branchVisibility.length ? [
|
|
130
|
+
{
|
|
131
|
+
$set: {
|
|
132
|
+
_id: {
|
|
133
|
+
$ifNull: [
|
|
134
|
+
'$_branchDocID',
|
|
135
|
+
'$_id'
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
] : []
|
|
88
141
|
];
|
|
89
142
|
const { Model: JoinModel } = getCollection({
|
|
90
143
|
adapter,
|
|
@@ -95,7 +148,7 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
95
148
|
as: alias,
|
|
96
149
|
from: JoinModel.collection.name,
|
|
97
150
|
let: {
|
|
98
|
-
root_id_:
|
|
151
|
+
root_id_: rootIDExpression
|
|
99
152
|
},
|
|
100
153
|
pipeline: [
|
|
101
154
|
...basePipeline,
|
|
@@ -128,7 +181,7 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
128
181
|
as: `${as}.totalDocs.${alias}`,
|
|
129
182
|
from: JoinModel.collection.name,
|
|
130
183
|
let: {
|
|
131
|
-
root_id_:
|
|
184
|
+
root_id_: rootIDExpression
|
|
132
185
|
},
|
|
133
186
|
pipeline: [
|
|
134
187
|
...basePipeline,
|
|
@@ -251,19 +304,75 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
251
304
|
});
|
|
252
305
|
const sortProperty = Object.keys(sort)[0];
|
|
253
306
|
const sortDirection = sort[sortProperty] === 'asc' ? 1 : -1;
|
|
307
|
+
// A join subquery must carry the same branch predicate as the top-level
|
|
308
|
+
// read, or a branch would see main's related documents.
|
|
309
|
+
const joinBranchPredicate = getBranchPredicateSync({
|
|
310
|
+
branch,
|
|
311
|
+
collectionSlug: collectionConfig.slug,
|
|
312
|
+
req
|
|
313
|
+
});
|
|
314
|
+
const joinBranchReadState = resolveBranchReadState({
|
|
315
|
+
branch,
|
|
316
|
+
collectionSlug: collectionConfig.slug,
|
|
317
|
+
req
|
|
318
|
+
});
|
|
319
|
+
const resolvedWhereJoin = useDrafts ? joinBranchReadState.useBranching ? rewriteBranchVersionParents(appendVersionToQueryKey(whereJoin)) ?? {} : await resolveBranchVersionQuery({
|
|
320
|
+
branch,
|
|
321
|
+
collectionSlug: collectionConfig.slug,
|
|
322
|
+
req,
|
|
323
|
+
where: appendVersionToQueryKey(whereJoin)
|
|
324
|
+
}) ?? {} : joinBranchReadState.useBranching ? rewriteBranchIDs(whereJoin) ?? {} : joinBranchPredicate ? {
|
|
325
|
+
and: [
|
|
326
|
+
whereJoin,
|
|
327
|
+
joinBranchPredicate
|
|
328
|
+
]
|
|
329
|
+
} : whereJoin;
|
|
254
330
|
const $match = await JoinModel.buildQuery({
|
|
331
|
+
branch,
|
|
255
332
|
locale,
|
|
256
333
|
payload: adapter.payload,
|
|
257
|
-
|
|
334
|
+
req,
|
|
335
|
+
where: useDrafts ? combineQueries(resolvedWhereJoin, {
|
|
258
336
|
latest: {
|
|
259
337
|
equals: true
|
|
260
338
|
}
|
|
261
|
-
}) :
|
|
339
|
+
}) : resolvedWhereJoin
|
|
262
340
|
});
|
|
341
|
+
const branchVisibility = joinBranchReadState.useBranching ? buildBranchVisibilityStages({
|
|
342
|
+
adapter,
|
|
343
|
+
branch: joinBranchReadState.branch,
|
|
344
|
+
collectionSlug: collectionConfig.slug,
|
|
345
|
+
mode: useDrafts ? 'drafts' : 'documents'
|
|
346
|
+
}) : [];
|
|
263
347
|
const pipeline = [
|
|
264
348
|
{
|
|
265
349
|
$match
|
|
266
350
|
},
|
|
351
|
+
...branchVisibility,
|
|
352
|
+
// Surface the canonical document ID rather than the shadow row's own
|
|
353
|
+
// primary key, so join results address documents the same way every
|
|
354
|
+
// other read does.
|
|
355
|
+
...joinBranchPredicate || branchVisibility.length ? [
|
|
356
|
+
useDrafts ? {
|
|
357
|
+
$set: {
|
|
358
|
+
parent: {
|
|
359
|
+
$ifNull: [
|
|
360
|
+
'$_branchParent',
|
|
361
|
+
'$parent'
|
|
362
|
+
]
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
} : {
|
|
366
|
+
$set: {
|
|
367
|
+
_id: {
|
|
368
|
+
$ifNull: [
|
|
369
|
+
'$_branchDocID',
|
|
370
|
+
'$_id'
|
|
371
|
+
]
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
] : [],
|
|
267
376
|
{
|
|
268
377
|
$sort: {
|
|
269
378
|
[sortProperty]: sortDirection
|
|
@@ -289,11 +398,12 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
289
398
|
as: `${as}.totalDocs`,
|
|
290
399
|
foreignField,
|
|
291
400
|
from: JoinModel.collection.name,
|
|
292
|
-
localField
|
|
401
|
+
localField,
|
|
293
402
|
pipeline: [
|
|
294
403
|
{
|
|
295
404
|
$match
|
|
296
405
|
},
|
|
406
|
+
...branchVisibility,
|
|
297
407
|
{
|
|
298
408
|
$count: 'result'
|
|
299
409
|
}
|
|
@@ -323,7 +433,7 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
323
433
|
as: `${as}.docs`,
|
|
324
434
|
foreignField: `${foreignFieldPrefix}${join.field.on}${code}${polymorphicSuffix}`,
|
|
325
435
|
from: JoinModel.collection.name,
|
|
326
|
-
localField
|
|
436
|
+
localField,
|
|
327
437
|
pipeline
|
|
328
438
|
}
|
|
329
439
|
}, {
|
|
@@ -380,7 +490,7 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
380
490
|
as: `${as}.docs`,
|
|
381
491
|
foreignField: `${foreignFieldPrefix}${foreignField}`,
|
|
382
492
|
from: JoinModel.collection.name,
|
|
383
|
-
localField
|
|
493
|
+
localField,
|
|
384
494
|
pipeline
|
|
385
495
|
}
|
|
386
496
|
}, {
|
|
@@ -420,6 +530,26 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
|
|
|
420
530
|
}
|
|
421
531
|
}
|
|
422
532
|
}
|
|
533
|
+
if (aggregate.length && outerBranchReadState.useBranching) {
|
|
534
|
+
aggregate.unshift({
|
|
535
|
+
$set: {
|
|
536
|
+
[canonicalParentField]: versions ? {
|
|
537
|
+
$ifNull: [
|
|
538
|
+
'$_branchParent',
|
|
539
|
+
'$parent'
|
|
540
|
+
]
|
|
541
|
+
} : {
|
|
542
|
+
$ifNull: [
|
|
543
|
+
'$_branchDocID',
|
|
544
|
+
'$_id'
|
|
545
|
+
]
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
aggregate.push({
|
|
550
|
+
$unset: canonicalParentField
|
|
551
|
+
});
|
|
552
|
+
}
|
|
423
553
|
return aggregate;
|
|
424
554
|
};
|
|
425
555
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/buildJoinAggregation.ts"],"sourcesContent":["import type { PipelineStage } from 'mongoose'\n\nimport {\n APIError,\n appendVersionToQueryKey,\n buildVersionCollectionFields,\n type CollectionSlug,\n combineQueries,\n type FlattenedField,\n getQueryDraftsSort,\n type JoinQuery,\n type SanitizedCollectionConfig,\n} from 'payload'\nimport { fieldShouldBeLocalized, hasDraftsEnabled } from 'payload/shared'\n\nimport type { MongooseAdapter } from '../index.js'\nimport type { CollectionModel } from '../types.js'\n\nimport { buildQuery } from '../queries/buildQuery.js'\nimport { buildSortParam } from '../queries/buildSortParam.js'\nimport { getCollection } from './getEntity.js'\n\ntype BuildJoinAggregationArgs = {\n adapter: MongooseAdapter\n collection: CollectionSlug\n collectionConfig: SanitizedCollectionConfig\n draftsEnabled?: boolean\n joins?: JoinQuery\n locale?: string\n projection?: Record<string, true>\n // the where clause for the top collection\n query?: Record<string, unknown>\n /** whether the query is from drafts */\n versions?: boolean\n}\n\nexport const buildJoinAggregation = async ({\n adapter,\n collection,\n collectionConfig,\n draftsEnabled,\n joins,\n locale,\n projection,\n versions,\n}: BuildJoinAggregationArgs): Promise<PipelineStage[]> => {\n if (!adapter.useJoinAggregations) {\n return []\n }\n if (\n (Object.keys(collectionConfig.joins).length === 0 &&\n collectionConfig.polymorphicJoins.length == 0) ||\n joins === false\n ) {\n return []\n }\n\n const joinConfig = adapter.payload.collections[collection]?.config?.joins\n\n if (!joinConfig) {\n throw new APIError(`Could not retrieve sanitized join config for ${collection}.`)\n }\n\n const aggregate: PipelineStage[] = []\n const polymorphicJoinsConfig = adapter.payload.collections[collection]?.config?.polymorphicJoins\n\n if (!polymorphicJoinsConfig) {\n throw new APIError(`Could not retrieve sanitized polymorphic joins config for ${collection}.`)\n }\n\n for (const join of polymorphicJoinsConfig) {\n if (projection && !projection[join.joinPath]) {\n continue\n }\n\n if (joins?.[join.joinPath] === false) {\n continue\n }\n\n const {\n count = false,\n limit: limitJoin = join.field.defaultLimit ?? 10,\n page,\n sort: sortJoin = join.field.defaultSort || collectionConfig.defaultSort,\n where: whereJoin = {},\n } = joins?.[join.joinPath] || {}\n\n const aggregatedFields: FlattenedField[] = []\n for (const collectionSlug of join.field.collection) {\n const { collectionConfig } = getCollection({ adapter, collectionSlug })\n\n for (const field of collectionConfig.flattenedFields) {\n if (!aggregatedFields.some((eachField) => eachField.name === field.name)) {\n aggregatedFields.push(field)\n }\n }\n }\n\n const sort = buildSortParam({\n adapter,\n config: adapter.payload.config,\n fields: aggregatedFields,\n locale,\n sort: sortJoin,\n timestamps: true,\n })\n\n const $match = await buildQuery({\n adapter,\n fields: aggregatedFields,\n locale,\n where: whereJoin,\n })\n\n const sortProperty = Object.keys(sort)[0]! // assert because buildSortParam always returns at least 1 key.\n const sortDirection = sort[sortProperty] === 'asc' ? 1 : -1\n\n const projectSort = sortProperty !== '_id' && sortProperty !== 'relationTo'\n\n const aliases: string[] = []\n\n const as = join.joinPath\n\n for (const collectionSlug of join.field.collection) {\n const alias = `${as}.docs.${collectionSlug}`\n aliases.push(alias)\n\n const basePipeline = [\n {\n $addFields: {\n relationTo: {\n $literal: collectionSlug,\n },\n },\n },\n {\n $match: {\n $and: [\n {\n $expr: {\n $eq: [`$${join.field.on}`, '$$root_id_'],\n },\n },\n $match,\n ],\n },\n },\n ]\n\n const { Model: JoinModel } = getCollection({ adapter, collectionSlug })\n\n aggregate.push({\n $lookup: {\n as: alias,\n from: JoinModel.collection.name,\n let: {\n root_id_: '$_id',\n },\n pipeline: [\n ...basePipeline,\n {\n $sort: {\n [sortProperty]: sortDirection,\n },\n },\n ...(limitJoin > 0\n ? [\n {\n // Unfortunately, we can't use $skip here because we can lose data, instead we do $slice then\n $limit: page ? page * limitJoin : limitJoin,\n },\n ]\n : []),\n {\n $project: {\n value: '$_id',\n ...(projectSort && {\n [sortProperty]: 1,\n }),\n relationTo: 1,\n },\n },\n ],\n },\n })\n\n if (count) {\n aggregate.push({\n $lookup: {\n as: `${as}.totalDocs.${alias}`,\n from: JoinModel.collection.name,\n let: {\n root_id_: '$_id',\n },\n pipeline: [\n ...basePipeline,\n {\n $count: 'result',\n },\n ],\n },\n })\n }\n }\n\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $concatArrays: aliases.map((alias) => `$${alias}`),\n },\n },\n })\n\n if (count) {\n aggregate.push({\n $addFields: {\n [`${as}.totalDocs`]: {\n $add: aliases.map((alias) => ({\n $ifNull: [\n {\n $first: `$${as}.totalDocs.${alias}.result`,\n },\n 0,\n ],\n })),\n },\n },\n })\n }\n\n aggregate.push({\n $set: {\n [`${as}.docs`]: {\n $sortArray: {\n input: `$${as}.docs`,\n sortBy: {\n [sortProperty]: sortDirection,\n },\n },\n },\n },\n })\n\n const sliceValue = page ? [(page - 1) * limitJoin, limitJoin] : [limitJoin]\n\n aggregate.push({\n $addFields: {\n [`${as}.hasNextPage`]: {\n $gt: [{ $size: `$${as}.docs` }, limitJoin || Number.MAX_VALUE],\n },\n },\n })\n\n if (limitJoin > 0) {\n aggregate.push({\n $set: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, ...sliceValue],\n },\n },\n })\n }\n }\n\n for (const slug of Object.keys(joinConfig)) {\n const joinsList = joinConfig[slug]\n\n if (!joinsList) {\n throw new APIError(`Failed to retrieve array of joins for ${slug} in collectio ${collection}`)\n }\n\n for (const join of joinsList) {\n const projectionPath = versions ? `version.${join.joinPath}` : join.joinPath\n if (projection && !projection[projectionPath]) {\n continue\n }\n\n if (joins?.[join.joinPath] === false) {\n continue\n }\n\n const collectionConfig = adapter.payload.collections[join.field.collection as string]?.config\n\n if (!collectionConfig) {\n throw new APIError(\n `Collection config for ${join.field.collection.toString()} was not found`,\n )\n }\n\n let JoinModel: CollectionModel | undefined\n\n const useDrafts = (draftsEnabled || versions) && hasDraftsEnabled(collectionConfig)\n\n if (useDrafts) {\n JoinModel = adapter.versions[collectionConfig.slug]\n } else {\n JoinModel = adapter.collections[collectionConfig.slug]\n }\n\n if (!JoinModel) {\n throw new APIError(`Join Model was not found for ${collectionConfig.slug}`)\n }\n\n const {\n count,\n limit: limitJoin = join.field.defaultLimit ?? 10,\n page,\n sort: sortJoin = join.field.defaultSort || collectionConfig.defaultSort,\n where: whereJoin = {},\n } = joins?.[join.joinPath] || {}\n\n if (Array.isArray(join.field.collection)) {\n throw new Error('Unreachable')\n }\n\n const fields = useDrafts\n ? buildVersionCollectionFields(adapter.payload.config, collectionConfig, true)\n : collectionConfig.flattenedFields\n\n const sort = buildSortParam({\n adapter,\n config: adapter.payload.config,\n fields,\n locale,\n sort: useDrafts ? getQueryDraftsSort({ collectionConfig, sort: sortJoin }) : sortJoin,\n timestamps: true,\n })\n const sortProperty = Object.keys(sort)[0]!\n const sortDirection = sort[sortProperty] === 'asc' ? 1 : -1\n\n const $match = await JoinModel.buildQuery({\n locale,\n payload: adapter.payload,\n where: useDrafts\n ? combineQueries(appendVersionToQueryKey(whereJoin), {\n latest: {\n equals: true,\n },\n })\n : whereJoin,\n })\n\n const pipeline: Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out>[] = [\n { $match },\n {\n $sort: { [sortProperty]: sortDirection },\n },\n ]\n\n if (page) {\n pipeline.push({\n $skip: (page - 1) * limitJoin,\n })\n }\n\n if (limitJoin > 0) {\n pipeline.push({\n $limit: limitJoin + 1,\n })\n }\n\n let polymorphicSuffix = ''\n if (Array.isArray(join.targetField.relationTo)) {\n polymorphicSuffix = '.value'\n }\n\n const addTotalDocsAggregation = (as: string, foreignField: string) =>\n aggregate.push(\n {\n $lookup: {\n as: `${as}.totalDocs`,\n foreignField,\n from: JoinModel.collection.name,\n localField: versions ? 'parent' : '_id',\n pipeline: [\n {\n $match,\n },\n {\n $count: 'result',\n },\n ],\n },\n },\n {\n $addFields: {\n [`${as}.totalDocs`]: { $ifNull: [{ $first: `$${as}.totalDocs.result` }, 0] },\n },\n },\n )\n\n let foreignFieldPrefix = ''\n\n if (useDrafts) {\n foreignFieldPrefix = 'version.'\n }\n\n if (adapter.payload.config.localization && locale === 'all') {\n adapter.payload.config.localization.localeCodes.forEach((code) => {\n const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${code}`\n\n aggregate.push(\n {\n $lookup: {\n as: `${as}.docs`,\n foreignField: `${foreignFieldPrefix}${join.field.on}${code}${polymorphicSuffix}`,\n from: JoinModel.collection.name,\n localField: versions ? 'parent' : '_id',\n pipeline,\n },\n },\n {\n $addFields: {\n [`${as}.docs`]: {\n $map: {\n as: 'doc',\n in: useDrafts ? `$$doc.parent` : '$$doc._id',\n input: `$${as}.docs`,\n },\n }, // Slicing the docs to match the limit\n [`${as}.hasNextPage`]: limitJoin\n ? { $gt: [{ $size: `$${as}.docs` }, limitJoin] }\n : false,\n // Boolean indicating if more docs than limit\n },\n },\n )\n\n if (limitJoin > 0) {\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, limitJoin],\n },\n },\n })\n }\n\n if (count) {\n addTotalDocsAggregation(\n as,\n `${foreignFieldPrefix}${join.field.on}${code}${polymorphicSuffix}`,\n )\n }\n })\n } else {\n const localeSuffix =\n fieldShouldBeLocalized({\n field: join.field,\n parentIsLocalized: join.parentIsLocalized,\n }) &&\n adapter.payload.config.localization &&\n locale\n ? `.${locale}`\n : ''\n const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${localeSuffix}`\n\n let foreignField: string\n\n if (join.getForeignPath) {\n foreignField = `${join.getForeignPath({ locale })}${polymorphicSuffix}`\n } else {\n foreignField = `${join.field.on}${polymorphicSuffix}`\n }\n\n aggregate.push(\n {\n $lookup: {\n as: `${as}.docs`,\n foreignField: `${foreignFieldPrefix}${foreignField}`,\n from: JoinModel.collection.name,\n localField: versions ? 'parent' : '_id',\n pipeline,\n },\n },\n {\n $addFields: {\n [`${as}.docs`]: {\n $map: {\n as: 'doc',\n in: useDrafts ? `$$doc.parent` : '$$doc._id',\n input: `$${as}.docs`,\n },\n }, // Slicing the docs to match the limit\n [`${as}.hasNextPage`]: {\n $gt: [{ $size: `$${as}.docs` }, limitJoin || Number.MAX_VALUE],\n }, // Boolean indicating if more docs than limit\n },\n },\n )\n\n if (count) {\n addTotalDocsAggregation(as, `${foreignFieldPrefix}${foreignField}`)\n }\n\n if (limitJoin > 0) {\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, limitJoin],\n },\n },\n })\n }\n }\n }\n }\n\n return aggregate\n}\n"],"names":["APIError","appendVersionToQueryKey","buildVersionCollectionFields","combineQueries","getQueryDraftsSort","fieldShouldBeLocalized","hasDraftsEnabled","buildQuery","buildSortParam","getCollection","buildJoinAggregation","adapter","collection","collectionConfig","draftsEnabled","joins","locale","projection","versions","useJoinAggregations","Object","keys","length","polymorphicJoins","joinConfig","payload","collections","config","aggregate","polymorphicJoinsConfig","join","joinPath","count","limit","limitJoin","field","defaultLimit","page","sort","sortJoin","defaultSort","where","whereJoin","aggregatedFields","collectionSlug","flattenedFields","some","eachField","name","push","fields","timestamps","$match","sortProperty","sortDirection","projectSort","aliases","as","alias","basePipeline","$addFields","relationTo","$literal","$and","$expr","$eq","on","Model","JoinModel","$lookup","from","let","root_id_","pipeline","$sort","$limit","$project","value","$count","$concatArrays","map","$add","$ifNull","$first","$set","$sortArray","input","sortBy","sliceValue","$gt","$size","Number","MAX_VALUE","$slice","slug","joinsList","projectionPath","toString","useDrafts","Array","isArray","Error","latest","equals","$skip","polymorphicSuffix","targetField","addTotalDocsAggregation","foreignField","localField","foreignFieldPrefix","localization","localeCodes","forEach","code","$map","in","localeSuffix","parentIsLocalized","getForeignPath"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/buildJoinAggregation.ts"],"sourcesContent":["import type { PipelineStage } from 'mongoose'\n\nimport {\n APIError,\n appendVersionToQueryKey,\n buildVersionCollectionFields,\n type CollectionSlug,\n combineQueries,\n type FlattenedField,\n getBranchPredicateSync,\n getQueryDraftsSort,\n type JoinQuery,\n type PayloadRequest,\n resolveBranchReadState,\n resolveBranchVersionQuery,\n rewriteBranchIDs,\n rewriteBranchVersionParents,\n type SanitizedCollectionConfig,\n type Where,\n} from 'payload'\nimport { fieldShouldBeLocalized, hasDraftsEnabled } from 'payload/shared'\n\nimport type { MongooseAdapter } from '../index.js'\nimport type { CollectionModel } from '../types.js'\n\nimport { buildBranchVisibilityStages } from '../queries/buildBranchVisibility.js'\nimport { buildQuery } from '../queries/buildQuery.js'\nimport { buildSortParam } from '../queries/buildSortParam.js'\nimport { getCollection } from './getEntity.js'\n\ntype BuildJoinAggregationArgs = {\n adapter: MongooseAdapter\n branch?: false | string\n collection: CollectionSlug\n collectionConfig: SanitizedCollectionConfig\n draftsEnabled?: boolean\n joins?: JoinQuery\n locale?: string\n projection?: Record<string, true>\n // the where clause for the top collection\n query?: Record<string, unknown>\n req?: Partial<PayloadRequest>\n /** whether the query is from drafts */\n versions?: boolean\n}\n\nexport const buildJoinAggregation = async ({\n adapter,\n branch,\n collection,\n collectionConfig,\n draftsEnabled,\n joins,\n locale,\n projection,\n req,\n versions,\n}: BuildJoinAggregationArgs): Promise<PipelineStage[]> => {\n if (!adapter.useJoinAggregations) {\n return []\n }\n if (\n (Object.keys(collectionConfig.joins).length === 0 &&\n collectionConfig.polymorphicJoins.length == 0) ||\n joins === false\n ) {\n return []\n }\n\n const joinConfig = adapter.payload.collections[collection]?.config?.joins\n\n if (!joinConfig) {\n throw new APIError(`Could not retrieve sanitized join config for ${collection}.`)\n }\n\n const aggregate: PipelineStage[] = []\n const outerBranchReadState = resolveBranchReadState({ branch, collectionSlug: collection, req })\n const canonicalParentField = '__payloadJoinParentID'\n let localField = versions ? 'parent' : '_id'\n\n if (outerBranchReadState.useBranching) {\n localField = canonicalParentField\n }\n\n const rootIDExpression = outerBranchReadState.useBranching ? `$${canonicalParentField}` : '$_id'\n const polymorphicJoinsConfig = adapter.payload.collections[collection]?.config?.polymorphicJoins\n\n if (!polymorphicJoinsConfig) {\n throw new APIError(`Could not retrieve sanitized polymorphic joins config for ${collection}.`)\n }\n\n for (const join of polymorphicJoinsConfig) {\n if (projection && !projection[join.joinPath]) {\n continue\n }\n\n if (joins?.[join.joinPath] === false) {\n continue\n }\n\n const {\n count = false,\n limit: limitJoin = join.field.defaultLimit ?? 10,\n page,\n sort: sortJoin = join.field.defaultSort || collectionConfig.defaultSort,\n where: whereJoin = {},\n } = joins?.[join.joinPath] || {}\n\n const aggregatedFields: FlattenedField[] = []\n for (const collectionSlug of join.field.collection) {\n const { collectionConfig } = getCollection({ adapter, collectionSlug })\n\n for (const field of collectionConfig.flattenedFields) {\n if (!aggregatedFields.some((eachField) => eachField.name === field.name)) {\n aggregatedFields.push(field)\n }\n }\n }\n\n const sort = buildSortParam({\n adapter,\n config: adapter.payload.config,\n fields: aggregatedFields,\n locale,\n sort: sortJoin,\n timestamps: true,\n })\n\n const $match = await buildQuery({\n adapter,\n branch,\n fields: aggregatedFields,\n locale,\n req,\n where: whereJoin,\n })\n\n const sortProperty = Object.keys(sort)[0]! // assert because buildSortParam always returns at least 1 key.\n const sortDirection = sort[sortProperty] === 'asc' ? 1 : -1\n\n const projectSort = sortProperty !== '_id' && sortProperty !== 'relationTo'\n\n const aliases: string[] = []\n\n const as = join.joinPath\n\n for (const collectionSlug of join.field.collection) {\n const alias = `${as}.docs.${collectionSlug}`\n aliases.push(alias)\n\n const joinBranchPredicate = getBranchPredicateSync({\n branch,\n collectionSlug,\n req,\n })\n const joinBranchReadState = resolveBranchReadState({\n branch,\n collectionSlug,\n req,\n })\n const branchMatch = joinBranchPredicate\n ? await buildQuery({\n adapter,\n branch,\n fields: adapter.payload.collections[collectionSlug]!.config.flattenedFields,\n locale,\n req,\n where: joinBranchPredicate,\n })\n : undefined\n const branchVisibility = joinBranchReadState.useBranching\n ? buildBranchVisibilityStages({\n adapter,\n branch: joinBranchReadState.branch,\n collectionSlug,\n })\n : []\n const basePipeline: Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out>[] = [\n {\n $addFields: {\n relationTo: {\n $literal: collectionSlug,\n },\n },\n },\n {\n $match: {\n $and: [\n {\n $expr: {\n $eq: [`$${join.field.on}`, '$$root_id_'],\n },\n },\n $match,\n ...(branchMatch ? [branchMatch] : []),\n ],\n },\n },\n ...branchVisibility,\n ...(joinBranchPredicate || branchVisibility.length\n ? ([{ $set: { _id: { $ifNull: ['$_branchDocID', '$_id'] } } }] as Exclude<\n PipelineStage,\n PipelineStage.Merge | PipelineStage.Out\n >[])\n : []),\n ]\n\n const { Model: JoinModel } = getCollection({ adapter, collectionSlug })\n\n aggregate.push({\n $lookup: {\n as: alias,\n from: JoinModel.collection.name,\n let: {\n root_id_: rootIDExpression,\n },\n pipeline: [\n ...basePipeline,\n {\n $sort: {\n [sortProperty]: sortDirection,\n },\n },\n ...(limitJoin > 0\n ? [\n {\n // Unfortunately, we can't use $skip here because we can lose data, instead we do $slice then\n $limit: page ? page * limitJoin : limitJoin,\n },\n ]\n : []),\n {\n $project: {\n value: '$_id',\n ...(projectSort && {\n [sortProperty]: 1,\n }),\n relationTo: 1,\n },\n },\n ],\n },\n })\n\n if (count) {\n aggregate.push({\n $lookup: {\n as: `${as}.totalDocs.${alias}`,\n from: JoinModel.collection.name,\n let: {\n root_id_: rootIDExpression,\n },\n pipeline: [\n ...basePipeline,\n {\n $count: 'result',\n },\n ],\n },\n })\n }\n }\n\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $concatArrays: aliases.map((alias) => `$${alias}`),\n },\n },\n })\n\n if (count) {\n aggregate.push({\n $addFields: {\n [`${as}.totalDocs`]: {\n $add: aliases.map((alias) => ({\n $ifNull: [\n {\n $first: `$${as}.totalDocs.${alias}.result`,\n },\n 0,\n ],\n })),\n },\n },\n })\n }\n\n aggregate.push({\n $set: {\n [`${as}.docs`]: {\n $sortArray: {\n input: `$${as}.docs`,\n sortBy: {\n [sortProperty]: sortDirection,\n },\n },\n },\n },\n })\n\n const sliceValue = page ? [(page - 1) * limitJoin, limitJoin] : [limitJoin]\n\n aggregate.push({\n $addFields: {\n [`${as}.hasNextPage`]: {\n $gt: [{ $size: `$${as}.docs` }, limitJoin || Number.MAX_VALUE],\n },\n },\n })\n\n if (limitJoin > 0) {\n aggregate.push({\n $set: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, ...sliceValue],\n },\n },\n })\n }\n }\n\n for (const slug of Object.keys(joinConfig)) {\n const joinsList = joinConfig[slug]\n\n if (!joinsList) {\n throw new APIError(`Failed to retrieve array of joins for ${slug} in collectio ${collection}`)\n }\n\n for (const join of joinsList) {\n const projectionPath = versions ? `version.${join.joinPath}` : join.joinPath\n if (projection && !projection[projectionPath]) {\n continue\n }\n\n if (joins?.[join.joinPath] === false) {\n continue\n }\n\n const collectionConfig = adapter.payload.collections[join.field.collection as string]?.config\n\n if (!collectionConfig) {\n throw new APIError(\n `Collection config for ${join.field.collection.toString()} was not found`,\n )\n }\n\n let JoinModel: CollectionModel | undefined\n\n const useDrafts = (draftsEnabled || versions) && hasDraftsEnabled(collectionConfig)\n\n if (useDrafts) {\n JoinModel = adapter.versions[collectionConfig.slug]\n } else {\n JoinModel = adapter.collections[collectionConfig.slug]\n }\n\n if (!JoinModel) {\n throw new APIError(`Join Model was not found for ${collectionConfig.slug}`)\n }\n\n const {\n count,\n limit: limitJoin = join.field.defaultLimit ?? 10,\n page,\n sort: sortJoin = join.field.defaultSort || collectionConfig.defaultSort,\n where: whereJoin = {},\n } = joins?.[join.joinPath] || {}\n\n if (Array.isArray(join.field.collection)) {\n throw new Error('Unreachable')\n }\n\n const fields = useDrafts\n ? buildVersionCollectionFields(adapter.payload.config, collectionConfig, true)\n : collectionConfig.flattenedFields\n\n const sort = buildSortParam({\n adapter,\n config: adapter.payload.config,\n fields,\n locale,\n sort: useDrafts ? getQueryDraftsSort({ collectionConfig, sort: sortJoin }) : sortJoin,\n timestamps: true,\n })\n const sortProperty = Object.keys(sort)[0]!\n const sortDirection = sort[sortProperty] === 'asc' ? 1 : -1\n\n // A join subquery must carry the same branch predicate as the top-level\n // read, or a branch would see main's related documents.\n const joinBranchPredicate = getBranchPredicateSync({\n branch,\n collectionSlug: collectionConfig.slug,\n req,\n })\n const joinBranchReadState = resolveBranchReadState({\n branch,\n collectionSlug: collectionConfig.slug,\n req,\n })\n\n const resolvedWhereJoin = useDrafts\n ? joinBranchReadState.useBranching\n ? (rewriteBranchVersionParents(appendVersionToQueryKey(whereJoin)) ?? {})\n : ((await resolveBranchVersionQuery({\n branch,\n collectionSlug: collectionConfig.slug,\n req,\n where: appendVersionToQueryKey(whereJoin),\n })) ?? {})\n : joinBranchReadState.useBranching\n ? (rewriteBranchIDs(whereJoin) ?? {})\n : joinBranchPredicate\n ? ({ and: [whereJoin, joinBranchPredicate] } as Where)\n : whereJoin\n\n const $match = await JoinModel.buildQuery({\n branch,\n locale,\n payload: adapter.payload,\n req,\n where: useDrafts\n ? combineQueries(resolvedWhereJoin, {\n latest: {\n equals: true,\n },\n })\n : resolvedWhereJoin,\n })\n const branchVisibility = joinBranchReadState.useBranching\n ? buildBranchVisibilityStages({\n adapter,\n branch: joinBranchReadState.branch,\n collectionSlug: collectionConfig.slug,\n mode: useDrafts ? 'drafts' : 'documents',\n })\n : []\n\n const pipeline: Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out>[] = [\n { $match },\n ...branchVisibility,\n // Surface the canonical document ID rather than the shadow row's own\n // primary key, so join results address documents the same way every\n // other read does.\n ...(joinBranchPredicate || branchVisibility.length\n ? ([\n useDrafts\n ? { $set: { parent: { $ifNull: ['$_branchParent', '$parent'] } } }\n : { $set: { _id: { $ifNull: ['$_branchDocID', '$_id'] } } },\n ] as Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out>[])\n : []),\n {\n $sort: { [sortProperty]: sortDirection },\n },\n ]\n\n if (page) {\n pipeline.push({\n $skip: (page - 1) * limitJoin,\n })\n }\n\n if (limitJoin > 0) {\n pipeline.push({\n $limit: limitJoin + 1,\n })\n }\n\n let polymorphicSuffix = ''\n if (Array.isArray(join.targetField.relationTo)) {\n polymorphicSuffix = '.value'\n }\n\n const addTotalDocsAggregation = (as: string, foreignField: string) =>\n aggregate.push(\n {\n $lookup: {\n as: `${as}.totalDocs`,\n foreignField,\n from: JoinModel.collection.name,\n localField,\n pipeline: [\n {\n $match,\n },\n ...branchVisibility,\n {\n $count: 'result',\n },\n ],\n },\n },\n {\n $addFields: {\n [`${as}.totalDocs`]: { $ifNull: [{ $first: `$${as}.totalDocs.result` }, 0] },\n },\n },\n )\n\n let foreignFieldPrefix = ''\n\n if (useDrafts) {\n foreignFieldPrefix = 'version.'\n }\n\n if (adapter.payload.config.localization && locale === 'all') {\n adapter.payload.config.localization.localeCodes.forEach((code) => {\n const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${code}`\n\n aggregate.push(\n {\n $lookup: {\n as: `${as}.docs`,\n foreignField: `${foreignFieldPrefix}${join.field.on}${code}${polymorphicSuffix}`,\n from: JoinModel.collection.name,\n localField,\n pipeline,\n },\n },\n {\n $addFields: {\n [`${as}.docs`]: {\n $map: {\n as: 'doc',\n in: useDrafts ? `$$doc.parent` : '$$doc._id',\n input: `$${as}.docs`,\n },\n }, // Slicing the docs to match the limit\n [`${as}.hasNextPage`]: limitJoin\n ? { $gt: [{ $size: `$${as}.docs` }, limitJoin] }\n : false,\n // Boolean indicating if more docs than limit\n },\n },\n )\n\n if (limitJoin > 0) {\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, limitJoin],\n },\n },\n })\n }\n\n if (count) {\n addTotalDocsAggregation(\n as,\n `${foreignFieldPrefix}${join.field.on}${code}${polymorphicSuffix}`,\n )\n }\n })\n } else {\n const localeSuffix =\n fieldShouldBeLocalized({\n field: join.field,\n parentIsLocalized: join.parentIsLocalized,\n }) &&\n adapter.payload.config.localization &&\n locale\n ? `.${locale}`\n : ''\n const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${localeSuffix}`\n\n let foreignField: string\n\n if (join.getForeignPath) {\n foreignField = `${join.getForeignPath({ locale })}${polymorphicSuffix}`\n } else {\n foreignField = `${join.field.on}${polymorphicSuffix}`\n }\n\n aggregate.push(\n {\n $lookup: {\n as: `${as}.docs`,\n foreignField: `${foreignFieldPrefix}${foreignField}`,\n from: JoinModel.collection.name,\n localField,\n pipeline,\n },\n },\n {\n $addFields: {\n [`${as}.docs`]: {\n $map: {\n as: 'doc',\n in: useDrafts ? `$$doc.parent` : '$$doc._id',\n input: `$${as}.docs`,\n },\n }, // Slicing the docs to match the limit\n [`${as}.hasNextPage`]: {\n $gt: [{ $size: `$${as}.docs` }, limitJoin || Number.MAX_VALUE],\n }, // Boolean indicating if more docs than limit\n },\n },\n )\n\n if (count) {\n addTotalDocsAggregation(as, `${foreignFieldPrefix}${foreignField}`)\n }\n\n if (limitJoin > 0) {\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, limitJoin],\n },\n },\n })\n }\n }\n }\n }\n\n if (aggregate.length && outerBranchReadState.useBranching) {\n aggregate.unshift({\n $set: {\n [canonicalParentField]: versions\n ? { $ifNull: ['$_branchParent', '$parent'] }\n : { $ifNull: ['$_branchDocID', '$_id'] },\n },\n })\n aggregate.push({ $unset: canonicalParentField })\n }\n\n return aggregate\n}\n"],"names":["APIError","appendVersionToQueryKey","buildVersionCollectionFields","combineQueries","getBranchPredicateSync","getQueryDraftsSort","resolveBranchReadState","resolveBranchVersionQuery","rewriteBranchIDs","rewriteBranchVersionParents","fieldShouldBeLocalized","hasDraftsEnabled","buildBranchVisibilityStages","buildQuery","buildSortParam","getCollection","buildJoinAggregation","adapter","branch","collection","collectionConfig","draftsEnabled","joins","locale","projection","req","versions","useJoinAggregations","Object","keys","length","polymorphicJoins","joinConfig","payload","collections","config","aggregate","outerBranchReadState","collectionSlug","canonicalParentField","localField","useBranching","rootIDExpression","polymorphicJoinsConfig","join","joinPath","count","limit","limitJoin","field","defaultLimit","page","sort","sortJoin","defaultSort","where","whereJoin","aggregatedFields","flattenedFields","some","eachField","name","push","fields","timestamps","$match","sortProperty","sortDirection","projectSort","aliases","as","alias","joinBranchPredicate","joinBranchReadState","branchMatch","undefined","branchVisibility","basePipeline","$addFields","relationTo","$literal","$and","$expr","$eq","on","$set","_id","$ifNull","Model","JoinModel","$lookup","from","let","root_id_","pipeline","$sort","$limit","$project","value","$count","$concatArrays","map","$add","$first","$sortArray","input","sortBy","sliceValue","$gt","$size","Number","MAX_VALUE","$slice","slug","joinsList","projectionPath","toString","useDrafts","Array","isArray","Error","resolvedWhereJoin","and","latest","equals","mode","parent","$skip","polymorphicSuffix","targetField","addTotalDocsAggregation","foreignField","foreignFieldPrefix","localization","localeCodes","forEach","code","$map","in","localeSuffix","parentIsLocalized","getForeignPath","unshift","$unset"],"mappings":"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"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { JoinQuery } from 'payload';
|
|
1
|
+
import type { JoinQuery, PayloadRequest } from 'payload';
|
|
2
2
|
import type { MongooseAdapter } from '../index.js';
|
|
3
3
|
export type ResolveJoinsArgs = {
|
|
4
4
|
/** The MongoDB adapter instance */
|
|
5
5
|
adapter: MongooseAdapter;
|
|
6
|
+
/** Explicit branch override for related document reads */
|
|
7
|
+
branch?: false | string;
|
|
6
8
|
/** The slug of the collection being queried */
|
|
7
9
|
collectionSlug: string;
|
|
8
10
|
/** Array of documents to resolve joins for */
|
|
@@ -13,6 +15,8 @@ export type ResolveJoinsArgs = {
|
|
|
13
15
|
locale?: string;
|
|
14
16
|
/** Optional projection for the join query */
|
|
15
17
|
projection?: Record<string, true>;
|
|
18
|
+
/** Request, for resolving the active branch */
|
|
19
|
+
req?: Partial<PayloadRequest>;
|
|
16
20
|
/** Whether to resolve versions instead of published documents */
|
|
17
21
|
versions?: boolean;
|
|
18
22
|
};
|
|
@@ -21,5 +25,5 @@ export type ResolveJoinsArgs = {
|
|
|
21
25
|
* This function fetches related documents based on join configurations and
|
|
22
26
|
* attaches them to the original documents with pagination support.
|
|
23
27
|
*/
|
|
24
|
-
export declare function resolveJoins({ adapter, collectionSlug, docs, joins, locale, projection, versions, }: ResolveJoinsArgs): Promise<void>;
|
|
28
|
+
export declare function resolveJoins({ adapter, branch, collectionSlug, docs, joins, locale, projection, req, versions, }: ResolveJoinsArgs): Promise<void>;
|
|
25
29
|
//# sourceMappingURL=resolveJoins.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveJoins.d.ts","sourceRoot":"","sources":["../../src/utilities/resolveJoins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAyB,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"resolveJoins.d.ts","sourceRoot":"","sources":["../../src/utilities/resolveJoins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAyB,MAAM,SAAS,CAAA;AAkB/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAOlD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,mCAAmC;IACnC,OAAO,EAAE,eAAe,CAAA;IACxB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IACvB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAA;IACtB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAC/B,iEAAiE;IACjE,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACjC,+CAA+C;IAC/C,GAAG,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAC7B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,EACjC,OAAO,EACP,MAAM,EACN,cAAc,EACd,IAAI,EACJ,KAAK,EACL,MAAM,EACN,UAAU,EACV,GAAG,EACH,QAAgB,GACjB,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+dlC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { appendVersionToQueryKey, buildVersionCollectionFields, combineQueries, getQueryDraftsSort } from 'payload';
|
|
1
|
+
import { appendVersionToQueryKey, applyBranchIDProjection, branchDocIDField, buildVersionCollectionFields, combineQueries, getBranchPredicateSync, getQueryDraftsSort, projectBranchVersionParent, resolveBranchReadState, resolveBranchVersionQuery, rewriteBranchIDs, rewriteBranchVersionParents } from 'payload';
|
|
2
2
|
import { fieldShouldBeLocalized } from 'payload/shared';
|
|
3
|
+
import { buildBranchVisibilityStages } from '../queries/buildBranchVisibility.js';
|
|
3
4
|
import { buildQuery } from '../queries/buildQuery.js';
|
|
4
5
|
import { buildSortParam } from '../queries/buildSortParam.js';
|
|
5
6
|
import { transform } from './transform.js';
|
|
@@ -7,7 +8,7 @@ import { transform } from './transform.js';
|
|
|
7
8
|
* Resolves join relationships for a collection of documents.
|
|
8
9
|
* This function fetches related documents based on join configurations and
|
|
9
10
|
* attaches them to the original documents with pagination support.
|
|
10
|
-
*/ export async function resolveJoins({ adapter, collectionSlug, docs, joins, locale, projection, versions = false }) {
|
|
11
|
+
*/ export async function resolveJoins({ adapter, branch, collectionSlug, docs, joins, locale, projection, req, versions = false }) {
|
|
11
12
|
// Early return if no joins are specified or no documents to process
|
|
12
13
|
if (!joins || docs.length === 0) {
|
|
13
14
|
return;
|
|
@@ -85,7 +86,7 @@ import { transform } from './transform.js';
|
|
|
85
86
|
return null;
|
|
86
87
|
}
|
|
87
88
|
// Extract all parent document IDs to use in the join query
|
|
88
|
-
const parentIDs = docs.map((
|
|
89
|
+
const parentIDs = docs.map((doc)=>versions ? projectBranchVersionParent(doc) : doc[branchDocIDField] ?? doc._id ?? doc.id);
|
|
89
90
|
// Build the base query
|
|
90
91
|
let whereQuery = null;
|
|
91
92
|
whereQuery = isPolymorphicJoin ? filterWhereForCollection(joinQuery.where || {}, targetConfig.flattenedFields, true) : joinQuery.where || {};
|
|
@@ -93,21 +94,57 @@ import { transform } from './transform.js';
|
|
|
93
94
|
if (whereQuery === null) {
|
|
94
95
|
return null;
|
|
95
96
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
latest: {
|
|
101
|
-
equals: true
|
|
102
|
-
}
|
|
103
|
-
})
|
|
104
|
-
}) : await buildQuery({
|
|
105
|
-
adapter,
|
|
97
|
+
// A join subquery must carry the same branch predicate as the top-level
|
|
98
|
+
// read, or a branch would see main's related documents.
|
|
99
|
+
const joinBranchPredicate = getBranchPredicateSync({
|
|
100
|
+
branch,
|
|
106
101
|
collectionSlug: joinCollectionSlug,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
102
|
+
req
|
|
103
|
+
});
|
|
104
|
+
const joinBranchReadState = resolveBranchReadState({
|
|
105
|
+
branch,
|
|
106
|
+
collectionSlug: joinCollectionSlug,
|
|
107
|
+
req
|
|
110
108
|
});
|
|
109
|
+
if (useDrafts) {
|
|
110
|
+
const branchVersionWhere = joinBranchReadState.useBranching ? rewriteBranchVersionParents(appendVersionToQueryKey(whereQuery)) : await resolveBranchVersionQuery({
|
|
111
|
+
branch,
|
|
112
|
+
collectionSlug: joinCollectionSlug,
|
|
113
|
+
req,
|
|
114
|
+
where: appendVersionToQueryKey(whereQuery)
|
|
115
|
+
});
|
|
116
|
+
whereQuery = await JoinModel.buildQuery({
|
|
117
|
+
branch,
|
|
118
|
+
locale,
|
|
119
|
+
payload: adapter.payload,
|
|
120
|
+
req,
|
|
121
|
+
where: combineQueries(branchVersionWhere ?? {}, {
|
|
122
|
+
latest: {
|
|
123
|
+
equals: true
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
});
|
|
127
|
+
} else {
|
|
128
|
+
if (joinBranchReadState.useBranching) {
|
|
129
|
+
whereQuery = rewriteBranchIDs(whereQuery) ?? {};
|
|
130
|
+
} else if (joinBranchPredicate) {
|
|
131
|
+
whereQuery = {
|
|
132
|
+
and: [
|
|
133
|
+
whereQuery,
|
|
134
|
+
joinBranchPredicate
|
|
135
|
+
]
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
whereQuery = await buildQuery({
|
|
139
|
+
adapter,
|
|
140
|
+
branch,
|
|
141
|
+
collectionSlug: joinCollectionSlug,
|
|
142
|
+
fields: targetConfig.flattenedFields,
|
|
143
|
+
locale,
|
|
144
|
+
req,
|
|
145
|
+
where: whereQuery
|
|
146
|
+
});
|
|
147
|
+
}
|
|
111
148
|
// Handle localized paths and version prefixes
|
|
112
149
|
let dbFieldName = joinDef.field.on;
|
|
113
150
|
if (effectiveLocale && typeof localizationConfig === 'object' && localizationConfig) {
|
|
@@ -156,8 +193,49 @@ import { transform } from './transform.js';
|
|
|
156
193
|
}) : joinQuery.sort || joinDef.field.defaultSort || targetConfig.defaultSort,
|
|
157
194
|
timestamps: true
|
|
158
195
|
});
|
|
159
|
-
const projection = buildJoinProjection(dbFieldName, useDrafts, sort);
|
|
160
|
-
const
|
|
196
|
+
const projection = buildJoinProjection(dbFieldName, useDrafts, sort, Boolean(joinBranchPredicate) || joinBranchReadState.useBranching);
|
|
197
|
+
const branchVisibility = joinBranchReadState.useBranching ? buildBranchVisibilityStages({
|
|
198
|
+
adapter,
|
|
199
|
+
branch: joinBranchReadState.branch,
|
|
200
|
+
collectionSlug: joinCollectionSlug,
|
|
201
|
+
mode: useDrafts ? 'drafts' : 'documents'
|
|
202
|
+
}) : [];
|
|
203
|
+
const [results, dbCount] = branchVisibility.length ? await Promise.all([
|
|
204
|
+
JoinModel.aggregate([
|
|
205
|
+
{
|
|
206
|
+
$match: whereQuery
|
|
207
|
+
},
|
|
208
|
+
...branchVisibility,
|
|
209
|
+
{
|
|
210
|
+
$sort: Object.fromEntries(Object.entries(sort).map(([key, value])=>[
|
|
211
|
+
key,
|
|
212
|
+
value === 'asc' ? 1 : -1
|
|
213
|
+
]))
|
|
214
|
+
},
|
|
215
|
+
...isPolymorphicJoin ? [] : [
|
|
216
|
+
{
|
|
217
|
+
$skip: skip
|
|
218
|
+
},
|
|
219
|
+
...limit > 0 ? [
|
|
220
|
+
{
|
|
221
|
+
$limit: limit
|
|
222
|
+
}
|
|
223
|
+
] : []
|
|
224
|
+
],
|
|
225
|
+
{
|
|
226
|
+
$project: projection
|
|
227
|
+
}
|
|
228
|
+
]),
|
|
229
|
+
isPolymorphicJoin ? Promise.resolve(0) : JoinModel.aggregate([
|
|
230
|
+
{
|
|
231
|
+
$match: whereQuery
|
|
232
|
+
},
|
|
233
|
+
...branchVisibility,
|
|
234
|
+
{
|
|
235
|
+
$count: 'count'
|
|
236
|
+
}
|
|
237
|
+
]).then((rows)=>rows[0]?.count ?? 0)
|
|
238
|
+
]) : await Promise.all([
|
|
161
239
|
JoinModel.find(whereQuery, projection, {
|
|
162
240
|
sort,
|
|
163
241
|
...isPolymorphicJoin ? {} : {
|
|
@@ -174,14 +252,25 @@ import { transform } from './transform.js';
|
|
|
174
252
|
fields: useDrafts ? buildVersionCollectionFields(adapter.payload.config, targetConfig, false) : targetConfig.fields,
|
|
175
253
|
operation: 'read'
|
|
176
254
|
});
|
|
255
|
+
if (useDrafts) {
|
|
256
|
+
for (const result of results){
|
|
257
|
+
result.id = projectBranchVersionParent(result);
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
applyBranchIDProjection({
|
|
261
|
+
branch,
|
|
262
|
+
collectionSlug: joinCollectionSlug,
|
|
263
|
+
docs: results,
|
|
264
|
+
req
|
|
265
|
+
});
|
|
266
|
+
}
|
|
177
267
|
// Return results with collection info for grouping
|
|
178
268
|
return {
|
|
179
269
|
collectionSlug: joinCollectionSlug,
|
|
180
270
|
count,
|
|
181
271
|
dbFieldName,
|
|
182
272
|
results,
|
|
183
|
-
sort
|
|
184
|
-
useDrafts
|
|
273
|
+
sort
|
|
185
274
|
};
|
|
186
275
|
});
|
|
187
276
|
const collectionResults = await Promise.all(collectionPromises);
|
|
@@ -192,12 +281,9 @@ import { transform } from './transform.js';
|
|
|
192
281
|
if (!collectionResult) {
|
|
193
282
|
continue;
|
|
194
283
|
}
|
|
195
|
-
const { collectionSlug, count, dbFieldName, results, sort
|
|
284
|
+
const { collectionSlug, count, dbFieldName, results, sort } = collectionResult;
|
|
196
285
|
totalCount += count;
|
|
197
286
|
for (const result of results){
|
|
198
|
-
if (useDrafts) {
|
|
199
|
-
result.id = result.parent;
|
|
200
|
-
}
|
|
201
287
|
const parentValues = getByPathWithArrays(result, dbFieldName);
|
|
202
288
|
if (parentValues.length === 0) {
|
|
203
289
|
continue;
|
|
@@ -273,7 +359,7 @@ import { transform } from './transform.js';
|
|
|
273
359
|
const { grouped, isPolymorphicJoin, joinQuery, limit, localizedJoinPath, skip, totalCount } = joinResult;
|
|
274
360
|
// Attach the joined data to each parent document
|
|
275
361
|
for (const doc of docs){
|
|
276
|
-
const id = versions ? doc
|
|
362
|
+
const id = versions ? projectBranchVersionParent(doc) : doc[branchDocIDField] ?? doc._id ?? doc.id;
|
|
277
363
|
const all = grouped[id]?.docs || [];
|
|
278
364
|
// Calculate the slice for pagination
|
|
279
365
|
// When limit is 0, it means unlimited - return all results
|
|
@@ -437,7 +523,7 @@ import { transform } from './transform.js';
|
|
|
437
523
|
}
|
|
438
524
|
/**
|
|
439
525
|
* Builds projection for join queries
|
|
440
|
-
*/ function buildJoinProjection(baseFieldName, useDrafts, sort) {
|
|
526
|
+
*/ function buildJoinProjection(baseFieldName, useDrafts, sort, shouldProjectBranchID) {
|
|
441
527
|
const projection = {
|
|
442
528
|
_id: 1,
|
|
443
529
|
[baseFieldName]: 1
|
|
@@ -445,6 +531,9 @@ import { transform } from './transform.js';
|
|
|
445
531
|
if (useDrafts) {
|
|
446
532
|
projection.parent = 1;
|
|
447
533
|
}
|
|
534
|
+
if (shouldProjectBranchID) {
|
|
535
|
+
projection[useDrafts ? '_branchParent' : '_branchDocID'] = 1;
|
|
536
|
+
}
|
|
448
537
|
for (const fieldName of Object.keys(sort)){
|
|
449
538
|
projection[fieldName] = 1;
|
|
450
539
|
}
|