@payloadcms/db-mongodb 4.0.0-internal.e55ccef → 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 +6 -6
  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,16 +1,74 @@
1
1
  import { Types } from 'mongoose';
2
- import { APIError, escapeRegExp, getFieldByPath, getLocalizedPaths } from 'payload';
3
- import { validOperatorSet } from 'payload/shared';
2
+ import { APIError, escapeRegExp, getFieldByPath, getLocalizedPaths, resolveBranchQuery, resolveBranchReadState, rewriteBranchIDs } from 'payload';
3
+ import { hasManyRelationshipOperatorSet, isNestedRelationshipQuery, validOperatorSet } from 'payload/shared';
4
4
  import { getCollection } from '../utilities/getEntity.js';
5
5
  import { isObjectID } from '../utilities/isObjectID.js';
6
+ import { buildBranchVisibilityStages } from './buildBranchVisibility.js';
6
7
  import { operatorMap } from './operatorMap.js';
7
8
  import { sanitizeQueryValue } from './sanitizeQueryValue.js';
8
- const subQueryOptions = {
9
- lean: true
9
+ const resolveRelatedBranchQuery = async ({ branch, collectionSlug, payload, req, where })=>{
10
+ const adapter = payload.db;
11
+ const branchReadState = resolveBranchReadState({
12
+ branch,
13
+ collectionSlug,
14
+ req
15
+ });
16
+ const resolvedWhere = branchReadState.useBranching ? rewriteBranchIDs(where) : await resolveBranchQuery({
17
+ branch,
18
+ collectionSlug,
19
+ req,
20
+ where
21
+ });
22
+ return {
23
+ branchVisibility: branchReadState.useBranching ? buildBranchVisibilityStages({
24
+ adapter,
25
+ branch: branchReadState.branch,
26
+ collectionSlug
27
+ }) : [],
28
+ where: resolvedWhere ?? {}
29
+ };
30
+ };
31
+ const findRelatedDocuments = async ({ branchVisibility, Model, projection, query })=>{
32
+ if (branchVisibility.length) {
33
+ return Model.aggregate([
34
+ {
35
+ $match: query
36
+ },
37
+ ...branchVisibility,
38
+ {
39
+ $project: projection
40
+ }
41
+ ]);
42
+ }
43
+ return Model.find(query).lean().select(projection);
44
+ };
45
+ const findRelatedDistinctValues = async ({ branchVisibility, Model, path, query })=>{
46
+ if (!branchVisibility.length) {
47
+ return Model.distinct(path, query);
48
+ }
49
+ return Model.aggregate([
50
+ {
51
+ $match: query
52
+ },
53
+ ...branchVisibility,
54
+ {
55
+ $project: {
56
+ value: `$${path}`
57
+ }
58
+ },
59
+ {
60
+ $unwind: '$value'
61
+ },
62
+ {
63
+ $group: {
64
+ _id: '$value'
65
+ }
66
+ }
67
+ ]).then((results)=>results.map(({ _id })=>_id));
10
68
  };
11
69
  /**
12
70
  * Convert the Payload key / value / operator into a MongoDB query
13
- */ export async function buildSearchParam({ collectionSlug, fields, globalSlug, incomingPath, locale, operator, parentIsLocalized, payload, val }) {
71
+ */ export async function buildSearchParam({ branch, collectionSlug, fields, globalSlug, incomingPath, locale, operator, parentIsLocalized, payload, req, val }) {
14
72
  // Replace GraphQL nested field double underscore formatting
15
73
  let sanitizedPath = incomingPath.replace(/__/g, '.');
16
74
  if (sanitizedPath === 'id') {
@@ -50,6 +108,31 @@ const subQueryOptions = {
50
108
  return undefined;
51
109
  }
52
110
  const [{ field, path }] = paths;
111
+ if (hasManyRelationshipOperatorSet.has(operator) && paths.length === 1 && (field.type === 'relationship' || field.type === 'upload') && field.hasMany && typeof field.relationTo === 'string' && isNestedRelationshipQuery(val)) {
112
+ return buildHasManyRelationshipSearchParam({
113
+ branch,
114
+ field,
115
+ locale,
116
+ nestedWhere: val,
117
+ operator: operator,
118
+ path,
119
+ payload,
120
+ req
121
+ });
122
+ }
123
+ if (operator === 'contains' && paths.length === 1 && field.type === 'join' && typeof field.collection === 'string' && isNestedRelationshipQuery(val)) {
124
+ return buildJoinContainsSearchParam({
125
+ branch,
126
+ field,
127
+ locale,
128
+ nestedWhere: val,
129
+ payload,
130
+ req
131
+ });
132
+ }
133
+ if ((operator === 'contains' || operator === 'like' || operator === 'not_like') && (isNestedRelationshipQuery(val) || Array.isArray(val) && val.some((entry)=>isNestedRelationshipQuery(entry)))) {
134
+ throw new APIError(`Invalid value for "${operator}" on path "${path}": expected a string.`, 400);
135
+ }
53
136
  if (path) {
54
137
  const sanitizedQueryValue = sanitizeQueryValue({
55
138
  field,
@@ -79,10 +162,17 @@ const subQueryOptions = {
79
162
  // Remove top collection and reverse array
80
163
  // to work backwards from top
81
164
  const pathsToQuery = paths.slice(1).reverse();
165
+ const parentPaths = paths.slice(0, -1).reverse();
82
166
  let relationshipQuery = {
83
167
  value: {}
84
168
  };
169
+ let relationshipWhere;
85
170
  for (const [i, { collectionSlug, path: subPath }] of pathsToQuery.entries()){
171
+ // The arrays are reversed together, so both entries describe the same relationship hop.
172
+ const parentField = parentPaths[i]?.field;
173
+ if (!parentField) {
174
+ return undefined;
175
+ }
86
176
  if (!collectionSlug) {
87
177
  throw new APIError(`Collection with the slug ${collectionSlug} was not found.`);
88
178
  }
@@ -91,24 +181,33 @@ const subQueryOptions = {
91
181
  collectionSlug
92
182
  });
93
183
  if (i === 0) {
94
- const subQuery = await SubModel.buildQuery({
95
- locale,
184
+ const { branchVisibility, where: relatedWhere } = await resolveRelatedBranchQuery({
185
+ branch,
186
+ collectionSlug,
96
187
  payload,
188
+ req,
97
189
  where: {
98
190
  [subPath]: {
99
191
  [formattedOperator]: val
100
192
  }
101
193
  }
102
194
  });
103
- const field = paths[0].field;
195
+ const subQuery = await SubModel.buildQuery({
196
+ branch,
197
+ locale,
198
+ payload,
199
+ req,
200
+ where: relatedWhere ?? {}
201
+ });
104
202
  const select = {
105
- _id: true
203
+ _id: true,
204
+ _branchDocID: true
106
205
  };
107
206
  let joinPath = null;
108
- if (field.type === 'join') {
207
+ if (parentField.type === 'join') {
109
208
  const relationshipField = getFieldByPath({
110
209
  fields: collectionConfig.flattenedFields,
111
- path: field.on
210
+ path: parentField.on
112
211
  });
113
212
  if (!relationshipField) {
114
213
  throw new APIError('Relationship field was not found');
@@ -123,7 +222,12 @@ const subQueryOptions = {
123
222
  if (joinPath) {
124
223
  select[joinPath] = true;
125
224
  }
126
- const result = await SubModel.find(subQuery).lean().select(select);
225
+ const result = await findRelatedDocuments({
226
+ branchVisibility,
227
+ Model: SubModel,
228
+ projection: select,
229
+ query: subQuery
230
+ });
127
231
  const $in = [];
128
232
  result.forEach((doc)=>{
129
233
  if (joinPath) {
@@ -148,9 +252,10 @@ const subQueryOptions = {
148
252
  $in.push(ref);
149
253
  }
150
254
  } else {
151
- const stringID = doc._id.toString();
255
+ const documentID = doc._branchDocID ?? doc._id;
256
+ const stringID = documentID.toString();
152
257
  if (Types.ObjectId.isValid(stringID)) {
153
- $in.push(doc._id);
258
+ $in.push(documentID);
154
259
  } else {
155
260
  $in.push(stringID);
156
261
  }
@@ -166,17 +271,81 @@ const subQueryOptions = {
166
271
  }
167
272
  const nextSubPath = pathsToQuery[i + 1]?.path;
168
273
  if (nextSubPath) {
169
- relationshipQuery = {
274
+ relationshipWhere = joinPath ? {
275
+ id: {
276
+ in: $in
277
+ }
278
+ } : {
279
+ [nextSubPath]: {
280
+ in: $in
281
+ }
282
+ };
283
+ }
284
+ continue;
285
+ }
286
+ if (!relationshipWhere) {
287
+ return undefined;
288
+ }
289
+ const { branchVisibility, where: relatedWhere } = await resolveRelatedBranchQuery({
290
+ branch,
291
+ collectionSlug,
292
+ payload,
293
+ req,
294
+ where: relationshipWhere
295
+ });
296
+ const subQuery = await SubModel.buildQuery({
297
+ branch,
298
+ locale,
299
+ payload,
300
+ req,
301
+ where: relatedWhere ?? {}
302
+ });
303
+ /**
304
+ * Follow this join back to its parent IDs.
305
+ * For example, matching songs yield album IDs, then artist IDs.
306
+ */ if (parentField.type === 'join') {
307
+ const relationshipField = getFieldByPath({
308
+ fields: collectionConfig.flattenedFields,
309
+ path: parentField.on
310
+ });
311
+ if (!relationshipField) {
312
+ throw new APIError('Relationship field was not found');
313
+ }
314
+ let joinPath = relationshipField.localizedPath;
315
+ if (relationshipField.pathHasLocalized && payload.config.localization) {
316
+ joinPath = joinPath.replace('<locale>', locale || payload.config.localization.defaultLocale);
317
+ }
318
+ const $in = await findRelatedDistinctValues({
319
+ branchVisibility,
320
+ Model: SubModel,
321
+ path: joinPath,
322
+ query: subQuery
323
+ });
324
+ if (i + 1 === pathsToQuery.length) {
325
+ return {
326
+ path: '_id',
170
327
  value: {
171
- [nextSubPath]: $in
328
+ $in
172
329
  }
173
330
  };
174
331
  }
332
+ relationshipWhere = {
333
+ id: {
334
+ in: $in
335
+ }
336
+ };
175
337
  continue;
176
338
  }
177
- const subQuery = relationshipQuery.value;
178
- const result = await SubModel.find(subQuery, subQueryOptions);
179
- const $in = result.map((doc)=>doc._id);
339
+ const result = await findRelatedDocuments({
340
+ branchVisibility,
341
+ Model: SubModel,
342
+ projection: {
343
+ _id: true,
344
+ _branchDocID: true
345
+ },
346
+ query: subQuery
347
+ });
348
+ const $in = result.map((doc)=>doc._branchDocID ?? doc._id);
180
349
  // If it is the last recursion
181
350
  // then pass through the search param
182
351
  if (i + 1 === pathsToQuery.length) {
@@ -189,11 +358,9 @@ const subQueryOptions = {
189
358
  } else {
190
359
  const nextSubPath = pathsToQuery[i + 1]?.path;
191
360
  if (nextSubPath) {
192
- relationshipQuery = {
193
- value: {
194
- [nextSubPath]: {
195
- $in
196
- }
361
+ relationshipWhere = {
362
+ [nextSubPath]: {
363
+ in: $in
197
364
  }
198
365
  };
199
366
  }
@@ -299,5 +466,152 @@ const subQueryOptions = {
299
466
  }
300
467
  return undefined;
301
468
  }
469
+ /**
470
+ * Builds a MongoDB condition for an operator containing a nested has-many relationship query.
471
+ *
472
+ * First, it finds IDs from the related collection that match the nested query. The parent
473
+ * collection can then use `$in` or `$nin` against its stored relationship IDs.
474
+ *
475
+ * @example
476
+ * ```ts
477
+ * // Input
478
+ * { ingredients: { not_equals: { isHealthy: { equals: false } } } }
479
+ *
480
+ * // Simplified MongoDB result, after finding the matching ingredient IDs
481
+ * { ingredients: { $nin: [unhealthyIngredientID] } }
482
+ * ```
483
+ */ async function buildHasManyRelationshipSearchParam({ branch, field, locale, nestedWhere, operator, path, payload, req }) {
484
+ if (field.type !== 'relationship' && field.type !== 'upload' || !field.hasMany || typeof field.relationTo !== 'string' || !isNestedRelationshipQuery(nestedWhere)) {
485
+ return undefined;
486
+ }
487
+ const { Model: RelatedModel } = getCollection({
488
+ adapter: payload.db,
489
+ collectionSlug: field.relationTo
490
+ });
491
+ const pathLocale = payload.config.localization ? payload.config.localization.localeCodes.find((localeCode)=>path.split('.').at(-1) === localeCode) : undefined;
492
+ const { branchVisibility, where: relatedWhere } = await resolveRelatedBranchQuery({
493
+ branch,
494
+ collectionSlug: field.relationTo,
495
+ payload,
496
+ req,
497
+ where: nestedWhere
498
+ });
499
+ const matchingRelatedDocumentsQuery = await RelatedModel.buildQuery({
500
+ branch,
501
+ locale: pathLocale ?? locale,
502
+ payload,
503
+ req,
504
+ where: relatedWhere ?? {}
505
+ });
506
+ const findRelatedDocumentIDs = async (query)=>(await findRelatedDocuments({
507
+ branchVisibility,
508
+ Model: RelatedModel,
509
+ projection: {
510
+ _id: true,
511
+ _branchDocID: true
512
+ },
513
+ query
514
+ })).map((document)=>document._branchDocID ?? document._id);
515
+ switch(operator){
516
+ case 'contains':
517
+ {
518
+ const matchingRelatedDocumentIDs = await findRelatedDocumentIDs(matchingRelatedDocumentsQuery);
519
+ return {
520
+ path,
521
+ value: {
522
+ $in: matchingRelatedDocumentIDs
523
+ }
524
+ };
525
+ }
526
+ case 'equals':
527
+ {
528
+ // Every related document satisfies an empty nested query.
529
+ if (!Object.keys(nestedWhere).length) {
530
+ return {
531
+ path,
532
+ value: {
533
+ $nin: []
534
+ }
535
+ };
536
+ }
537
+ // MongoDB rejects `$near` and `$text` when they are inverted with `$nor`. Check the parent
538
+ // instead: none of its IDs may fall outside the matching IDs.
539
+ const matchingRelatedDocumentIDs = await findRelatedDocumentIDs(matchingRelatedDocumentsQuery);
540
+ return {
541
+ path,
542
+ value: {
543
+ $not: {
544
+ $elemMatch: {
545
+ $nin: matchingRelatedDocumentIDs
546
+ }
547
+ }
548
+ }
549
+ };
550
+ }
551
+ case 'not_equals':
552
+ {
553
+ const matchingRelatedDocumentIDs = await findRelatedDocumentIDs(matchingRelatedDocumentsQuery);
554
+ return {
555
+ path,
556
+ value: {
557
+ $nin: matchingRelatedDocumentIDs
558
+ }
559
+ };
560
+ }
561
+ }
562
+ }
563
+ /**
564
+ * Builds a MongoDB condition for a `contains` query nested on a join field.
565
+ *
566
+ * Finds documents in the joined collection that match the nested query, then follows the join's
567
+ * `on` relationship to collect the parent IDs those documents point back to. Because the nested
568
+ * query resolves against a single joined document, the user's filter and any injected access
569
+ * constraint must be satisfied by the same document.
570
+ */ async function buildJoinContainsSearchParam({ branch, field, locale, nestedWhere, payload, req }) {
571
+ if (field.type !== 'join' || typeof field.collection !== 'string' || !isNestedRelationshipQuery(nestedWhere)) {
572
+ return undefined;
573
+ }
574
+ const { collectionConfig, Model: JoinedModel } = getCollection({
575
+ adapter: payload.db,
576
+ collectionSlug: field.collection
577
+ });
578
+ const relationshipField = getFieldByPath({
579
+ fields: collectionConfig.flattenedFields,
580
+ path: field.on
581
+ });
582
+ if (!relationshipField) {
583
+ throw new APIError('Relationship field was not found');
584
+ }
585
+ let joinPath = relationshipField.localizedPath;
586
+ if (relationshipField.pathHasLocalized && payload.config.localization) {
587
+ joinPath = joinPath.replace('<locale>', locale || payload.config.localization.defaultLocale);
588
+ }
589
+ const { branchVisibility, where: relatedWhere } = await resolveRelatedBranchQuery({
590
+ branch,
591
+ collectionSlug: field.collection,
592
+ payload,
593
+ req,
594
+ where: nestedWhere
595
+ });
596
+ const subQuery = await JoinedModel.buildQuery({
597
+ branch,
598
+ locale,
599
+ payload,
600
+ req,
601
+ where: relatedWhere ?? {}
602
+ });
603
+ const parentIDs = await findRelatedDistinctValues({
604
+ branchVisibility,
605
+ Model: JoinedModel,
606
+ path: joinPath,
607
+ query: subQuery
608
+ });
609
+ return {
610
+ path: '_id',
611
+ value: {
612
+ $in: parentIDs
613
+ }
614
+ };
615
+ }
302
616
 
303
617
  //# sourceMappingURL=buildSearchParams.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/queries/buildSearchParams.ts"],"sourcesContent":["import type { FilterQuery } from 'mongoose'\nimport type { FlattenedField, Operator, PathToQuery, Payload } from 'payload'\n\nimport { Types } from 'mongoose'\nimport { APIError, escapeRegExp, getFieldByPath, getLocalizedPaths } from 'payload'\nimport { validOperatorSet } from 'payload/shared'\n\nimport type { MongooseAdapter } from '../index.js'\nimport type { OperatorMapKey } from './operatorMap.js'\n\nimport { getCollection } from '../utilities/getEntity.js'\nimport { isObjectID } from '../utilities/isObjectID.js'\nimport { operatorMap } from './operatorMap.js'\nimport { sanitizeQueryValue } from './sanitizeQueryValue.js'\n\ntype SearchParam = {\n path?: string\n rawQuery?: unknown\n value?: unknown\n}\n\nconst subQueryOptions = {\n lean: true,\n}\n\n/**\n * Convert the Payload key / value / operator into a MongoDB query\n */\nexport async function buildSearchParam({\n collectionSlug,\n fields,\n globalSlug,\n incomingPath,\n locale,\n operator,\n parentIsLocalized,\n payload,\n val,\n}: {\n collectionSlug?: string\n fields: FlattenedField[]\n globalSlug?: string\n incomingPath: string\n locale?: string\n operator: Operator\n parentIsLocalized: boolean\n payload: Payload\n val: unknown\n}): Promise<SearchParam | undefined> {\n // Replace GraphQL nested field double underscore formatting\n let sanitizedPath = incomingPath.replace(/__/g, '.')\n if (sanitizedPath === 'id') {\n sanitizedPath = '_id'\n }\n\n let paths: PathToQuery[] = []\n\n let hasCustomID = false\n\n if (sanitizedPath === '_id') {\n const customIDFieldType = collectionSlug\n ? payload.collections[collectionSlug]?.customIDType\n : undefined\n\n let idFieldType: 'number' | 'text' = 'text'\n\n if (customIDFieldType) {\n idFieldType = customIDFieldType\n hasCustomID = true\n }\n\n paths.push({\n collectionSlug,\n complete: true,\n field: {\n name: 'id',\n type: idFieldType,\n } as FlattenedField,\n parentIsLocalized: parentIsLocalized ?? false,\n path: '_id',\n })\n } else {\n paths = getLocalizedPaths({\n collectionSlug,\n fields,\n globalSlug,\n incomingPath: sanitizedPath,\n locale,\n parentIsLocalized,\n payload,\n })\n }\n\n if (!paths[0]) {\n return undefined\n }\n\n const [{ field, path }] = paths\n if (path) {\n const sanitizedQueryValue = sanitizeQueryValue({\n field,\n hasCustomID,\n locale,\n operator,\n parentIsLocalized,\n path,\n payload,\n val,\n })\n\n if (!sanitizedQueryValue) {\n return undefined\n }\n\n const { operator: formattedOperator, rawQuery, val: formattedValue } = sanitizedQueryValue\n\n if (rawQuery && paths.length === 1) {\n return { value: rawQuery }\n }\n\n if (!formattedOperator) {\n return undefined\n }\n\n // If there are multiple collections to search through,\n // Recursively build up a list of query constraints\n if (paths.length > 1) {\n // Remove top collection and reverse array\n // to work backwards from top\n const pathsToQuery = paths.slice(1).reverse()\n\n let relationshipQuery: SearchParam = {\n value: {},\n }\n\n for (const [i, { collectionSlug, path: subPath }] of pathsToQuery.entries()) {\n if (!collectionSlug) {\n throw new APIError(`Collection with the slug ${collectionSlug} was not found.`)\n }\n\n const { collectionConfig, Model: SubModel } = getCollection({\n adapter: payload.db as MongooseAdapter,\n collectionSlug,\n })\n\n if (i === 0) {\n const subQuery = await SubModel.buildQuery({\n locale,\n payload,\n where: {\n [subPath]: {\n [formattedOperator]: val,\n },\n },\n })\n\n const field = paths[0].field\n\n const select: Record<string, boolean> = {\n _id: true,\n }\n\n let joinPath: null | string = null\n\n if (field.type === 'join') {\n const relationshipField = getFieldByPath({\n fields: collectionConfig.flattenedFields,\n path: field.on,\n })\n if (!relationshipField) {\n throw new APIError('Relationship field was not found')\n }\n\n let path = relationshipField.localizedPath\n if (relationshipField.pathHasLocalized && payload.config.localization) {\n path = path.replace('<locale>', locale || payload.config.localization.defaultLocale)\n }\n select[path] = true\n\n joinPath = path\n }\n\n if (joinPath) {\n select[joinPath] = true\n }\n\n const result = await SubModel.find(subQuery).lean().select(select)\n\n const $in: unknown[] = []\n\n result.forEach((doc: any) => {\n if (joinPath) {\n let ref = doc\n\n for (const segment of joinPath.split('.')) {\n if (Array.isArray(ref)) {\n ref = ref\n .map((item) => (typeof item === 'object' && item ? item[segment] : undefined))\n .flat()\n .filter((item) => item != null)\n } else if (typeof ref === 'object' && ref) {\n ref = ref[segment]\n } else {\n ref = undefined\n break\n }\n }\n\n if (Array.isArray(ref)) {\n for (const item of ref) {\n if (isObjectID(item)) {\n $in.push(item)\n }\n }\n } else if (isObjectID(ref)) {\n $in.push(ref)\n }\n } else {\n const stringID = doc._id.toString()\n if (Types.ObjectId.isValid(stringID)) {\n $in.push(doc._id)\n } else {\n $in.push(stringID)\n }\n }\n })\n\n if (pathsToQuery.length === 1) {\n return {\n path: joinPath ? '_id' : path,\n value: { $in },\n }\n }\n\n const nextSubPath = pathsToQuery[i + 1]?.path\n\n if (nextSubPath) {\n relationshipQuery = { value: { [nextSubPath]: $in } }\n }\n\n continue\n }\n\n const subQuery = relationshipQuery.value as FilterQuery<any>\n const result = await SubModel.find(subQuery, subQueryOptions)\n\n const $in = result.map((doc) => doc._id)\n\n // If it is the last recursion\n // then pass through the search param\n if (i + 1 === pathsToQuery.length) {\n relationshipQuery = {\n path,\n value: { $in },\n }\n } else {\n const nextSubPath = pathsToQuery[i + 1]?.path\n if (nextSubPath) {\n relationshipQuery = {\n value: {\n [nextSubPath]: { $in },\n },\n }\n }\n }\n }\n\n return relationshipQuery\n }\n\n if (formattedOperator && validOperatorSet.has(formattedOperator as Operator)) {\n const operatorKey = operatorMap[formattedOperator as OperatorMapKey]\n\n if (field.type === 'relationship' || field.type === 'upload') {\n let hasNumberIDRelation\n let multiIDCondition = '$or'\n if (operatorKey === '$ne') {\n multiIDCondition = '$and'\n }\n\n const result = {\n value: {\n [multiIDCondition]: [{ [path]: { [operatorKey]: formattedValue } }],\n },\n }\n\n if (typeof formattedValue === 'string') {\n if (Types.ObjectId.isValid(formattedValue)) {\n result.value[multiIDCondition]?.push({\n [path]: { [operatorKey]: new Types.ObjectId(formattedValue) },\n })\n } else {\n ;(Array.isArray(field.relationTo) ? field.relationTo : [field.relationTo]).forEach(\n (relationTo) => {\n const isRelatedToCustomNumberID =\n payload.collections[relationTo]?.customIDType === 'number'\n\n if (isRelatedToCustomNumberID) {\n hasNumberIDRelation = true\n }\n },\n )\n\n if (hasNumberIDRelation) {\n result.value[multiIDCondition]?.push({\n [path]: { [operatorKey]: parseFloat(formattedValue) },\n })\n }\n }\n }\n\n const length = result.value[multiIDCondition]?.length\n\n if (typeof length === 'number' && length > 1) {\n return result\n }\n }\n\n if (formattedOperator === 'like' && typeof formattedValue === 'string') {\n const words = formattedValue.split(' ')\n\n const result = {\n value: {\n $and: words.map((word) => ({\n [path]: {\n $options: 'i',\n $regex: escapeRegExp(word),\n },\n })),\n },\n }\n\n return result\n }\n\n if (formattedOperator === 'not_like' && typeof formattedValue === 'string') {\n const words = formattedValue.split(' ')\n\n const result = {\n value: {\n $and: words.map((word) => ({\n [path]: {\n $not: {\n $options: 'i',\n $regex: escapeRegExp(word),\n },\n },\n })),\n },\n }\n\n return result\n }\n\n // Some operators like 'near' need to define a full query\n // so if there is no operator key, just return the value\n if (!operatorKey) {\n return {\n path,\n value: formattedValue,\n }\n }\n\n return {\n path,\n value: { [operatorKey]: formattedValue },\n }\n }\n }\n return undefined\n}\n"],"names":["Types","APIError","escapeRegExp","getFieldByPath","getLocalizedPaths","validOperatorSet","getCollection","isObjectID","operatorMap","sanitizeQueryValue","subQueryOptions","lean","buildSearchParam","collectionSlug","fields","globalSlug","incomingPath","locale","operator","parentIsLocalized","payload","val","sanitizedPath","replace","paths","hasCustomID","customIDFieldType","collections","customIDType","undefined","idFieldType","push","complete","field","name","type","path","sanitizedQueryValue","formattedOperator","rawQuery","formattedValue","length","value","pathsToQuery","slice","reverse","relationshipQuery","i","subPath","entries","collectionConfig","Model","SubModel","adapter","db","subQuery","buildQuery","where","select","_id","joinPath","relationshipField","flattenedFields","on","localizedPath","pathHasLocalized","config","localization","defaultLocale","result","find","$in","forEach","doc","ref","segment","split","Array","isArray","map","item","flat","filter","stringID","toString","ObjectId","isValid","nextSubPath","has","operatorKey","hasNumberIDRelation","multiIDCondition","relationTo","isRelatedToCustomNumberID","parseFloat","words","$and","word","$options","$regex","$not"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/queries/buildSearchParams.ts"],"sourcesContent":["import type { PipelineStage, QueryFilter } from 'mongoose'\nimport type {\n FlattenedField,\n HasManyRelationshipOperator,\n Operator,\n PathToQuery,\n Payload,\n PayloadRequest,\n Where,\n} from 'payload'\n\nimport { Types } from 'mongoose'\nimport {\n APIError,\n escapeRegExp,\n getFieldByPath,\n getLocalizedPaths,\n resolveBranchQuery,\n resolveBranchReadState,\n rewriteBranchIDs,\n} from 'payload'\nimport {\n hasManyRelationshipOperatorSet,\n isNestedRelationshipQuery,\n validOperatorSet,\n} from 'payload/shared'\n\nimport type { MongooseAdapter } from '../index.js'\nimport type { CollectionModel } from '../types.js'\nimport type { OperatorMapKey } from './operatorMap.js'\n\nimport { getCollection } from '../utilities/getEntity.js'\nimport { isObjectID } from '../utilities/isObjectID.js'\nimport { buildBranchVisibilityStages } from './buildBranchVisibility.js'\nimport { operatorMap } from './operatorMap.js'\nimport { sanitizeQueryValue } from './sanitizeQueryValue.js'\n\ntype SearchParam = {\n path?: string\n rawQuery?: unknown\n value?: unknown\n}\n\nconst resolveRelatedBranchQuery = async ({\n branch,\n collectionSlug,\n payload,\n req,\n where,\n}: {\n branch?: false | string\n collectionSlug: string\n payload: Payload\n req?: Partial<PayloadRequest>\n where: Where\n}) => {\n const adapter = payload.db as MongooseAdapter\n const branchReadState = resolveBranchReadState({ branch, collectionSlug, req })\n const resolvedWhere = branchReadState.useBranching\n ? rewriteBranchIDs(where)\n : await resolveBranchQuery({ branch, collectionSlug, req, where })\n\n return {\n branchVisibility: branchReadState.useBranching\n ? buildBranchVisibilityStages({\n adapter,\n branch: branchReadState.branch,\n collectionSlug,\n })\n : [],\n where: resolvedWhere ?? {},\n }\n}\n\nconst findRelatedDocuments = async ({\n branchVisibility,\n Model,\n projection,\n query,\n}: {\n branchVisibility: PipelineStage[]\n Model: CollectionModel\n projection: Record<string, boolean>\n query: Record<string, unknown>\n}) => {\n if (branchVisibility.length) {\n return Model.aggregate([{ $match: query }, ...branchVisibility, { $project: projection }])\n }\n\n return Model.find(query).lean().select(projection)\n}\n\nconst findRelatedDistinctValues = async ({\n branchVisibility,\n Model,\n path,\n query,\n}: {\n branchVisibility: PipelineStage[]\n Model: CollectionModel\n path: string\n query: Record<string, unknown>\n}) => {\n if (!branchVisibility.length) {\n return Model.distinct(path, query)\n }\n\n return Model.aggregate([\n { $match: query },\n ...branchVisibility,\n { $project: { value: `$${path}` } },\n { $unwind: '$value' },\n { $group: { _id: '$value' } },\n ]).then((results) => results.map(({ _id }) => _id))\n}\n\n/**\n * Convert the Payload key / value / operator into a MongoDB query\n */\nexport async function buildSearchParam({\n branch,\n collectionSlug,\n fields,\n globalSlug,\n incomingPath,\n locale,\n operator,\n parentIsLocalized,\n payload,\n req,\n val,\n}: {\n branch?: false | string\n collectionSlug?: string\n fields: FlattenedField[]\n globalSlug?: string\n incomingPath: string\n locale?: string\n operator: Operator\n parentIsLocalized: boolean\n payload: Payload\n req?: Partial<PayloadRequest>\n val: unknown\n}): Promise<SearchParam | undefined> {\n // Replace GraphQL nested field double underscore formatting\n let sanitizedPath = incomingPath.replace(/__/g, '.')\n if (sanitizedPath === 'id') {\n sanitizedPath = '_id'\n }\n\n let paths: PathToQuery[] = []\n\n let hasCustomID = false\n\n if (sanitizedPath === '_id') {\n const customIDFieldType = collectionSlug\n ? payload.collections[collectionSlug]?.customIDType\n : undefined\n\n let idFieldType: 'number' | 'text' = 'text'\n\n if (customIDFieldType) {\n idFieldType = customIDFieldType\n hasCustomID = true\n }\n\n paths.push({\n collectionSlug,\n complete: true,\n field: {\n name: 'id',\n type: idFieldType,\n } as FlattenedField,\n parentIsLocalized: parentIsLocalized ?? false,\n path: '_id',\n })\n } else {\n paths = getLocalizedPaths({\n collectionSlug,\n fields,\n globalSlug,\n incomingPath: sanitizedPath,\n locale,\n parentIsLocalized,\n payload,\n })\n }\n\n if (!paths[0]) {\n return undefined\n }\n\n const [{ field, path }] = paths\n\n if (\n hasManyRelationshipOperatorSet.has(operator as HasManyRelationshipOperator) &&\n paths.length === 1 &&\n (field.type === 'relationship' || field.type === 'upload') &&\n field.hasMany &&\n typeof field.relationTo === 'string' &&\n isNestedRelationshipQuery(val)\n ) {\n return buildHasManyRelationshipSearchParam({\n branch,\n field,\n locale,\n nestedWhere: val,\n operator: operator as HasManyRelationshipOperator,\n path,\n payload,\n req,\n })\n }\n\n if (\n operator === 'contains' &&\n paths.length === 1 &&\n field.type === 'join' &&\n typeof field.collection === 'string' &&\n isNestedRelationshipQuery(val)\n ) {\n return buildJoinContainsSearchParam({\n branch,\n field,\n locale,\n nestedWhere: val,\n payload,\n req,\n })\n }\n\n if (\n (operator === 'contains' || operator === 'like' || operator === 'not_like') &&\n (isNestedRelationshipQuery(val) ||\n (Array.isArray(val) && val.some((entry) => isNestedRelationshipQuery(entry))))\n ) {\n throw new APIError(`Invalid value for \"${operator}\" on path \"${path}\": expected a string.`, 400)\n }\n\n if (path) {\n const sanitizedQueryValue = sanitizeQueryValue({\n field,\n hasCustomID,\n locale,\n operator,\n parentIsLocalized,\n path,\n payload,\n val,\n })\n\n if (!sanitizedQueryValue) {\n return undefined\n }\n\n const { operator: formattedOperator, rawQuery, val: formattedValue } = sanitizedQueryValue\n\n if (rawQuery && paths.length === 1) {\n return { value: rawQuery }\n }\n\n if (!formattedOperator) {\n return undefined\n }\n\n // If there are multiple collections to search through,\n // Recursively build up a list of query constraints\n if (paths.length > 1) {\n // Remove top collection and reverse array\n // to work backwards from top\n const pathsToQuery = paths.slice(1).reverse()\n const parentPaths = paths.slice(0, -1).reverse()\n\n let relationshipQuery: SearchParam = { value: {} }\n let relationshipWhere: undefined | Where\n\n for (const [i, { collectionSlug, path: subPath }] of pathsToQuery.entries()) {\n // The arrays are reversed together, so both entries describe the same relationship hop.\n const parentField = parentPaths[i]?.field\n\n if (!parentField) {\n return undefined\n }\n\n if (!collectionSlug) {\n throw new APIError(`Collection with the slug ${collectionSlug} was not found.`)\n }\n\n const { collectionConfig, Model: SubModel } = getCollection({\n adapter: payload.db as MongooseAdapter,\n collectionSlug,\n })\n\n if (i === 0) {\n const { branchVisibility, where: relatedWhere } = await resolveRelatedBranchQuery({\n branch,\n collectionSlug,\n payload,\n req,\n where: {\n [subPath]: {\n [formattedOperator]: val,\n },\n },\n })\n const subQuery = await SubModel.buildQuery({\n branch,\n locale,\n payload,\n req,\n where: relatedWhere ?? {},\n })\n\n const select: Record<string, boolean> = {\n _id: true,\n _branchDocID: true,\n }\n\n let joinPath: null | string = null\n\n if (parentField.type === 'join') {\n const relationshipField = getFieldByPath({\n fields: collectionConfig.flattenedFields,\n path: parentField.on,\n })\n if (!relationshipField) {\n throw new APIError('Relationship field was not found')\n }\n\n let path = relationshipField.localizedPath\n if (relationshipField.pathHasLocalized && payload.config.localization) {\n path = path.replace('<locale>', locale || payload.config.localization.defaultLocale)\n }\n select[path] = true\n\n joinPath = path\n }\n\n if (joinPath) {\n select[joinPath] = true\n }\n\n const result = await findRelatedDocuments({\n branchVisibility,\n Model: SubModel,\n projection: select,\n query: subQuery,\n })\n\n const $in: unknown[] = []\n\n result.forEach((doc: any) => {\n if (joinPath) {\n let ref = doc\n\n for (const segment of joinPath.split('.')) {\n if (Array.isArray(ref)) {\n ref = ref\n .map((item) => (typeof item === 'object' && item ? item[segment] : undefined))\n .flat()\n .filter((item) => item != null)\n } else if (typeof ref === 'object' && ref) {\n ref = ref[segment]\n } else {\n ref = undefined\n break\n }\n }\n\n if (Array.isArray(ref)) {\n for (const item of ref) {\n if (isObjectID(item)) {\n $in.push(item)\n }\n }\n } else if (isObjectID(ref)) {\n $in.push(ref)\n }\n } else {\n const documentID = doc._branchDocID ?? doc._id\n const stringID = documentID.toString()\n if (Types.ObjectId.isValid(stringID)) {\n $in.push(documentID)\n } else {\n $in.push(stringID)\n }\n }\n })\n\n if (pathsToQuery.length === 1) {\n return {\n path: joinPath ? '_id' : path,\n value: { $in },\n }\n }\n\n const nextSubPath = pathsToQuery[i + 1]?.path\n\n if (nextSubPath) {\n relationshipWhere = joinPath ? { id: { in: $in } } : { [nextSubPath]: { in: $in } }\n }\n\n continue\n }\n\n if (!relationshipWhere) {\n return undefined\n }\n\n const { branchVisibility, where: relatedWhere } = await resolveRelatedBranchQuery({\n branch,\n collectionSlug,\n payload,\n req,\n where: relationshipWhere,\n })\n const subQuery = (await SubModel.buildQuery({\n branch,\n locale,\n payload,\n req,\n where: relatedWhere ?? {},\n })) as QueryFilter<any>\n\n /**\n * Follow this join back to its parent IDs.\n * For example, matching songs yield album IDs, then artist IDs.\n */\n if (parentField.type === 'join') {\n const relationshipField = getFieldByPath({\n fields: collectionConfig.flattenedFields,\n path: parentField.on,\n })\n if (!relationshipField) {\n throw new APIError('Relationship field was not found')\n }\n\n let joinPath = relationshipField.localizedPath\n if (relationshipField.pathHasLocalized && payload.config.localization) {\n joinPath = joinPath.replace(\n '<locale>',\n locale || payload.config.localization.defaultLocale,\n )\n }\n\n const $in = await findRelatedDistinctValues({\n branchVisibility,\n Model: SubModel,\n path: joinPath,\n query: subQuery,\n })\n if (i + 1 === pathsToQuery.length) {\n return { path: '_id', value: { $in } }\n }\n\n relationshipWhere = { id: { in: $in } }\n continue\n }\n\n const result = await findRelatedDocuments({\n branchVisibility,\n Model: SubModel,\n projection: { _id: true, _branchDocID: true },\n query: subQuery,\n })\n\n const $in = result.map((doc) => doc._branchDocID ?? doc._id)\n\n // If it is the last recursion\n // then pass through the search param\n if (i + 1 === pathsToQuery.length) {\n relationshipQuery = {\n path,\n value: { $in },\n }\n } else {\n const nextSubPath = pathsToQuery[i + 1]?.path\n if (nextSubPath) {\n relationshipWhere = { [nextSubPath]: { in: $in } }\n }\n }\n }\n\n return relationshipQuery\n }\n\n if (formattedOperator && validOperatorSet.has(formattedOperator as Operator)) {\n const operatorKey = operatorMap[formattedOperator as OperatorMapKey]\n\n if (field.type === 'relationship' || field.type === 'upload') {\n let hasNumberIDRelation\n let multiIDCondition = '$or'\n if (operatorKey === '$ne') {\n multiIDCondition = '$and'\n }\n\n const result = {\n value: {\n [multiIDCondition]: [{ [path]: { [operatorKey]: formattedValue } }],\n },\n }\n\n if (typeof formattedValue === 'string') {\n if (Types.ObjectId.isValid(formattedValue)) {\n result.value[multiIDCondition]?.push({\n [path]: { [operatorKey]: new Types.ObjectId(formattedValue) },\n })\n } else {\n ;(Array.isArray(field.relationTo) ? field.relationTo : [field.relationTo]).forEach(\n (relationTo) => {\n const isRelatedToCustomNumberID =\n payload.collections[relationTo]?.customIDType === 'number'\n\n if (isRelatedToCustomNumberID) {\n hasNumberIDRelation = true\n }\n },\n )\n\n if (hasNumberIDRelation) {\n result.value[multiIDCondition]?.push({\n [path]: { [operatorKey]: parseFloat(formattedValue) },\n })\n }\n }\n }\n\n const length = result.value[multiIDCondition]?.length\n\n if (typeof length === 'number' && length > 1) {\n return result\n }\n }\n\n if (formattedOperator === 'like' && typeof formattedValue === 'string') {\n const words = formattedValue.split(' ')\n\n const result = {\n value: {\n $and: words.map((word) => ({\n [path]: {\n $options: 'i',\n $regex: escapeRegExp(word),\n },\n })),\n },\n }\n\n return result\n }\n\n if (formattedOperator === 'not_like' && typeof formattedValue === 'string') {\n const words = formattedValue.split(' ')\n\n const result = {\n value: {\n $and: words.map((word) => ({\n [path]: {\n $not: {\n $options: 'i',\n $regex: escapeRegExp(word),\n },\n },\n })),\n },\n }\n\n return result\n }\n\n // Some operators like 'near' need to define a full query\n // so if there is no operator key, just return the value\n if (!operatorKey) {\n return {\n path,\n value: formattedValue,\n }\n }\n\n return {\n path,\n value: { [operatorKey]: formattedValue },\n }\n }\n }\n return undefined\n}\n\n/**\n * Builds a MongoDB condition for an operator containing a nested has-many relationship query.\n *\n * First, it finds IDs from the related collection that match the nested query. The parent\n * collection can then use `$in` or `$nin` against its stored relationship IDs.\n *\n * @example\n * ```ts\n * // Input\n * { ingredients: { not_equals: { isHealthy: { equals: false } } } }\n *\n * // Simplified MongoDB result, after finding the matching ingredient IDs\n * { ingredients: { $nin: [unhealthyIngredientID] } }\n * ```\n */\nasync function buildHasManyRelationshipSearchParam({\n branch,\n field,\n locale,\n nestedWhere,\n operator,\n path,\n payload,\n req,\n}: {\n branch?: false | string\n field: FlattenedField\n locale?: string\n nestedWhere: unknown\n operator: HasManyRelationshipOperator\n path: string\n payload: Payload\n req?: Partial<PayloadRequest>\n}): Promise<SearchParam | undefined> {\n if (\n (field.type !== 'relationship' && field.type !== 'upload') ||\n !field.hasMany ||\n typeof field.relationTo !== 'string' ||\n !isNestedRelationshipQuery(nestedWhere)\n ) {\n return undefined\n }\n\n const { Model: RelatedModel } = getCollection({\n adapter: payload.db as MongooseAdapter,\n collectionSlug: field.relationTo,\n })\n const pathLocale = payload.config.localization\n ? payload.config.localization.localeCodes.find(\n (localeCode) => path.split('.').at(-1) === localeCode,\n )\n : undefined\n const { branchVisibility, where: relatedWhere } = await resolveRelatedBranchQuery({\n branch,\n collectionSlug: field.relationTo,\n payload,\n req,\n where: nestedWhere,\n })\n const matchingRelatedDocumentsQuery = await RelatedModel.buildQuery({\n branch,\n locale: pathLocale ?? locale,\n payload,\n req,\n where: relatedWhere ?? {},\n })\n\n const findRelatedDocumentIDs = async (query: Record<string, unknown>) =>\n (\n await findRelatedDocuments({\n branchVisibility,\n Model: RelatedModel,\n projection: { _id: true, _branchDocID: true },\n query,\n })\n ).map((document) => document._branchDocID ?? document._id)\n\n switch (operator) {\n case 'contains': {\n const matchingRelatedDocumentIDs = await findRelatedDocumentIDs(matchingRelatedDocumentsQuery)\n\n return {\n path,\n value: { $in: matchingRelatedDocumentIDs },\n }\n }\n\n case 'equals': {\n // Every related document satisfies an empty nested query.\n if (!Object.keys(nestedWhere).length) {\n return {\n path,\n value: { $nin: [] },\n }\n }\n\n // MongoDB rejects `$near` and `$text` when they are inverted with `$nor`. Check the parent\n // instead: none of its IDs may fall outside the matching IDs.\n const matchingRelatedDocumentIDs = await findRelatedDocumentIDs(matchingRelatedDocumentsQuery)\n\n return {\n path,\n value: { $not: { $elemMatch: { $nin: matchingRelatedDocumentIDs } } },\n }\n }\n\n case 'not_equals': {\n const matchingRelatedDocumentIDs = await findRelatedDocumentIDs(matchingRelatedDocumentsQuery)\n\n return {\n path,\n value: { $nin: matchingRelatedDocumentIDs },\n }\n }\n }\n}\n\n/**\n * Builds a MongoDB condition for a `contains` query nested on a join field.\n *\n * Finds documents in the joined collection that match the nested query, then follows the join's\n * `on` relationship to collect the parent IDs those documents point back to. Because the nested\n * query resolves against a single joined document, the user's filter and any injected access\n * constraint must be satisfied by the same document.\n */\nasync function buildJoinContainsSearchParam({\n branch,\n field,\n locale,\n nestedWhere,\n payload,\n req,\n}: {\n branch?: false | string\n field: FlattenedField\n locale?: string\n nestedWhere: unknown\n payload: Payload\n req?: Partial<PayloadRequest>\n}): Promise<SearchParam | undefined> {\n if (\n field.type !== 'join' ||\n typeof field.collection !== 'string' ||\n !isNestedRelationshipQuery(nestedWhere)\n ) {\n return undefined\n }\n\n const { collectionConfig, Model: JoinedModel } = getCollection({\n adapter: payload.db as MongooseAdapter,\n collectionSlug: field.collection,\n })\n\n const relationshipField = getFieldByPath({\n fields: collectionConfig.flattenedFields,\n path: field.on,\n })\n\n if (!relationshipField) {\n throw new APIError('Relationship field was not found')\n }\n\n let joinPath = relationshipField.localizedPath\n if (relationshipField.pathHasLocalized && payload.config.localization) {\n joinPath = joinPath.replace('<locale>', locale || payload.config.localization.defaultLocale)\n }\n\n const { branchVisibility, where: relatedWhere } = await resolveRelatedBranchQuery({\n branch,\n collectionSlug: field.collection,\n payload,\n req,\n where: nestedWhere,\n })\n const subQuery = await JoinedModel.buildQuery({\n branch,\n locale,\n payload,\n req,\n where: relatedWhere ?? {},\n })\n\n const parentIDs = await findRelatedDistinctValues({\n branchVisibility,\n Model: JoinedModel,\n path: joinPath,\n query: subQuery,\n })\n\n return {\n path: '_id',\n value: { $in: parentIDs },\n }\n}\n"],"names":["Types","APIError","escapeRegExp","getFieldByPath","getLocalizedPaths","resolveBranchQuery","resolveBranchReadState","rewriteBranchIDs","hasManyRelationshipOperatorSet","isNestedRelationshipQuery","validOperatorSet","getCollection","isObjectID","buildBranchVisibilityStages","operatorMap","sanitizeQueryValue","resolveRelatedBranchQuery","branch","collectionSlug","payload","req","where","adapter","db","branchReadState","resolvedWhere","useBranching","branchVisibility","findRelatedDocuments","Model","projection","query","length","aggregate","$match","$project","find","lean","select","findRelatedDistinctValues","path","distinct","value","$unwind","$group","_id","then","results","map","buildSearchParam","fields","globalSlug","incomingPath","locale","operator","parentIsLocalized","val","sanitizedPath","replace","paths","hasCustomID","customIDFieldType","collections","customIDType","undefined","idFieldType","push","complete","field","name","type","has","hasMany","relationTo","buildHasManyRelationshipSearchParam","nestedWhere","collection","buildJoinContainsSearchParam","Array","isArray","some","entry","sanitizedQueryValue","formattedOperator","rawQuery","formattedValue","pathsToQuery","slice","reverse","parentPaths","relationshipQuery","relationshipWhere","i","subPath","entries","parentField","collectionConfig","SubModel","relatedWhere","subQuery","buildQuery","_branchDocID","joinPath","relationshipField","flattenedFields","on","localizedPath","pathHasLocalized","config","localization","defaultLocale","result","$in","forEach","doc","ref","segment","split","item","flat","filter","documentID","stringID","toString","ObjectId","isValid","nextSubPath","id","in","operatorKey","hasNumberIDRelation","multiIDCondition","isRelatedToCustomNumberID","parseFloat","words","$and","word","$options","$regex","$not","RelatedModel","pathLocale","localeCodes","localeCode","at","matchingRelatedDocumentsQuery","findRelatedDocumentIDs","document","matchingRelatedDocumentIDs","Object","keys","$nin","$elemMatch","JoinedModel","parentIDs"],"mappings":"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"}
@@ -1,12 +1,14 @@
1
- import type { FlattenedField, Payload, Where } from 'payload';
1
+ import type { FlattenedField, Payload, PayloadRequest, Where } from 'payload';
2
2
  type GetBuildQueryPluginArgs = {
3
3
  collectionSlug?: string;
4
4
  versionsFields?: FlattenedField[];
5
5
  };
6
6
  export type BuildQueryArgs = {
7
+ branch?: false | string;
7
8
  globalSlug?: string;
8
9
  locale?: string;
9
10
  payload: Payload;
11
+ req?: Partial<PayloadRequest>;
10
12
  where: Where;
11
13
  };
12
14
  export declare const getBuildQueryPlugin: ({ collectionSlug, versionsFields, }?: GetBuildQueryPluginArgs) => (schema: any) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"getBuildQueryPlugin.d.ts","sourceRoot":"","sources":["../../src/queries/getBuildQueryPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAM7D,KAAK,uBAAuB,GAAG;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,cAAc,EAAE,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,KAAK,CAAA;CACb,CAAA;AAKD,eAAO,MAAM,mBAAmB,yCAG7B,uBAAuB,cACiB,GAAG,SAmD7C,CAAA"}
1
+ {"version":3,"file":"getBuildQueryPlugin.d.ts","sourceRoot":"","sources":["../../src/queries/getBuildQueryPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAM7E,KAAK,uBAAuB,GAAG;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,cAAc,EAAE,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAC7B,KAAK,EAAE,KAAK,CAAA;CACb,CAAA;AAKD,eAAO,MAAM,mBAAmB,yCAG7B,uBAAuB,cACiB,GAAG,SAuD7C,CAAA"}
@@ -6,7 +6,7 @@ import { parseParams } from './parseParams.js';
6
6
  export const getBuildQueryPlugin = ({ collectionSlug, versionsFields } = {})=>{
7
7
  return function buildQueryPlugin(schema) {
8
8
  const modifiedSchema = schema;
9
- async function schemaBuildQuery({ globalSlug, locale, payload, where }) {
9
+ async function schemaBuildQuery({ branch, globalSlug, locale, payload, req, where }) {
10
10
  let fields = null;
11
11
  if (versionsFields) {
12
12
  fields = versionsFields;
@@ -30,12 +30,14 @@ export const getBuildQueryPlugin = ({ collectionSlug, versionsFields } = {})=>{
30
30
  throw new APIError('Fields are not initialized.');
31
31
  }
32
32
  const result = await parseParams({
33
+ branch,
33
34
  collectionSlug,
34
35
  fields,
35
36
  globalSlug,
36
37
  locale,
37
38
  parentIsLocalized: false,
38
39
  payload,
40
+ req,
39
41
  where
40
42
  });
41
43
  return result;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/queries/getBuildQueryPlugin.ts"],"sourcesContent":["import type { FlattenedField, Payload, Where } from 'payload'\n\nimport { APIError } from 'payload'\n\nimport { parseParams } from './parseParams.js'\n\ntype GetBuildQueryPluginArgs = {\n collectionSlug?: string\n versionsFields?: FlattenedField[]\n}\n\nexport type BuildQueryArgs = {\n globalSlug?: string\n locale?: string\n payload: Payload\n where: Where\n}\n\n// This plugin asynchronously builds a list of Mongoose query constraints\n// which can then be used in subsequent Mongoose queries.\n// Deprecated in favor of using simpler buildQuery directly\nexport const getBuildQueryPlugin = ({\n collectionSlug,\n versionsFields,\n}: GetBuildQueryPluginArgs = {}) => {\n return function buildQueryPlugin(schema: any) {\n const modifiedSchema = schema\n async function schemaBuildQuery({\n globalSlug,\n locale,\n payload,\n where,\n }: BuildQueryArgs): Promise<Record<string, unknown>> {\n let fields: FlattenedField[] | null = null\n\n if (versionsFields) {\n fields = versionsFields\n } else {\n if (globalSlug) {\n const globalConfig = payload.globals.config.find(({ slug }) => slug === globalSlug)\n\n if (!globalConfig) {\n throw new APIError(`Global with the slug ${globalSlug} was not found`)\n }\n\n fields = globalConfig.flattenedFields\n }\n if (collectionSlug) {\n const collectionConfig = payload.collections[collectionSlug]?.config\n\n if (!collectionConfig) {\n throw new APIError(`Collection with the slug ${globalSlug} was not found`)\n }\n\n fields = collectionConfig.flattenedFields\n }\n }\n\n if (fields === null) {\n throw new APIError('Fields are not initialized.')\n }\n\n const result = await parseParams({\n collectionSlug,\n fields,\n globalSlug,\n locale,\n parentIsLocalized: false,\n payload,\n where,\n })\n\n return result\n }\n modifiedSchema.statics.buildQuery = schemaBuildQuery\n }\n}\n"],"names":["APIError","parseParams","getBuildQueryPlugin","collectionSlug","versionsFields","buildQueryPlugin","schema","modifiedSchema","schemaBuildQuery","globalSlug","locale","payload","where","fields","globalConfig","globals","config","find","slug","flattenedFields","collectionConfig","collections","result","parentIsLocalized","statics","buildQuery"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,UAAS;AAElC,SAASC,WAAW,QAAQ,mBAAkB;AAc9C,yEAAyE;AACzE,yDAAyD;AACzD,2DAA2D;AAC3D,OAAO,MAAMC,sBAAsB,CAAC,EAClCC,cAAc,EACdC,cAAc,EACU,GAAG,CAAC,CAAC;IAC7B,OAAO,SAASC,iBAAiBC,MAAW;QAC1C,MAAMC,iBAAiBD;QACvB,eAAeE,iBAAiB,EAC9BC,UAAU,EACVC,MAAM,EACNC,OAAO,EACPC,KAAK,EACU;YACf,IAAIC,SAAkC;YAEtC,IAAIT,gBAAgB;gBAClBS,SAAST;YACX,OAAO;gBACL,IAAIK,YAAY;oBACd,MAAMK,eAAeH,QAAQI,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC,CAAC,EAAEC,IAAI,EAAE,GAAKA,SAAST;oBAExE,IAAI,CAACK,cAAc;wBACjB,MAAM,IAAId,SAAS,CAAC,qBAAqB,EAAES,WAAW,cAAc,CAAC;oBACvE;oBAEAI,SAASC,aAAaK,eAAe;gBACvC;gBACA,IAAIhB,gBAAgB;oBAClB,MAAMiB,mBAAmBT,QAAQU,WAAW,CAAClB,eAAe,EAAEa;oBAE9D,IAAI,CAACI,kBAAkB;wBACrB,MAAM,IAAIpB,SAAS,CAAC,yBAAyB,EAAES,WAAW,cAAc,CAAC;oBAC3E;oBAEAI,SAASO,iBAAiBD,eAAe;gBAC3C;YACF;YAEA,IAAIN,WAAW,MAAM;gBACnB,MAAM,IAAIb,SAAS;YACrB;YAEA,MAAMsB,SAAS,MAAMrB,YAAY;gBAC/BE;gBACAU;gBACAJ;gBACAC;gBACAa,mBAAmB;gBACnBZ;gBACAC;YACF;YAEA,OAAOU;QACT;QACAf,eAAeiB,OAAO,CAACC,UAAU,GAAGjB;IACtC;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/queries/getBuildQueryPlugin.ts"],"sourcesContent":["import type { FlattenedField, Payload, PayloadRequest, Where } from 'payload'\n\nimport { APIError } from 'payload'\n\nimport { parseParams } from './parseParams.js'\n\ntype GetBuildQueryPluginArgs = {\n collectionSlug?: string\n versionsFields?: FlattenedField[]\n}\n\nexport type BuildQueryArgs = {\n branch?: false | string\n globalSlug?: string\n locale?: string\n payload: Payload\n req?: Partial<PayloadRequest>\n where: Where\n}\n\n// This plugin asynchronously builds a list of Mongoose query constraints\n// which can then be used in subsequent Mongoose queries.\n// Deprecated in favor of using simpler buildQuery directly\nexport const getBuildQueryPlugin = ({\n collectionSlug,\n versionsFields,\n}: GetBuildQueryPluginArgs = {}) => {\n return function buildQueryPlugin(schema: any) {\n const modifiedSchema = schema\n async function schemaBuildQuery({\n branch,\n globalSlug,\n locale,\n payload,\n req,\n where,\n }: BuildQueryArgs): Promise<Record<string, unknown>> {\n let fields: FlattenedField[] | null = null\n\n if (versionsFields) {\n fields = versionsFields\n } else {\n if (globalSlug) {\n const globalConfig = payload.globals.config.find(({ slug }) => slug === globalSlug)\n\n if (!globalConfig) {\n throw new APIError(`Global with the slug ${globalSlug} was not found`)\n }\n\n fields = globalConfig.flattenedFields\n }\n if (collectionSlug) {\n const collectionConfig = payload.collections[collectionSlug]?.config\n\n if (!collectionConfig) {\n throw new APIError(`Collection with the slug ${globalSlug} was not found`)\n }\n\n fields = collectionConfig.flattenedFields\n }\n }\n\n if (fields === null) {\n throw new APIError('Fields are not initialized.')\n }\n\n const result = await parseParams({\n branch,\n collectionSlug,\n fields,\n globalSlug,\n locale,\n parentIsLocalized: false,\n payload,\n req,\n where,\n })\n\n return result\n }\n modifiedSchema.statics.buildQuery = schemaBuildQuery\n }\n}\n"],"names":["APIError","parseParams","getBuildQueryPlugin","collectionSlug","versionsFields","buildQueryPlugin","schema","modifiedSchema","schemaBuildQuery","branch","globalSlug","locale","payload","req","where","fields","globalConfig","globals","config","find","slug","flattenedFields","collectionConfig","collections","result","parentIsLocalized","statics","buildQuery"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,UAAS;AAElC,SAASC,WAAW,QAAQ,mBAAkB;AAgB9C,yEAAyE;AACzE,yDAAyD;AACzD,2DAA2D;AAC3D,OAAO,MAAMC,sBAAsB,CAAC,EAClCC,cAAc,EACdC,cAAc,EACU,GAAG,CAAC,CAAC;IAC7B,OAAO,SAASC,iBAAiBC,MAAW;QAC1C,MAAMC,iBAAiBD;QACvB,eAAeE,iBAAiB,EAC9BC,MAAM,EACNC,UAAU,EACVC,MAAM,EACNC,OAAO,EACPC,GAAG,EACHC,KAAK,EACU;YACf,IAAIC,SAAkC;YAEtC,IAAIX,gBAAgB;gBAClBW,SAASX;YACX,OAAO;gBACL,IAAIM,YAAY;oBACd,MAAMM,eAAeJ,QAAQK,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC,CAAC,EAAEC,IAAI,EAAE,GAAKA,SAASV;oBAExE,IAAI,CAACM,cAAc;wBACjB,MAAM,IAAIhB,SAAS,CAAC,qBAAqB,EAAEU,WAAW,cAAc,CAAC;oBACvE;oBAEAK,SAASC,aAAaK,eAAe;gBACvC;gBACA,IAAIlB,gBAAgB;oBAClB,MAAMmB,mBAAmBV,QAAQW,WAAW,CAACpB,eAAe,EAAEe;oBAE9D,IAAI,CAACI,kBAAkB;wBACrB,MAAM,IAAItB,SAAS,CAAC,yBAAyB,EAAEU,WAAW,cAAc,CAAC;oBAC3E;oBAEAK,SAASO,iBAAiBD,eAAe;gBAC3C;YACF;YAEA,IAAIN,WAAW,MAAM;gBACnB,MAAM,IAAIf,SAAS;YACrB;YAEA,MAAMwB,SAAS,MAAMvB,YAAY;gBAC/BQ;gBACAN;gBACAY;gBACAL;gBACAC;gBACAc,mBAAmB;gBACnBb;gBACAC;gBACAC;YACF;YAEA,OAAOU;QACT;QACAjB,eAAemB,OAAO,CAACC,UAAU,GAAGnB;IACtC;AACF,EAAC"}