@payloadcms/db-mongodb 4.0.0-internal.e7d4ebc → 4.0.0-internal.ea6e8f8

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.
Files changed (181) hide show
  1. package/dist/connect.d.ts.map +1 -1
  2. package/dist/connect.js +9 -2
  3. package/dist/connect.js.map +1 -1
  4. package/dist/count.d.ts.map +1 -1
  5. package/dist/count.js +33 -4
  6. package/dist/count.js.map +1 -1
  7. package/dist/countGlobalVersions.d.ts.map +1 -1
  8. package/dist/countGlobalVersions.js +1 -0
  9. package/dist/countGlobalVersions.js.map +1 -1
  10. package/dist/countVersions.d.ts.map +1 -1
  11. package/dist/countVersions.js +36 -4
  12. package/dist/countVersions.js.map +1 -1
  13. package/dist/create.d.ts.map +1 -1
  14. package/dist/create.js +2 -1
  15. package/dist/create.js.map +1 -1
  16. package/dist/createGlobalVersion.d.ts.map +1 -1
  17. package/dist/createGlobalVersion.js +23 -1
  18. package/dist/createGlobalVersion.js.map +1 -1
  19. package/dist/createMigration.d.ts.map +1 -1
  20. package/dist/createMigration.js +9 -2
  21. package/dist/createMigration.js.map +1 -1
  22. package/dist/createVersion.d.ts.map +1 -1
  23. package/dist/createVersion.js +17 -4
  24. package/dist/createVersion.js.map +1 -1
  25. package/dist/deleteBranchGlobal.d.ts +10 -0
  26. package/dist/deleteBranchGlobal.d.ts.map +1 -0
  27. package/dist/deleteBranchGlobal.js +22 -0
  28. package/dist/deleteBranchGlobal.js.map +1 -0
  29. package/dist/deleteMany.d.ts.map +1 -1
  30. package/dist/deleteMany.js +1 -0
  31. package/dist/deleteMany.js.map +1 -1
  32. package/dist/deleteOne.d.ts.map +1 -1
  33. package/dist/deleteOne.js +20 -1
  34. package/dist/deleteOne.js.map +1 -1
  35. package/dist/deleteVersions.d.ts.map +1 -1
  36. package/dist/deleteVersions.js +1 -0
  37. package/dist/deleteVersions.js.map +1 -1
  38. package/dist/exports/migration-utils.d.ts +2 -0
  39. package/dist/exports/migration-utils.d.ts.map +1 -1
  40. package/dist/exports/migration-utils.js +2 -0
  41. package/dist/exports/migration-utils.js.map +1 -1
  42. package/dist/find.d.ts.map +1 -1
  43. package/dist/find.js +44 -8
  44. package/dist/find.js.map +1 -1
  45. package/dist/findDistinct.d.ts.map +1 -1
  46. package/dist/findDistinct.js +115 -12
  47. package/dist/findDistinct.js.map +1 -1
  48. package/dist/findGlobal.d.ts.map +1 -1
  49. package/dist/findGlobal.js +34 -5
  50. package/dist/findGlobal.js.map +1 -1
  51. package/dist/findGlobalVersions.d.ts.map +1 -1
  52. package/dist/findGlobalVersions.js +10 -2
  53. package/dist/findGlobalVersions.js.map +1 -1
  54. package/dist/findOne.d.ts.map +1 -1
  55. package/dist/findOne.js +43 -5
  56. package/dist/findOne.js.map +1 -1
  57. package/dist/findVersions.d.ts.map +1 -1
  58. package/dist/findVersions.js +49 -5
  59. package/dist/findVersions.js.map +1 -1
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +4 -0
  62. package/dist/index.js.map +1 -1
  63. package/dist/init.d.ts.map +1 -1
  64. package/dist/init.js +89 -67
  65. package/dist/init.js.map +1 -1
  66. package/dist/migrateFresh.d.ts +4 -2
  67. package/dist/migrateFresh.d.ts.map +1 -1
  68. package/dist/migrateFresh.js +21 -6
  69. package/dist/migrateFresh.js.map +1 -1
  70. package/dist/models/buildCollectionSchema.d.ts +8 -2
  71. package/dist/models/buildCollectionSchema.d.ts.map +1 -1
  72. package/dist/models/buildCollectionSchema.js +4 -2
  73. package/dist/models/buildCollectionSchema.js.map +1 -1
  74. package/dist/models/buildGlobalModel.d.ts +5 -1
  75. package/dist/models/buildGlobalModel.d.ts.map +1 -1
  76. package/dist/models/buildGlobalModel.js +34 -3
  77. package/dist/models/buildGlobalModel.js.map +1 -1
  78. package/dist/models/buildSchema.d.ts +4 -0
  79. package/dist/models/buildSchema.d.ts.map +1 -1
  80. package/dist/models/buildSchema.js +94 -36
  81. package/dist/models/buildSchema.js.map +1 -1
  82. package/dist/models/schemaBuildContext.d.ts +21 -0
  83. package/dist/models/schemaBuildContext.d.ts.map +1 -0
  84. package/dist/models/schemaBuildContext.js +29 -0
  85. package/dist/models/schemaBuildContext.js.map +1 -0
  86. package/dist/predefinedMigrations/branching.d.ts +4 -0
  87. package/dist/predefinedMigrations/branching.d.ts.map +1 -0
  88. package/dist/predefinedMigrations/branching.js +9 -0
  89. package/dist/predefinedMigrations/branching.js.map +1 -0
  90. package/dist/predefinedMigrations/migrateBranching.d.ts +15 -0
  91. package/dist/predefinedMigrations/migrateBranching.d.ts.map +1 -0
  92. package/dist/predefinedMigrations/migrateBranching.js +88 -0
  93. package/dist/predefinedMigrations/migrateBranching.js.map +1 -0
  94. package/dist/predefinedMigrations/migrateRelationshipsV2_V3.d.ts.map +1 -1
  95. package/dist/predefinedMigrations/migrateRelationshipsV2_V3.js +4 -4
  96. package/dist/predefinedMigrations/migrateRelationshipsV2_V3.js.map +1 -1
  97. package/dist/predefinedMigrations/migrateSizesToVariants.d.ts +13 -0
  98. package/dist/predefinedMigrations/migrateSizesToVariants.d.ts.map +1 -0
  99. package/dist/predefinedMigrations/migrateSizesToVariants.js +368 -0
  100. package/dist/predefinedMigrations/migrateSizesToVariants.js.map +1 -0
  101. package/dist/predefinedMigrations/sizes-to-variants.d.ts +5 -0
  102. package/dist/predefinedMigrations/sizes-to-variants.d.ts.map +1 -0
  103. package/dist/predefinedMigrations/sizes-to-variants.js +8 -0
  104. package/dist/predefinedMigrations/sizes-to-variants.js.map +1 -0
  105. package/dist/queries/buildAndOrConditions.d.ts +4 -2
  106. package/dist/queries/buildAndOrConditions.d.ts.map +1 -1
  107. package/dist/queries/buildAndOrConditions.js +3 -1
  108. package/dist/queries/buildAndOrConditions.js.map +1 -1
  109. package/dist/queries/buildBranchVisibility.d.ts +11 -0
  110. package/dist/queries/buildBranchVisibility.d.ts.map +1 -0
  111. package/dist/queries/buildBranchVisibility.js +204 -0
  112. package/dist/queries/buildBranchVisibility.js.map +1 -0
  113. package/dist/queries/buildQuery.d.ts +4 -2
  114. package/dist/queries/buildQuery.d.ts.map +1 -1
  115. package/dist/queries/buildQuery.js +3 -1
  116. package/dist/queries/buildQuery.js.map +1 -1
  117. package/dist/queries/buildSearchParams.d.ts +4 -2
  118. package/dist/queries/buildSearchParams.d.ts.map +1 -1
  119. package/dist/queries/buildSearchParams.js +338 -24
  120. package/dist/queries/buildSearchParams.js.map +1 -1
  121. package/dist/queries/getBuildQueryPlugin.d.ts +3 -1
  122. package/dist/queries/getBuildQueryPlugin.d.ts.map +1 -1
  123. package/dist/queries/getBuildQueryPlugin.js +3 -1
  124. package/dist/queries/getBuildQueryPlugin.js.map +1 -1
  125. package/dist/queries/parseParams.d.ts +4 -2
  126. package/dist/queries/parseParams.d.ts.map +1 -1
  127. package/dist/queries/parseParams.js +5 -1
  128. package/dist/queries/parseParams.js.map +1 -1
  129. package/dist/queryDrafts.d.ts.map +1 -1
  130. package/dist/queryDrafts.js +38 -7
  131. package/dist/queryDrafts.js.map +1 -1
  132. package/dist/transactions/commitTransaction.d.ts.map +1 -1
  133. package/dist/transactions/commitTransaction.js +55 -7
  134. package/dist/transactions/commitTransaction.js.map +1 -1
  135. package/dist/transactions/rollbackTransaction.d.ts.map +1 -1
  136. package/dist/transactions/rollbackTransaction.js +10 -9
  137. package/dist/transactions/rollbackTransaction.js.map +1 -1
  138. package/dist/updateGlobal.d.ts.map +1 -1
  139. package/dist/updateGlobal.js +89 -9
  140. package/dist/updateGlobal.js.map +1 -1
  141. package/dist/updateGlobalVersion.d.ts.map +1 -1
  142. package/dist/updateGlobalVersion.js +3 -2
  143. package/dist/updateGlobalVersion.js.map +1 -1
  144. package/dist/updateJobs.d.ts.map +1 -1
  145. package/dist/updateJobs.js +71 -14
  146. package/dist/updateJobs.js.map +1 -1
  147. package/dist/updateMany.d.ts.map +1 -1
  148. package/dist/updateMany.js +3 -2
  149. package/dist/updateMany.js.map +1 -1
  150. package/dist/updateOne.d.ts.map +1 -1
  151. package/dist/updateOne.js +30 -4
  152. package/dist/updateOne.js.map +1 -1
  153. package/dist/updateVersion.d.ts.map +1 -1
  154. package/dist/updateVersion.js +3 -2
  155. package/dist/updateVersion.js.map +1 -1
  156. package/dist/upsertBranchGlobalChange.d.ts +3 -0
  157. package/dist/upsertBranchGlobalChange.d.ts.map +1 -0
  158. package/dist/upsertBranchGlobalChange.js +28 -0
  159. package/dist/upsertBranchGlobalChange.js.map +1 -0
  160. package/dist/utilities/aggregatePaginate.d.ts +2 -1
  161. package/dist/utilities/aggregatePaginate.d.ts.map +1 -1
  162. package/dist/utilities/aggregatePaginate.js +21 -5
  163. package/dist/utilities/aggregatePaginate.js.map +1 -1
  164. package/dist/utilities/buildJoinAggregation.d.ts +4 -2
  165. package/dist/utilities/buildJoinAggregation.d.ts.map +1 -1
  166. package/dist/utilities/buildJoinAggregation.js +107 -8
  167. package/dist/utilities/buildJoinAggregation.js.map +1 -1
  168. package/dist/utilities/resolveJoins.d.ts +6 -2
  169. package/dist/utilities/resolveJoins.d.ts.map +1 -1
  170. package/dist/utilities/resolveJoins.js +114 -26
  171. package/dist/utilities/resolveJoins.js.map +1 -1
  172. package/dist/utilities/transform.d.ts.map +1 -1
  173. package/dist/utilities/transform.js +15 -0
  174. package/dist/utilities/transform.js.map +1 -1
  175. package/package.json +5 -5
  176. package/dist/queries/buildSortParam.spec.js +0 -123
  177. package/dist/queries/buildSortParam.spec.js.map +0 -1
  178. package/dist/queries/getLocalizedSortProperty.spec.js +0 -215
  179. package/dist/queries/getLocalizedSortProperty.spec.js.map +0 -1
  180. package/dist/utilities/transform.spec.js +0 -479
  181. package/dist/utilities/transform.spec.js.map +0 -1
@@ -1,8 +1,9 @@
1
1
  import type { PipelineStage } from 'mongoose';
2
- import { type CollectionSlug, type JoinQuery, type SanitizedCollectionConfig } from 'payload';
2
+ import { type CollectionSlug, type JoinQuery, type PayloadRequest, type SanitizedCollectionConfig } from 'payload';
3
3
  import type { MongooseAdapter } from '../index.js';
4
4
  type BuildJoinAggregationArgs = {
5
5
  adapter: MongooseAdapter;
6
+ branch?: false | string;
6
7
  collection: CollectionSlug;
7
8
  collectionConfig: SanitizedCollectionConfig;
8
9
  draftsEnabled?: boolean;
@@ -10,9 +11,10 @@ type BuildJoinAggregationArgs = {
10
11
  locale?: string;
11
12
  projection?: Record<string, true>;
12
13
  query?: Record<string, unknown>;
14
+ req?: Partial<PayloadRequest>;
13
15
  /** whether the query is from drafts */
14
16
  versions?: boolean;
15
17
  };
16
- export declare const buildJoinAggregation: ({ adapter, collection, collectionConfig, draftsEnabled, joins, locale, projection, versions, }: BuildJoinAggregationArgs) => Promise<PipelineStage[] | undefined>;
18
+ export declare const buildJoinAggregation: ({ adapter, branch, collection, collectionConfig, draftsEnabled, joins, locale, projection, req, versions, }: BuildJoinAggregationArgs) => Promise<PipelineStage[]>;
17
19
  export {};
18
20
  //# sourceMappingURL=buildJoinAggregation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"buildJoinAggregation.d.ts","sourceRoot":"","sources":["../../src/utilities/buildJoinAggregation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE7C,OAAO,EAIL,KAAK,cAAc,EAInB,KAAK,SAAS,EACd,KAAK,yBAAyB,EAC/B,MAAM,SAAS,CAAA;AAGhB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAOlD,KAAK,wBAAwB,GAAG;IAC9B,OAAO,EAAE,eAAe,CAAA;IACxB,UAAU,EAAE,cAAc,CAAA;IAC1B,gBAAgB,EAAE,yBAAyB,CAAA;IAC3C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAEjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,eAAO,MAAM,oBAAoB,mGAS9B,wBAAwB,KAAG,OAAO,CAAC,aAAa,EAAE,GAAG,SAAS,CA0chE,CAAA"}
1
+ {"version":3,"file":"buildJoinAggregation.d.ts","sourceRoot":"","sources":["../../src/utilities/buildJoinAggregation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE7C,OAAO,EAIL,KAAK,cAAc,EAKnB,KAAK,SAAS,EACd,KAAK,cAAc,EAKnB,KAAK,yBAAyB,EAE/B,MAAM,SAAS,CAAA;AAGhB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAQlD,KAAK,wBAAwB,GAAG;IAC9B,OAAO,EAAE,eAAe,CAAA;IACxB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IACvB,UAAU,EAAE,cAAc,CAAA;IAC1B,gBAAgB,EAAE,yBAAyB,CAAA;IAC3C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAEjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,GAAG,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAC7B,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,eAAO,MAAM,oBAAoB,gHAW9B,wBAAwB,KAAG,OAAO,CAAC,aAAa,EAAE,CAiiBpD,CAAA"}
@@ -1,14 +1,15 @@
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
- return;
9
+ return [];
9
10
  }
10
11
  if (Object.keys(collectionConfig.joins).length === 0 && collectionConfig.polymorphicJoins.length == 0 || joins === false) {
11
- return;
12
+ return [];
12
13
  }
13
14
  const joinConfig = adapter.payload.collections[collection]?.config?.joins;
14
15
  if (!joinConfig) {
@@ -49,8 +50,10 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
49
50
  });
50
51
  const $match = await buildQuery({
51
52
  adapter,
53
+ branch,
52
54
  fields: aggregatedFields,
53
55
  locale,
56
+ req,
54
57
  where: whereJoin
55
58
  });
56
59
  const sortProperty = Object.keys(sort)[0]// assert because buildSortParam always returns at least 1 key.
@@ -62,6 +65,29 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
62
65
  for (const collectionSlug of join.field.collection){
63
66
  const alias = `${as}.docs.${collectionSlug}`;
64
67
  aliases.push(alias);
68
+ const joinBranchPredicate = getBranchPredicateSync({
69
+ branch,
70
+ collectionSlug,
71
+ req
72
+ });
73
+ const joinBranchReadState = resolveBranchReadState({
74
+ branch,
75
+ collectionSlug,
76
+ req
77
+ });
78
+ const branchMatch = joinBranchPredicate ? await buildQuery({
79
+ adapter,
80
+ branch,
81
+ fields: adapter.payload.collections[collectionSlug].config.flattenedFields,
82
+ locale,
83
+ req,
84
+ where: joinBranchPredicate
85
+ }) : undefined;
86
+ const branchVisibility = joinBranchReadState.useBranching ? buildBranchVisibilityStages({
87
+ adapter,
88
+ branch: joinBranchReadState.branch,
89
+ collectionSlug
90
+ }) : [];
65
91
  const basePipeline = [
66
92
  {
67
93
  $addFields: {
@@ -81,10 +107,26 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
81
107
  ]
82
108
  }
83
109
  },
84
- $match
110
+ $match,
111
+ ...branchMatch ? [
112
+ branchMatch
113
+ ] : []
85
114
  ]
86
115
  }
87
- }
116
+ },
117
+ ...branchVisibility,
118
+ ...joinBranchPredicate || branchVisibility.length ? [
119
+ {
120
+ $set: {
121
+ _id: {
122
+ $ifNull: [
123
+ '$_branchDocID',
124
+ '$_id'
125
+ ]
126
+ }
127
+ }
128
+ }
129
+ ] : []
88
130
  ];
89
131
  const { Model: JoinModel } = getCollection({
90
132
  adapter,
@@ -247,19 +289,75 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
247
289
  });
248
290
  const sortProperty = Object.keys(sort)[0];
249
291
  const sortDirection = sort[sortProperty] === 'asc' ? 1 : -1;
292
+ // A join subquery must carry the same branch predicate as the top-level
293
+ // read, or a branch would see main's related documents.
294
+ const joinBranchPredicate = getBranchPredicateSync({
295
+ branch,
296
+ collectionSlug: collectionConfig.slug,
297
+ req
298
+ });
299
+ const joinBranchReadState = resolveBranchReadState({
300
+ branch,
301
+ collectionSlug: collectionConfig.slug,
302
+ req
303
+ });
304
+ const resolvedWhereJoin = useDrafts ? joinBranchReadState.useBranching ? rewriteBranchVersionParents(appendVersionToQueryKey(whereJoin)) ?? {} : await resolveBranchVersionQuery({
305
+ branch,
306
+ collectionSlug: collectionConfig.slug,
307
+ req,
308
+ where: appendVersionToQueryKey(whereJoin)
309
+ }) ?? {} : joinBranchReadState.useBranching ? rewriteBranchIDs(whereJoin) ?? {} : joinBranchPredicate ? {
310
+ and: [
311
+ whereJoin,
312
+ joinBranchPredicate
313
+ ]
314
+ } : whereJoin;
250
315
  const $match = await JoinModel.buildQuery({
316
+ branch,
251
317
  locale,
252
318
  payload: adapter.payload,
253
- where: useDrafts ? combineQueries(appendVersionToQueryKey(whereJoin), {
319
+ req,
320
+ where: useDrafts ? combineQueries(resolvedWhereJoin, {
254
321
  latest: {
255
322
  equals: true
256
323
  }
257
- }) : whereJoin
324
+ }) : resolvedWhereJoin
258
325
  });
326
+ const branchVisibility = joinBranchReadState.useBranching ? buildBranchVisibilityStages({
327
+ adapter,
328
+ branch: joinBranchReadState.branch,
329
+ collectionSlug: collectionConfig.slug,
330
+ mode: useDrafts ? 'drafts' : 'documents'
331
+ }) : [];
259
332
  const pipeline = [
260
333
  {
261
334
  $match
262
335
  },
336
+ ...branchVisibility,
337
+ // Surface the canonical document ID rather than the shadow row's own
338
+ // primary key, so join results address documents the same way every
339
+ // other read does.
340
+ ...joinBranchPredicate || branchVisibility.length ? [
341
+ useDrafts ? {
342
+ $set: {
343
+ parent: {
344
+ $ifNull: [
345
+ '$_branchParent',
346
+ '$parent'
347
+ ]
348
+ }
349
+ }
350
+ } : {
351
+ $set: {
352
+ _id: {
353
+ $ifNull: [
354
+ '$_branchDocID',
355
+ '$_id'
356
+ ]
357
+ }
358
+ }
359
+ }
360
+ ] : [],
263
361
  {
264
362
  $sort: {
265
363
  [sortProperty]: sortDirection
@@ -290,6 +388,7 @@ export const buildJoinAggregation = async ({ adapter, collection, collectionConf
290
388
  {
291
389
  $match
292
390
  },
391
+ ...branchVisibility,
293
392
  {
294
393
  $count: 'result'
295
394
  }
@@ -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[] | undefined> => {\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 {\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 $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 aggregate.push({\n $set: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, ...sliceValue],\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 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_: '$_id',\n },\n pipeline: [\n ...basePipeline,\n {\n $sort: {\n [sortProperty]: sortDirection,\n },\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 $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 aggregate.push({\n $set: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, ...sliceValue],\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: versions ? 'parent' : '_id',\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: 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","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","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","joinBranchPredicate","joinBranchReadState","branchMatch","undefined","branchVisibility","useBranching","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","localField","foreignFieldPrefix","localization","localeCodes","forEach","code","$map","in","localeSuffix","parentIsLocalized","getForeignPath"],"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;AAU/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAMlD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,mCAAmC;IACnC,OAAO,EAAE,eAAe,CAAA;IACxB,+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,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,EACjC,OAAO,EACP,cAAc,EACd,IAAI,EACJ,KAAK,EACL,MAAM,EACN,UAAU,EACV,QAAgB,GACjB,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6YlC"}
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;AAiB/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,CA4dlC"}
@@ -1,5 +1,6 @@
1
- import { appendVersionToQueryKey, buildVersionCollectionFields, combineQueries, getQueryDraftsSort } from 'payload';
1
+ import { appendVersionToQueryKey, applyBranchIDProjection, 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((d)=>versions ? d.parent ?? d._id ?? d.id : d._id ?? d.id);
89
+ const parentIDs = docs.map((doc)=>versions ? projectBranchVersionParent(doc) : 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
- whereQuery = useDrafts ? await JoinModel.buildQuery({
97
- locale,
98
- payload: adapter.payload,
99
- where: combineQueries(appendVersionToQueryKey(whereQuery), {
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
- fields: targetConfig.flattenedFields,
108
- locale,
109
- where: whereQuery
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 [results, dbCount] = await Promise.all([
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,24 @@ 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
+ collectionSlug: joinCollectionSlug,
262
+ docs: results,
263
+ req
264
+ });
265
+ }
177
266
  // Return results with collection info for grouping
178
267
  return {
179
268
  collectionSlug: joinCollectionSlug,
180
269
  count,
181
270
  dbFieldName,
182
271
  results,
183
- sort,
184
- useDrafts
272
+ sort
185
273
  };
186
274
  });
187
275
  const collectionResults = await Promise.all(collectionPromises);
@@ -192,12 +280,9 @@ import { transform } from './transform.js';
192
280
  if (!collectionResult) {
193
281
  continue;
194
282
  }
195
- const { collectionSlug, count, dbFieldName, results, sort, useDrafts } = collectionResult;
283
+ const { collectionSlug, count, dbFieldName, results, sort } = collectionResult;
196
284
  totalCount += count;
197
285
  for (const result of results){
198
- if (useDrafts) {
199
- result.id = result.parent;
200
- }
201
286
  const parentValues = getByPathWithArrays(result, dbFieldName);
202
287
  if (parentValues.length === 0) {
203
288
  continue;
@@ -273,7 +358,7 @@ import { transform } from './transform.js';
273
358
  const { grouped, isPolymorphicJoin, joinQuery, limit, localizedJoinPath, skip, totalCount } = joinResult;
274
359
  // Attach the joined data to each parent document
275
360
  for (const doc of docs){
276
- const id = versions ? doc.parent ?? doc._id ?? doc.id : doc._id ?? doc.id;
361
+ const id = versions ? projectBranchVersionParent(doc) : doc._id ?? doc.id;
277
362
  const all = grouped[id]?.docs || [];
278
363
  // Calculate the slice for pagination
279
364
  // When limit is 0, it means unlimited - return all results
@@ -437,7 +522,7 @@ import { transform } from './transform.js';
437
522
  }
438
523
  /**
439
524
  * Builds projection for join queries
440
- */ function buildJoinProjection(baseFieldName, useDrafts, sort) {
525
+ */ function buildJoinProjection(baseFieldName, useDrafts, sort, shouldProjectBranchID) {
441
526
  const projection = {
442
527
  _id: 1,
443
528
  [baseFieldName]: 1
@@ -445,6 +530,9 @@ import { transform } from './transform.js';
445
530
  if (useDrafts) {
446
531
  projection.parent = 1;
447
532
  }
533
+ if (shouldProjectBranchID) {
534
+ projection[useDrafts ? '_branchParent' : '_branchDocID'] = 1;
535
+ }
448
536
  for (const fieldName of Object.keys(sort)){
449
537
  projection[fieldName] = 1;
450
538
  }