payload 3.80.0-internal.cdd7ef7 → 3.80.0

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 (265) hide show
  1. package/dist/admin/elements/Nav.d.ts +0 -13
  2. package/dist/admin/elements/Nav.d.ts.map +1 -1
  3. package/dist/admin/elements/Nav.js.map +1 -1
  4. package/dist/admin/functions/index.d.ts +38 -1
  5. package/dist/admin/functions/index.d.ts.map +1 -1
  6. package/dist/admin/functions/index.js.map +1 -1
  7. package/dist/admin/types.d.ts +4 -5
  8. package/dist/admin/types.d.ts.map +1 -1
  9. package/dist/admin/types.js.map +1 -1
  10. package/dist/admin/views/folderList.d.ts +56 -0
  11. package/dist/admin/views/folderList.d.ts.map +1 -0
  12. package/dist/admin/views/folderList.js +3 -0
  13. package/dist/admin/views/folderList.js.map +1 -0
  14. package/dist/admin/views/index.d.ts +3 -1
  15. package/dist/admin/views/index.d.ts.map +1 -1
  16. package/dist/admin/views/index.js.map +1 -1
  17. package/dist/admin/views/list.d.ts +2 -43
  18. package/dist/admin/views/list.d.ts.map +1 -1
  19. package/dist/admin/views/list.js.map +1 -1
  20. package/dist/bin/generateImportMap/iterateCollections.d.ts.map +1 -1
  21. package/dist/bin/generateImportMap/iterateCollections.js +0 -1
  22. package/dist/bin/generateImportMap/iterateCollections.js.map +1 -1
  23. package/dist/bin/generateImportMap/iterateConfig.d.ts.map +1 -1
  24. package/dist/bin/generateImportMap/iterateConfig.js +0 -7
  25. package/dist/bin/generateImportMap/iterateConfig.js.map +1 -1
  26. package/dist/collections/config/client.d.ts +1 -3
  27. package/dist/collections/config/client.d.ts.map +1 -1
  28. package/dist/collections/config/client.js +0 -11
  29. package/dist/collections/config/client.js.map +1 -1
  30. package/dist/collections/config/defaults.js +1 -1
  31. package/dist/collections/config/defaults.js.map +1 -1
  32. package/dist/collections/config/sanitize.d.ts.map +1 -1
  33. package/dist/collections/config/sanitize.js +7 -3
  34. package/dist/collections/config/sanitize.js.map +1 -1
  35. package/dist/collections/config/types.d.ts +7 -29
  36. package/dist/collections/config/types.d.ts.map +1 -1
  37. package/dist/collections/config/types.js.map +1 -1
  38. package/dist/collections/operations/create.js +17 -17
  39. package/dist/collections/operations/create.js.map +1 -1
  40. package/dist/collections/operations/findByID.js +3 -3
  41. package/dist/collections/operations/findByID.js.map +1 -1
  42. package/dist/collections/operations/update.js +1 -1
  43. package/dist/collections/operations/update.js.map +1 -1
  44. package/dist/collections/operations/utilities/update.d.ts.map +1 -1
  45. package/dist/collections/operations/utilities/update.js +6 -6
  46. package/dist/collections/operations/utilities/update.js.map +1 -1
  47. package/dist/config/client.d.ts.map +1 -1
  48. package/dist/config/client.js +10 -0
  49. package/dist/config/client.js.map +1 -1
  50. package/dist/config/defaults.d.ts.map +1 -1
  51. package/dist/config/defaults.js +15 -0
  52. package/dist/config/defaults.js.map +1 -1
  53. package/dist/config/sanitize.d.ts.map +1 -1
  54. package/dist/config/sanitize.js +26 -3
  55. package/dist/config/sanitize.js.map +1 -1
  56. package/dist/config/types.d.ts +12 -26
  57. package/dist/config/types.d.ts.map +1 -1
  58. package/dist/config/types.js.map +1 -1
  59. package/dist/exports/shared.d.ts +3 -2
  60. package/dist/exports/shared.d.ts.map +1 -1
  61. package/dist/exports/shared.js +2 -1
  62. package/dist/exports/shared.js.map +1 -1
  63. package/dist/fields/baseFields/slug/index.d.ts +7 -0
  64. package/dist/fields/baseFields/slug/index.d.ts.map +1 -1
  65. package/dist/fields/baseFields/slug/index.js +2 -2
  66. package/dist/fields/baseFields/slug/index.js.map +1 -1
  67. package/dist/fields/config/sanitize.d.ts.map +1 -1
  68. package/dist/fields/config/sanitize.js +0 -4
  69. package/dist/fields/config/sanitize.js.map +1 -1
  70. package/dist/fields/config/sanitizeJoinField.d.ts.map +1 -1
  71. package/dist/fields/config/sanitizeJoinField.js +0 -3
  72. package/dist/fields/config/sanitizeJoinField.js.map +1 -1
  73. package/dist/folders/addFolderCollection.d.ts +10 -0
  74. package/dist/folders/addFolderCollection.d.ts.map +1 -0
  75. package/dist/folders/addFolderCollection.js +26 -0
  76. package/dist/folders/addFolderCollection.js.map +1 -0
  77. package/dist/folders/addFolderFieldToCollection.d.ts +8 -0
  78. package/dist/folders/addFolderFieldToCollection.d.ts.map +1 -0
  79. package/dist/folders/addFolderFieldToCollection.js +20 -0
  80. package/dist/folders/addFolderFieldToCollection.js.map +1 -0
  81. package/dist/folders/buildFolderField.d.ts +8 -0
  82. package/dist/folders/buildFolderField.d.ts.map +1 -0
  83. package/dist/folders/buildFolderField.js +87 -0
  84. package/dist/folders/buildFolderField.js.map +1 -0
  85. package/dist/folders/constants.d.ts +3 -0
  86. package/dist/folders/constants.d.ts.map +1 -0
  87. package/dist/folders/constants.js +4 -0
  88. package/dist/folders/constants.js.map +1 -0
  89. package/dist/folders/createFolderCollection.d.ts +11 -0
  90. package/dist/folders/createFolderCollection.d.ts.map +1 -0
  91. package/dist/folders/createFolderCollection.js +115 -0
  92. package/dist/folders/createFolderCollection.js.map +1 -0
  93. package/dist/folders/hooks/deleteSubfoldersAfterDelete.d.ts +8 -0
  94. package/dist/folders/hooks/deleteSubfoldersAfterDelete.d.ts.map +1 -0
  95. package/dist/folders/hooks/deleteSubfoldersAfterDelete.js +15 -0
  96. package/dist/folders/hooks/deleteSubfoldersAfterDelete.js.map +1 -0
  97. package/dist/folders/hooks/dissasociateAfterDelete.d.ts +8 -0
  98. package/dist/folders/hooks/dissasociateAfterDelete.d.ts.map +1 -0
  99. package/dist/folders/hooks/dissasociateAfterDelete.js +20 -0
  100. package/dist/folders/hooks/dissasociateAfterDelete.js.map +1 -0
  101. package/dist/folders/hooks/ensureSafeCollectionsChange.d.ts +5 -0
  102. package/dist/folders/hooks/ensureSafeCollectionsChange.d.ts.map +1 -0
  103. package/dist/folders/hooks/ensureSafeCollectionsChange.js +107 -0
  104. package/dist/folders/hooks/ensureSafeCollectionsChange.js.map +1 -0
  105. package/dist/folders/hooks/reparentChildFolder.d.ts +24 -0
  106. package/dist/folders/hooks/reparentChildFolder.d.ts.map +1 -0
  107. package/dist/folders/hooks/reparentChildFolder.js +72 -0
  108. package/dist/folders/hooks/reparentChildFolder.js.map +1 -0
  109. package/dist/folders/types.d.ts +118 -0
  110. package/dist/folders/types.d.ts.map +1 -0
  111. package/dist/folders/types.js +3 -0
  112. package/dist/folders/types.js.map +1 -0
  113. package/dist/folders/utils/buildFolderWhereConstraints.d.ts +13 -0
  114. package/dist/folders/utils/buildFolderWhereConstraints.d.ts.map +1 -0
  115. package/dist/folders/utils/buildFolderWhereConstraints.js +45 -0
  116. package/dist/folders/utils/buildFolderWhereConstraints.js.map +1 -0
  117. package/dist/folders/utils/formatFolderOrDocumentItem.d.ts +12 -0
  118. package/dist/folders/utils/formatFolderOrDocumentItem.d.ts.map +1 -0
  119. package/dist/folders/utils/formatFolderOrDocumentItem.js +30 -0
  120. package/dist/folders/utils/formatFolderOrDocumentItem.js.map +1 -0
  121. package/dist/folders/utils/getFolderBreadcrumbs.d.ts +14 -0
  122. package/dist/folders/utils/getFolderBreadcrumbs.d.ts.map +1 -0
  123. package/dist/folders/utils/getFolderBreadcrumbs.js +45 -0
  124. package/dist/folders/utils/getFolderBreadcrumbs.js.map +1 -0
  125. package/dist/folders/utils/getFolderData.d.ts +33 -0
  126. package/dist/folders/utils/getFolderData.d.ts.map +1 -0
  127. package/dist/folders/utils/getFolderData.js +88 -0
  128. package/dist/folders/utils/getFolderData.js.map +1 -0
  129. package/dist/folders/utils/getFoldersAndDocumentsFromJoin.d.ts +24 -0
  130. package/dist/folders/utils/getFoldersAndDocumentsFromJoin.d.ts.map +1 -0
  131. package/dist/folders/utils/getFoldersAndDocumentsFromJoin.js +66 -0
  132. package/dist/folders/utils/getFoldersAndDocumentsFromJoin.js.map +1 -0
  133. package/dist/folders/utils/getOrphanedDocs.d.ts +15 -0
  134. package/dist/folders/utils/getOrphanedDocs.d.ts.map +1 -0
  135. package/dist/folders/utils/getOrphanedDocs.js +40 -0
  136. package/dist/folders/utils/getOrphanedDocs.js.map +1 -0
  137. package/dist/globals/config/types.d.ts +0 -4
  138. package/dist/globals/config/types.d.ts.map +1 -1
  139. package/dist/globals/config/types.js.map +1 -1
  140. package/dist/globals/operations/update.d.ts.map +1 -1
  141. package/dist/globals/operations/update.js +2 -1
  142. package/dist/globals/operations/update.js.map +1 -1
  143. package/dist/index.bundled.d.ts +288 -577
  144. package/dist/index.d.ts +9 -23
  145. package/dist/index.d.ts.map +1 -1
  146. package/dist/index.js +5 -13
  147. package/dist/index.js.map +1 -1
  148. package/dist/preferences/keys.d.ts +4 -8
  149. package/dist/preferences/keys.d.ts.map +1 -1
  150. package/dist/preferences/keys.js +4 -7
  151. package/dist/preferences/keys.js.map +1 -1
  152. package/dist/types/index.d.ts +0 -1
  153. package/dist/types/index.d.ts.map +1 -1
  154. package/dist/types/index.js.map +1 -1
  155. package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
  156. package/dist/utilities/addDataAndFileToRequest.js +7 -1
  157. package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
  158. package/dist/utilities/extractID.js +1 -1
  159. package/dist/utilities/extractID.js.map +1 -1
  160. package/dist/utilities/formatAdminURL.d.ts +2 -13
  161. package/dist/utilities/formatAdminURL.d.ts.map +1 -1
  162. package/dist/utilities/formatAdminURL.js.map +1 -1
  163. package/dist/versions/saveVersion.d.ts +1 -0
  164. package/dist/versions/saveVersion.d.ts.map +1 -1
  165. package/dist/versions/saveVersion.js +16 -66
  166. package/dist/versions/saveVersion.js.map +1 -1
  167. package/dist/versions/updateLatestVersion.d.ts +24 -0
  168. package/dist/versions/updateLatestVersion.d.ts.map +1 -0
  169. package/dist/versions/updateLatestVersion.js +64 -0
  170. package/dist/versions/updateLatestVersion.js.map +1 -0
  171. package/package.json +4 -4
  172. package/dist/admin/views/hierarchyList.d.ts +0 -9
  173. package/dist/admin/views/hierarchyList.d.ts.map +0 -1
  174. package/dist/admin/views/hierarchyList.js +0 -3
  175. package/dist/admin/views/hierarchyList.js.map +0 -1
  176. package/dist/hierarchy/addHierarchyToCollection.d.ts +0 -8
  177. package/dist/hierarchy/addHierarchyToCollection.d.ts.map +0 -1
  178. package/dist/hierarchy/addHierarchyToCollection.js +0 -62
  179. package/dist/hierarchy/addHierarchyToCollection.js.map +0 -1
  180. package/dist/hierarchy/buildParentField.d.ts +0 -11
  181. package/dist/hierarchy/buildParentField.d.ts.map +0 -1
  182. package/dist/hierarchy/buildParentField.js +0 -42
  183. package/dist/hierarchy/buildParentField.js.map +0 -1
  184. package/dist/hierarchy/constants.d.ts +0 -15
  185. package/dist/hierarchy/constants.d.ts.map +0 -1
  186. package/dist/hierarchy/constants.js +0 -11
  187. package/dist/hierarchy/constants.js.map +0 -1
  188. package/dist/hierarchy/createFolderField.d.ts +0 -39
  189. package/dist/hierarchy/createFolderField.d.ts.map +0 -1
  190. package/dist/hierarchy/createFolderField.js +0 -54
  191. package/dist/hierarchy/createFolderField.js.map +0 -1
  192. package/dist/hierarchy/createFoldersCollection.d.ts +0 -57
  193. package/dist/hierarchy/createFoldersCollection.d.ts.map +0 -1
  194. package/dist/hierarchy/createFoldersCollection.js +0 -63
  195. package/dist/hierarchy/createFoldersCollection.js.map +0 -1
  196. package/dist/hierarchy/createTagField.d.ts +0 -44
  197. package/dist/hierarchy/createTagField.d.ts.map +0 -1
  198. package/dist/hierarchy/createTagField.js +0 -48
  199. package/dist/hierarchy/createTagField.js.map +0 -1
  200. package/dist/hierarchy/createTagsCollection.d.ts +0 -54
  201. package/dist/hierarchy/createTagsCollection.d.ts.map +0 -1
  202. package/dist/hierarchy/createTagsCollection.js +0 -56
  203. package/dist/hierarchy/createTagsCollection.js.map +0 -1
  204. package/dist/hierarchy/getInitialTreeData.d.ts +0 -27
  205. package/dist/hierarchy/getInitialTreeData.d.ts.map +0 -1
  206. package/dist/hierarchy/getInitialTreeData.js +0 -125
  207. package/dist/hierarchy/getInitialTreeData.js.map +0 -1
  208. package/dist/hierarchy/hooks/collectionAfterDelete.d.ts +0 -14
  209. package/dist/hierarchy/hooks/collectionAfterDelete.d.ts.map +0 -1
  210. package/dist/hierarchy/hooks/collectionAfterDelete.js +0 -21
  211. package/dist/hierarchy/hooks/collectionAfterDelete.js.map +0 -1
  212. package/dist/hierarchy/hooks/collectionAfterRead.d.ts +0 -27
  213. package/dist/hierarchy/hooks/collectionAfterRead.d.ts.map +0 -1
  214. package/dist/hierarchy/hooks/collectionAfterRead.js +0 -64
  215. package/dist/hierarchy/hooks/collectionAfterRead.js.map +0 -1
  216. package/dist/hierarchy/hooks/collectionBeforeChange.d.ts +0 -19
  217. package/dist/hierarchy/hooks/collectionBeforeChange.d.ts.map +0 -1
  218. package/dist/hierarchy/hooks/collectionBeforeChange.js +0 -90
  219. package/dist/hierarchy/hooks/collectionBeforeChange.js.map +0 -1
  220. package/dist/hierarchy/hooks/collectionBeforeDelete.d.ts +0 -15
  221. package/dist/hierarchy/hooks/collectionBeforeDelete.d.ts.map +0 -1
  222. package/dist/hierarchy/hooks/collectionBeforeDelete.js +0 -20
  223. package/dist/hierarchy/hooks/collectionBeforeDelete.js.map +0 -1
  224. package/dist/hierarchy/hooks/ensureSafeCollectionsChange.d.ts +0 -8
  225. package/dist/hierarchy/hooks/ensureSafeCollectionsChange.d.ts.map +0 -1
  226. package/dist/hierarchy/hooks/ensureSafeCollectionsChange.js +0 -108
  227. package/dist/hierarchy/hooks/ensureSafeCollectionsChange.js.map +0 -1
  228. package/dist/hierarchy/injectHierarchyButton.d.ts +0 -14
  229. package/dist/hierarchy/injectHierarchyButton.d.ts.map +0 -1
  230. package/dist/hierarchy/injectHierarchyButton.js +0 -37
  231. package/dist/hierarchy/injectHierarchyButton.js.map +0 -1
  232. package/dist/hierarchy/resolveHierarchyCollections.d.ts +0 -23
  233. package/dist/hierarchy/resolveHierarchyCollections.d.ts.map +0 -1
  234. package/dist/hierarchy/resolveHierarchyCollections.js +0 -312
  235. package/dist/hierarchy/resolveHierarchyCollections.js.map +0 -1
  236. package/dist/hierarchy/sanitizeHierarchyCollection.d.ts +0 -14
  237. package/dist/hierarchy/sanitizeHierarchyCollection.d.ts.map +0 -1
  238. package/dist/hierarchy/sanitizeHierarchyCollection.js +0 -112
  239. package/dist/hierarchy/sanitizeHierarchyCollection.js.map +0 -1
  240. package/dist/hierarchy/types.d.ts +0 -137
  241. package/dist/hierarchy/types.d.ts.map +0 -1
  242. package/dist/hierarchy/types.js +0 -6
  243. package/dist/hierarchy/types.js.map +0 -1
  244. package/dist/hierarchy/utils/buildLocalizedHierarchyPaths.d.ts +0 -71
  245. package/dist/hierarchy/utils/buildLocalizedHierarchyPaths.d.ts.map +0 -1
  246. package/dist/hierarchy/utils/buildLocalizedHierarchyPaths.js +0 -65
  247. package/dist/hierarchy/utils/buildLocalizedHierarchyPaths.js.map +0 -1
  248. package/dist/hierarchy/utils/computePaths.d.ts +0 -31
  249. package/dist/hierarchy/utils/computePaths.d.ts.map +0 -1
  250. package/dist/hierarchy/utils/computePaths.js +0 -371
  251. package/dist/hierarchy/utils/computePaths.js.map +0 -1
  252. package/dist/hierarchy/utils/findUseAsTitle.d.ts +0 -6
  253. package/dist/hierarchy/utils/findUseAsTitle.d.ts.map +0 -1
  254. package/dist/hierarchy/utils/findUseAsTitle.js +0 -72
  255. package/dist/hierarchy/utils/findUseAsTitle.js.map +0 -1
  256. package/dist/hierarchy/utils/getAncestors.d.ts +0 -34
  257. package/dist/hierarchy/utils/getAncestors.d.ts.map +0 -1
  258. package/dist/hierarchy/utils/getAncestors.js +0 -94
  259. package/dist/hierarchy/utils/getAncestors.js.map +0 -1
  260. package/dist/hierarchy/utils/getLocalizedValue.d.ts +0 -30
  261. package/dist/hierarchy/utils/getLocalizedValue.d.ts.map +0 -1
  262. package/dist/hierarchy/utils/getLocalizedValue.js +0 -46
  263. package/dist/hierarchy/utils/getLocalizedValue.js.map +0 -1
  264. package/dist/hierarchy/utils/getLocalizedValue.spec.js +0 -250
  265. package/dist/hierarchy/utils/getLocalizedValue.spec.js.map +0 -1
@@ -1,371 +0,0 @@
1
- import { slugify as payloadSlugify } from '../../utilities/slugify.js';
2
- import { HIERARCHY_SLUG_PATH_FIELD, HIERARCHY_TITLE_PATH_FIELD } from '../constants.js';
3
- import { buildLocalizedHierarchyPaths } from './buildLocalizedHierarchyPaths.js';
4
- import { findUseAsTitleField } from './findUseAsTitle.js';
5
- import { getLocalizedValue } from './getLocalizedValue.js';
6
- // Helper to get title value - returns string for single locale, object for 'all' locales
7
- const getTitleValue = ({ document, isTitleLocalized = false, locale, req, titleFieldName })=>{
8
- const titleValue = document[titleFieldName];
9
- if (!titleValue) {
10
- return document.id?.toString() || 'untitled';
11
- }
12
- // If field is localized and we want all locales, return the full object
13
- if (isTitleLocalized && locale === 'all' && typeof titleValue === 'object') {
14
- return titleValue;
15
- }
16
- // Single locale - use getLocalizedValue to handle fallback
17
- if (isTitleLocalized && typeof titleValue === 'object') {
18
- const localizedValue = getLocalizedValue({
19
- fallbackLocale: req.fallbackLocale,
20
- fieldType: 'text',
21
- locale: locale || req.locale || 'en',
22
- value: titleValue
23
- });
24
- return localizedValue || document.id?.toString() || 'untitled';
25
- }
26
- return titleValue;
27
- };
28
- /**
29
- * Computes both slug and title breadcrumb paths for a document by walking up the parent chain.
30
- * More efficient than computing them separately since it only walks the chain once.
31
- *
32
- * Note: Ancestor fetches always use `overrideAccess: true` to ensure paths are complete.
33
- * If a user can read a document, they should see its full breadcrumb path even if they
34
- * cannot read all ancestor documents. This prevents broken breadcrumbs and provides
35
- * better UX at the cost of minimal information leakage (ancestor titles in paths).
36
- *
37
- * @param args - Configuration for path computation
38
- * @returns Object with slugPath and titlePath
39
- */ export async function computePaths(args) {
40
- const { collection, doc, draft = false, locale, parentFieldName, req, slugPathFieldName = HIERARCHY_SLUG_PATH_FIELD, titlePathFieldName = HIERARCHY_TITLE_PATH_FIELD } = args;
41
- const slugify = collection.hierarchy !== false && collection.hierarchy.slugify || ((text)=>payloadSlugify(text) || '');
42
- const { localized: isTitleLocalized, titleFieldName } = findUseAsTitleField(collection);
43
- // Initialize cache if it doesn't exist
44
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
- const context = req.context;
46
- if (!context.hierarchyAncestorCache) {
47
- context.hierarchyAncestorCache = {};
48
- }
49
- if (!context.hierarchyAncestorCache[collection.slug]) {
50
- context.hierarchyAncestorCache[collection.slug] = {};
51
- }
52
- // Initialize cache stats if debug is enabled
53
- if (req.payload.config.debug && !context.hierarchyCacheStats) {
54
- context.hierarchyCacheStats = {
55
- hits: 0,
56
- misses: 0,
57
- queries: 0
58
- };
59
- }
60
- const parentValue = doc[parentFieldName];
61
- let parentID;
62
- if (!parentValue) {
63
- // No parent - root document
64
- parentID = undefined;
65
- } else {
66
- // Extract ID from parent value
67
- // Parent can be:
68
- // - Plain ID (string/number)
69
- // - Populated object with { id: ... }
70
- if (typeof parentValue === 'object' && 'id' in parentValue) {
71
- parentID = parentValue.id;
72
- } else {
73
- parentID = parentValue;
74
- }
75
- }
76
- if (parentID) {
77
- // Parent is always from the same collection (self-referential)
78
- const parentCollectionConfig = collection;
79
- const parentHierarchyConfig = parentCollectionConfig.hierarchy;
80
- // If parent collection doesn't have hierarchy, we can't compute paths through it
81
- if (!parentHierarchyConfig || !parentCollectionConfig) {
82
- const titleValue = getTitleValue({
83
- document: doc,
84
- isTitleLocalized,
85
- locale,
86
- req,
87
- titleFieldName
88
- });
89
- if (isTitleLocalized && locale === 'all') {
90
- return buildLocalizedHierarchyPaths({
91
- req,
92
- slugify,
93
- titleValue: titleValue
94
- });
95
- }
96
- return {
97
- slugPath: slugify(titleValue),
98
- titlePath: titleValue
99
- };
100
- }
101
- // Initialize cache for parent collection if needed
102
- if (!context.hierarchyAncestorCache[collection.slug]) {
103
- context.hierarchyAncestorCache[collection.slug] = {};
104
- }
105
- const cache = context.hierarchyAncestorCache[collection.slug];
106
- const cacheKey = `${parentID}_${locale || 'default'}`;
107
- // Check cache first
108
- let parent = cache[cacheKey];
109
- if (parent) {
110
- // Cache hit
111
- if (context.hierarchyCacheStats) {
112
- context.hierarchyCacheStats.hits += 1;
113
- }
114
- } else {
115
- // Cache miss - fetch parent
116
- if (context.hierarchyCacheStats) {
117
- context.hierarchyCacheStats.misses += 1;
118
- context.hierarchyCacheStats.queries += 1;
119
- }
120
- const parentTitleField = findUseAsTitleField(parentCollectionConfig).titleFieldName;
121
- // parentID is guaranteed to be defined here (we're inside if (parentID))
122
- const validParentID = parentID;
123
- // Create new context with computeHierarchyPaths enabled to trigger recursive path computation
124
- const parentReq = {
125
- ...req,
126
- context: {
127
- ...req.context,
128
- computeHierarchyPaths: true
129
- }
130
- };
131
- // Fetch parent
132
- // When locale === 'all', we need special handling because Payload doesn't support
133
- // fetching all locales of a draft document (drafts are stored per-locale).
134
- // Strategy: Try published first, fallback to fetching each locale separately for drafts.
135
- const fetchParent = async ()=>{
136
- if (locale === 'all') {
137
- try {
138
- // First try to fetch published version with all locales
139
- return await req.payload.findByID({
140
- id: validParentID,
141
- collection: collection.slug,
142
- depth: 0,
143
- locale,
144
- overrideAccess: true,
145
- req: parentReq,
146
- select: {
147
- [parentHierarchyConfig.parentFieldName]: true,
148
- [parentHierarchyConfig.slugPathFieldName]: true,
149
- [parentHierarchyConfig.titlePathFieldName]: true,
150
- [parentTitleField]: true
151
- },
152
- user: req.user
153
- });
154
- } catch (_error) {
155
- // Published version not found, must be a draft
156
- // Payload doesn't support fetching all locales of a draft with a single query
157
- // So we need to fetch each locale separately and combine the path data
158
- const locales = req.payload.config.localization ? req.payload.config.localization.localeCodes : [];
159
- const parentPathsByLocale = {};
160
- // Get parent collection's slugify function (may differ from child's)
161
- const parentSlugify = parentCollectionConfig.hierarchy !== false && parentCollectionConfig.hierarchy.slugify || ((text)=>payloadSlugify(text) || '');
162
- // Fetch parent for each locale to get paths
163
- for (const loc of locales){
164
- // Create a new request with this specific locale but keep computeHierarchyPaths flag
165
- const localeReq = {
166
- ...req,
167
- context: {
168
- ...req.context,
169
- computeHierarchyPaths: true
170
- },
171
- locale: loc
172
- };
173
- try {
174
- const parentForLocale = await req.payload.findByID({
175
- id: validParentID,
176
- collection: collection.slug,
177
- depth: 0,
178
- draft: true,
179
- locale: loc,
180
- overrideAccess: true,
181
- req: localeReq,
182
- user: req.user
183
- });
184
- // Extract the path fields and title from the parent
185
- // If paths weren't computed (undefined), compute them manually for root documents
186
- let parentSlugPath = parentForLocale[parentHierarchyConfig.slugPathFieldName];
187
- let parentTitlePath = parentForLocale[parentHierarchyConfig.titlePathFieldName];
188
- const parentTitle = parentForLocale[parentTitleField];
189
- // If paths are undefined, this might be a root document - compute paths from title
190
- if (!parentSlugPath && parentTitle) {
191
- parentSlugPath = parentSlugify(parentTitle);
192
- }
193
- if (!parentTitlePath && parentTitle) {
194
- parentTitlePath = parentTitle;
195
- }
196
- parentPathsByLocale[loc] = {
197
- slugPath: parentSlugPath,
198
- title: parentTitle,
199
- titlePath: parentTitlePath
200
- };
201
- } catch (localeError) {
202
- // This locale doesn't exist, skip it
203
- }
204
- }
205
- // Combine the path data from all locales into a single parent object
206
- const combinedSlugPaths = {};
207
- const combinedTitlePaths = {};
208
- const combinedTitles = {};
209
- for (const loc of locales){
210
- if (parentPathsByLocale[loc]) {
211
- combinedSlugPaths[loc] = parentPathsByLocale[loc].slugPath;
212
- combinedTitlePaths[loc] = parentPathsByLocale[loc].titlePath;
213
- combinedTitles[loc] = parentPathsByLocale[loc].title;
214
- }
215
- }
216
- // Return a parent object with only the hierarchy fields we need
217
- // (all properly formatted as multi-locale objects)
218
- return {
219
- id: validParentID,
220
- [parentHierarchyConfig.slugPathFieldName]: combinedSlugPaths,
221
- [parentHierarchyConfig.titlePathFieldName]: combinedTitlePaths,
222
- [parentTitleField]: combinedTitles
223
- };
224
- }
225
- } else {
226
- // Normal case: single locale, can pass draft parameter
227
- return await req.payload.findByID({
228
- id: validParentID,
229
- collection: collection.slug,
230
- depth: 0,
231
- draft,
232
- locale,
233
- overrideAccess: true,
234
- req: parentReq,
235
- select: {
236
- [parentHierarchyConfig.parentFieldName]: true,
237
- [parentHierarchyConfig.slugPathFieldName]: true,
238
- [parentHierarchyConfig.titlePathFieldName]: true,
239
- [parentTitleField]: true
240
- },
241
- user: req.user
242
- });
243
- }
244
- };
245
- try {
246
- parent = await fetchParent();
247
- // Store in cache
248
- cache[cacheKey] = parent;
249
- } catch {
250
- // If we can't fetch the parent at all (even with fallbacks), treat this as a root document
251
- // This can happen with complex draft/locale combinations
252
- parentID = undefined;
253
- }
254
- }
255
- // If parent fetch failed, treat as root document
256
- if (!parentID || !parent) {
257
- const titleValue = getTitleValue({
258
- document: doc,
259
- isTitleLocalized,
260
- locale,
261
- req,
262
- titleFieldName
263
- });
264
- if (isTitleLocalized && locale === 'all') {
265
- return buildLocalizedHierarchyPaths({
266
- req,
267
- slugify,
268
- titleValue: titleValue
269
- });
270
- }
271
- return {
272
- slugPath: slugify(titleValue),
273
- titlePath: titleValue
274
- };
275
- }
276
- const docTitle = getTitleValue({
277
- document: doc,
278
- isTitleLocalized,
279
- locale,
280
- req,
281
- titleFieldName
282
- });
283
- // Cache the current document (in its own collection's cache)
284
- const currentDocCacheKey = `${doc.id}_${locale || 'default'}`;
285
- if (!context.hierarchyAncestorCache[collection.slug]) {
286
- context.hierarchyAncestorCache[collection.slug] = {};
287
- }
288
- context.hierarchyAncestorCache[collection.slug][currentDocCacheKey] = {
289
- [parentFieldName]: parentID,
290
- [slugPathFieldName]: undefined,
291
- [titleFieldName]: docTitle,
292
- [titlePathFieldName]: undefined
293
- };
294
- // Get parent's path field names from hierarchy config
295
- const parentSlugPathFieldName = parentCollectionConfig.hierarchy !== false ? parentCollectionConfig.hierarchy.slugPathFieldName : HIERARCHY_SLUG_PATH_FIELD;
296
- const parentTitlePathFieldName = parentCollectionConfig.hierarchy !== false ? parentCollectionConfig.hierarchy.titlePathFieldName : HIERARCHY_TITLE_PATH_FIELD;
297
- // Handle localized case (locale === 'all' with localized title field)
298
- if (isTitleLocalized && locale === 'all') {
299
- // Parent might have non-localized title field, resulting in string paths instead of objects
300
- // Convert parent paths to objects if they're strings (use same value for all locales)
301
- let parentSlugPathObj = parent[parentSlugPathFieldName];
302
- let parentTitlePathObj = parent[parentTitlePathFieldName];
303
- // If parent paths are strings (non-localized parent), convert to objects for all locales
304
- if (typeof parentSlugPathObj === 'string') {
305
- const locales = req.payload.config.localization ? req.payload.config.localization.localeCodes : [];
306
- const slugValue = parentSlugPathObj;
307
- parentSlugPathObj = {};
308
- for (const loc of locales){
309
- parentSlugPathObj[loc] = slugValue;
310
- }
311
- }
312
- if (typeof parentTitlePathObj === 'string') {
313
- const locales = req.payload.config.localization ? req.payload.config.localization.localeCodes : [];
314
- const titleValue = parentTitlePathObj;
315
- parentTitlePathObj = {};
316
- for (const loc of locales){
317
- parentTitlePathObj[loc] = titleValue;
318
- }
319
- }
320
- // If parent paths are undefined (parent fetch failed or paths not computed),
321
- // buildLocalizedHierarchyPaths will handle it by using just the child's title
322
- const result = buildLocalizedHierarchyPaths({
323
- parentSlugPath: parentSlugPathObj,
324
- parentTitlePath: parentTitlePathObj,
325
- req,
326
- slugify,
327
- titleValue: docTitle
328
- });
329
- // Update cache with computed paths
330
- context.hierarchyAncestorCache[collection.slug][currentDocCacheKey][slugPathFieldName] = result.slugPath;
331
- context.hierarchyAncestorCache[collection.slug][currentDocCacheKey][titlePathFieldName] = result.titlePath;
332
- return result;
333
- }
334
- // Single locale case
335
- const result = {
336
- slugPath: parent[parentSlugPathFieldName] + '/' + slugify(docTitle),
337
- titlePath: parent[parentTitlePathFieldName] + '/' + docTitle
338
- };
339
- // Update cache with computed paths
340
- context.hierarchyAncestorCache[collection.slug][currentDocCacheKey][slugPathFieldName] = result.slugPath;
341
- context.hierarchyAncestorCache[collection.slug][currentDocCacheKey][titlePathFieldName] = result.titlePath;
342
- return result;
343
- } else {
344
- const titleValue = getTitleValue({
345
- document: doc,
346
- isTitleLocalized,
347
- locale,
348
- req,
349
- titleFieldName
350
- });
351
- context.hierarchyAncestorCache[collection.slug][doc.id] = {
352
- [parentFieldName]: null,
353
- [titleFieldName]: titleValue
354
- };
355
- // Handle localized case (locale === 'all' with localized title field)
356
- if (isTitleLocalized && locale === 'all') {
357
- return buildLocalizedHierarchyPaths({
358
- req,
359
- slugify,
360
- titleValue: titleValue
361
- });
362
- }
363
- // Single locale case
364
- return {
365
- slugPath: slugify(titleValue),
366
- titlePath: titleValue
367
- };
368
- }
369
- }
370
-
371
- //# sourceMappingURL=computePaths.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/hierarchy/utils/computePaths.ts"],"sourcesContent":["import type { SanitizedCollectionConfig } from '../../collections/config/types.js'\nimport type { Document, PayloadRequest } from '../../types/index.js'\n\nimport { slugify as payloadSlugify } from '../../utilities/slugify.js'\nimport {\n HIERARCHY_DEFAULT_LOCALE,\n HIERARCHY_SLUG_PATH_FIELD,\n HIERARCHY_TITLE_PATH_FIELD,\n} from '../constants.js'\nimport { buildLocalizedHierarchyPaths } from './buildLocalizedHierarchyPaths.js'\nimport { findUseAsTitleField } from './findUseAsTitle.js'\nimport { getLocalizedValue } from './getLocalizedValue.js'\n\ntype ComputePathsArgs = {\n collection: SanitizedCollectionConfig\n doc: Document\n draft?: boolean\n locale?: string\n parentFieldName: string\n req: PayloadRequest\n slugPathFieldName?: string\n titlePathFieldName?: string\n}\n\ntype ComputePathsResult = {\n slugPath: Record<string, string> | string\n titlePath: Record<string, string> | string\n}\n\n// Helper to get title value - returns string for single locale, object for 'all' locales\nconst getTitleValue = ({\n document,\n isTitleLocalized = false,\n locale,\n req,\n titleFieldName,\n}: {\n document: Document\n isTitleLocalized?: boolean\n locale?: string\n req: PayloadRequest\n titleFieldName: string\n}): Record<string, string> | string => {\n const titleValue = document[titleFieldName]\n\n if (!titleValue) {\n return document.id?.toString() || 'untitled'\n }\n\n // If field is localized and we want all locales, return the full object\n if (isTitleLocalized && locale === 'all' && typeof titleValue === 'object') {\n return titleValue\n }\n\n // Single locale - use getLocalizedValue to handle fallback\n if (isTitleLocalized && typeof titleValue === 'object') {\n const localizedValue = getLocalizedValue({\n fallbackLocale: req.fallbackLocale,\n fieldType: 'text',\n locale: locale || req.locale || 'en',\n value: titleValue,\n })\n return localizedValue || document.id?.toString() || 'untitled'\n }\n\n return titleValue\n}\n\n/**\n * Computes both slug and title breadcrumb paths for a document by walking up the parent chain.\n * More efficient than computing them separately since it only walks the chain once.\n *\n * Note: Ancestor fetches always use `overrideAccess: true` to ensure paths are complete.\n * If a user can read a document, they should see its full breadcrumb path even if they\n * cannot read all ancestor documents. This prevents broken breadcrumbs and provides\n * better UX at the cost of minimal information leakage (ancestor titles in paths).\n *\n * @param args - Configuration for path computation\n * @returns Object with slugPath and titlePath\n */\nexport async function computePaths(args: ComputePathsArgs): Promise<ComputePathsResult> {\n const {\n collection,\n doc,\n draft = false,\n locale,\n parentFieldName,\n req,\n slugPathFieldName = HIERARCHY_SLUG_PATH_FIELD,\n titlePathFieldName = HIERARCHY_TITLE_PATH_FIELD,\n } = args\n\n const slugify =\n (collection.hierarchy !== false && collection.hierarchy.slugify) ||\n ((text: string) => payloadSlugify(text) || '')\n const { localized: isTitleLocalized, titleFieldName } = findUseAsTitleField(collection)\n\n // Initialize cache if it doesn't exist\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const context = req.context as any\n if (!context.hierarchyAncestorCache) {\n context.hierarchyAncestorCache = {}\n }\n if (!context.hierarchyAncestorCache[collection.slug]) {\n context.hierarchyAncestorCache[collection.slug] = {}\n }\n\n // Initialize cache stats if debug is enabled\n if (req.payload.config.debug && !context.hierarchyCacheStats) {\n context.hierarchyCacheStats = {\n hits: 0,\n misses: 0,\n queries: 0,\n }\n }\n\n const parentValue = doc[parentFieldName]\n let parentID: number | string | undefined\n\n if (!parentValue) {\n // No parent - root document\n parentID = undefined\n } else {\n // Extract ID from parent value\n // Parent can be:\n // - Plain ID (string/number)\n // - Populated object with { id: ... }\n if (typeof parentValue === 'object' && 'id' in parentValue) {\n parentID = parentValue.id\n } else {\n parentID = parentValue as number | string\n }\n }\n\n if (parentID) {\n // Parent is always from the same collection (self-referential)\n const parentCollectionConfig = collection\n const parentHierarchyConfig = parentCollectionConfig.hierarchy\n\n // If parent collection doesn't have hierarchy, we can't compute paths through it\n if (!parentHierarchyConfig || !parentCollectionConfig) {\n const titleValue = getTitleValue({\n document: doc,\n isTitleLocalized,\n locale,\n req,\n titleFieldName,\n })\n\n if (isTitleLocalized && locale === 'all') {\n return buildLocalizedHierarchyPaths({\n req,\n slugify,\n titleValue: titleValue as Record<string, string>,\n })\n }\n\n return {\n slugPath: slugify(titleValue as string),\n titlePath: titleValue as string,\n }\n }\n\n // Initialize cache for parent collection if needed\n if (!context.hierarchyAncestorCache[collection.slug]) {\n context.hierarchyAncestorCache[collection.slug] = {}\n }\n\n const cache = context.hierarchyAncestorCache[collection.slug]\n const cacheKey = `${parentID}_${locale || 'default'}`\n\n // Check cache first\n let parent = cache[cacheKey]\n\n if (parent) {\n // Cache hit\n if (context.hierarchyCacheStats) {\n context.hierarchyCacheStats.hits += 1\n }\n } else {\n // Cache miss - fetch parent\n if (context.hierarchyCacheStats) {\n context.hierarchyCacheStats.misses += 1\n context.hierarchyCacheStats.queries += 1\n }\n\n const parentTitleField = findUseAsTitleField(parentCollectionConfig).titleFieldName\n\n // parentID is guaranteed to be defined here (we're inside if (parentID))\n const validParentID = parentID\n\n // Create new context with computeHierarchyPaths enabled to trigger recursive path computation\n const parentReq = {\n ...req,\n context: {\n ...req.context,\n computeHierarchyPaths: true,\n },\n }\n\n // Fetch parent\n // When locale === 'all', we need special handling because Payload doesn't support\n // fetching all locales of a draft document (drafts are stored per-locale).\n // Strategy: Try published first, fallback to fetching each locale separately for drafts.\n const fetchParent = async () => {\n if (locale === 'all') {\n try {\n // First try to fetch published version with all locales\n return await req.payload.findByID({\n id: validParentID,\n collection: collection.slug,\n depth: 0,\n locale,\n overrideAccess: true,\n req: parentReq,\n select: {\n [parentHierarchyConfig.parentFieldName]: true,\n [parentHierarchyConfig.slugPathFieldName]: true,\n [parentHierarchyConfig.titlePathFieldName]: true,\n [parentTitleField]: true,\n },\n user: req.user,\n })\n } catch (_error) {\n // Published version not found, must be a draft\n // Payload doesn't support fetching all locales of a draft with a single query\n // So we need to fetch each locale separately and combine the path data\n const locales = req.payload.config.localization\n ? req.payload.config.localization.localeCodes\n : []\n const parentPathsByLocale: Record<\n string,\n { slugPath?: string; title?: string; titlePath?: string }\n > = {}\n\n // Get parent collection's slugify function (may differ from child's)\n const parentSlugify =\n (parentCollectionConfig.hierarchy !== false &&\n parentCollectionConfig.hierarchy.slugify) ||\n ((text: string) => payloadSlugify(text) || '')\n\n // Fetch parent for each locale to get paths\n for (const loc of locales) {\n // Create a new request with this specific locale but keep computeHierarchyPaths flag\n const localeReq = {\n ...req,\n context: {\n ...req.context,\n computeHierarchyPaths: true,\n },\n locale: loc,\n }\n\n try {\n const parentForLocale = await req.payload.findByID({\n id: validParentID,\n collection: collection.slug,\n depth: 0,\n draft: true,\n locale: loc,\n overrideAccess: true,\n req: localeReq,\n user: req.user,\n })\n\n // Extract the path fields and title from the parent\n // If paths weren't computed (undefined), compute them manually for root documents\n let parentSlugPath = parentForLocale[parentHierarchyConfig.slugPathFieldName]\n let parentTitlePath = parentForLocale[parentHierarchyConfig.titlePathFieldName]\n const parentTitle = parentForLocale[parentTitleField]\n\n // If paths are undefined, this might be a root document - compute paths from title\n if (!parentSlugPath && parentTitle) {\n parentSlugPath = parentSlugify(parentTitle)\n }\n if (!parentTitlePath && parentTitle) {\n parentTitlePath = parentTitle\n }\n\n parentPathsByLocale[loc] = {\n slugPath: parentSlugPath,\n title: parentTitle,\n titlePath: parentTitlePath,\n }\n } catch (localeError) {\n // This locale doesn't exist, skip it\n }\n }\n\n // Combine the path data from all locales into a single parent object\n const combinedSlugPaths: Record<string, string | undefined> = {}\n const combinedTitlePaths: Record<string, string | undefined> = {}\n const combinedTitles: Record<string, string | undefined> = {}\n\n for (const loc of locales) {\n if (parentPathsByLocale[loc]) {\n combinedSlugPaths[loc] = parentPathsByLocale[loc].slugPath\n combinedTitlePaths[loc] = parentPathsByLocale[loc].titlePath\n combinedTitles[loc] = parentPathsByLocale[loc].title\n }\n }\n\n // Return a parent object with only the hierarchy fields we need\n // (all properly formatted as multi-locale objects)\n return {\n id: validParentID,\n [parentHierarchyConfig.slugPathFieldName]: combinedSlugPaths,\n [parentHierarchyConfig.titlePathFieldName]: combinedTitlePaths,\n [parentTitleField]: combinedTitles,\n }\n }\n } else {\n // Normal case: single locale, can pass draft parameter\n return await req.payload.findByID({\n id: validParentID,\n collection: collection.slug,\n depth: 0,\n draft,\n locale,\n overrideAccess: true,\n req: parentReq,\n select: {\n [parentHierarchyConfig.parentFieldName]: true,\n [parentHierarchyConfig.slugPathFieldName]: true,\n [parentHierarchyConfig.titlePathFieldName]: true,\n [parentTitleField]: true,\n },\n user: req.user,\n })\n }\n }\n\n try {\n parent = await fetchParent()\n\n // Store in cache\n cache[cacheKey] = parent\n } catch {\n // If we can't fetch the parent at all (even with fallbacks), treat this as a root document\n // This can happen with complex draft/locale combinations\n parentID = undefined\n }\n }\n\n // If parent fetch failed, treat as root document\n if (!parentID || !parent) {\n const titleValue = getTitleValue({\n document: doc,\n isTitleLocalized,\n locale,\n req,\n titleFieldName,\n })\n\n if (isTitleLocalized && locale === 'all') {\n return buildLocalizedHierarchyPaths({\n req,\n slugify,\n titleValue: titleValue as Record<string, string>,\n })\n }\n\n return {\n slugPath: slugify(titleValue as string),\n titlePath: titleValue as string,\n }\n }\n\n const docTitle = getTitleValue({ document: doc, isTitleLocalized, locale, req, titleFieldName })\n\n // Cache the current document (in its own collection's cache)\n const currentDocCacheKey = `${doc.id}_${locale || 'default'}`\n if (!context.hierarchyAncestorCache[collection.slug]) {\n context.hierarchyAncestorCache[collection.slug] = {}\n }\n context.hierarchyAncestorCache[collection.slug][currentDocCacheKey] = {\n [parentFieldName]: parentID,\n [slugPathFieldName]: undefined, // Will be set below\n [titleFieldName]: docTitle,\n [titlePathFieldName]: undefined, // Will be set below\n }\n\n // Get parent's path field names from hierarchy config\n const parentSlugPathFieldName =\n parentCollectionConfig.hierarchy !== false\n ? parentCollectionConfig.hierarchy.slugPathFieldName\n : HIERARCHY_SLUG_PATH_FIELD\n const parentTitlePathFieldName =\n parentCollectionConfig.hierarchy !== false\n ? parentCollectionConfig.hierarchy.titlePathFieldName\n : HIERARCHY_TITLE_PATH_FIELD\n\n // Handle localized case (locale === 'all' with localized title field)\n if (isTitleLocalized && locale === 'all') {\n // Parent might have non-localized title field, resulting in string paths instead of objects\n // Convert parent paths to objects if they're strings (use same value for all locales)\n let parentSlugPathObj: Record<string, string> | undefined = parent[\n parentSlugPathFieldName\n ] as Record<string, string> | undefined\n let parentTitlePathObj: Record<string, string> | undefined = parent[\n parentTitlePathFieldName\n ] as Record<string, string> | undefined\n\n // If parent paths are strings (non-localized parent), convert to objects for all locales\n if (typeof parentSlugPathObj === 'string') {\n const locales = req.payload.config.localization\n ? req.payload.config.localization.localeCodes\n : []\n const slugValue = parentSlugPathObj\n parentSlugPathObj = {}\n for (const loc of locales) {\n parentSlugPathObj[loc] = slugValue\n }\n }\n\n if (typeof parentTitlePathObj === 'string') {\n const locales = req.payload.config.localization\n ? req.payload.config.localization.localeCodes\n : []\n const titleValue = parentTitlePathObj\n parentTitlePathObj = {}\n for (const loc of locales) {\n parentTitlePathObj[loc] = titleValue\n }\n }\n\n // If parent paths are undefined (parent fetch failed or paths not computed),\n // buildLocalizedHierarchyPaths will handle it by using just the child's title\n const result = buildLocalizedHierarchyPaths({\n parentSlugPath: parentSlugPathObj,\n parentTitlePath: parentTitlePathObj,\n req,\n slugify,\n titleValue: docTitle as Record<string, string>,\n })\n\n // Update cache with computed paths\n context.hierarchyAncestorCache[collection.slug][currentDocCacheKey][slugPathFieldName] =\n result.slugPath\n context.hierarchyAncestorCache[collection.slug][currentDocCacheKey][titlePathFieldName] =\n result.titlePath\n\n return result\n }\n\n // Single locale case\n const result = {\n slugPath: (parent[parentSlugPathFieldName] as string) + '/' + slugify(docTitle as string),\n titlePath: (parent[parentTitlePathFieldName] as string) + '/' + (docTitle as string),\n }\n\n // Update cache with computed paths\n context.hierarchyAncestorCache[collection.slug][currentDocCacheKey][slugPathFieldName] =\n result.slugPath\n context.hierarchyAncestorCache[collection.slug][currentDocCacheKey][titlePathFieldName] =\n result.titlePath\n\n return result\n } else {\n const titleValue = getTitleValue({\n document: doc,\n isTitleLocalized,\n locale,\n req,\n titleFieldName,\n })\n context.hierarchyAncestorCache[collection.slug][doc.id] = {\n [parentFieldName]: null,\n [titleFieldName]: titleValue,\n }\n\n // Handle localized case (locale === 'all' with localized title field)\n if (isTitleLocalized && locale === 'all') {\n return buildLocalizedHierarchyPaths({\n req,\n slugify,\n titleValue: titleValue as Record<string, string>,\n })\n }\n\n // Single locale case\n return {\n slugPath: slugify(titleValue as string),\n titlePath: titleValue as string,\n }\n }\n}\n"],"names":["slugify","payloadSlugify","HIERARCHY_SLUG_PATH_FIELD","HIERARCHY_TITLE_PATH_FIELD","buildLocalizedHierarchyPaths","findUseAsTitleField","getLocalizedValue","getTitleValue","document","isTitleLocalized","locale","req","titleFieldName","titleValue","id","toString","localizedValue","fallbackLocale","fieldType","value","computePaths","args","collection","doc","draft","parentFieldName","slugPathFieldName","titlePathFieldName","hierarchy","text","localized","context","hierarchyAncestorCache","slug","payload","config","debug","hierarchyCacheStats","hits","misses","queries","parentValue","parentID","undefined","parentCollectionConfig","parentHierarchyConfig","slugPath","titlePath","cache","cacheKey","parent","parentTitleField","validParentID","parentReq","computeHierarchyPaths","fetchParent","findByID","depth","overrideAccess","select","user","_error","locales","localization","localeCodes","parentPathsByLocale","parentSlugify","loc","localeReq","parentForLocale","parentSlugPath","parentTitlePath","parentTitle","title","localeError","combinedSlugPaths","combinedTitlePaths","combinedTitles","docTitle","currentDocCacheKey","parentSlugPathFieldName","parentTitlePathFieldName","parentSlugPathObj","parentTitlePathObj","slugValue","result"],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- import type { CollectionConfig } from '../../collections/config/types.js';
2
- export declare function findUseAsTitleField(collectionConfig: CollectionConfig): {
3
- localized: boolean;
4
- titleFieldName: string;
5
- };
6
- //# sourceMappingURL=findUseAsTitle.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"findUseAsTitle.d.ts","sourceRoot":"","sources":["../../../src/hierarchy/utils/findUseAsTitle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AAGzE,wBAAgB,mBAAmB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG;IACvE,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;CACvB,CAGA"}
@@ -1,72 +0,0 @@
1
- export function findUseAsTitleField(collectionConfig) {
2
- const titleFieldName = collectionConfig.admin?.useAsTitle || 'id';
3
- return iterateFields({
4
- fields: collectionConfig.fields,
5
- titleFieldName
6
- });
7
- }
8
- function iterateFields({ fields, titleFieldName }) {
9
- let titleField;
10
- if (titleFieldName === 'id') {
11
- return {
12
- localized: false,
13
- titleFieldName
14
- };
15
- }
16
- for (const field of fields){
17
- switch(field.type){
18
- case 'text':
19
- case 'number':
20
- case 'textarea':
21
- if (field.name === titleFieldName) {
22
- return {
23
- localized: Boolean(field.localized),
24
- titleFieldName: field.name
25
- };
26
- }
27
- break;
28
- case 'row':
29
- case 'collapsible':
30
- {
31
- const result = iterateFields({
32
- fields: field.fields,
33
- titleFieldName
34
- });
35
- if (result) {
36
- titleField = result;
37
- }
38
- }
39
- break;
40
- case 'group':
41
- if (!('name' in field)) {
42
- const result = iterateFields({
43
- fields: field.fields,
44
- titleFieldName
45
- });
46
- if (result) {
47
- titleField = result;
48
- }
49
- }
50
- break;
51
- case 'tabs':
52
- for (const tab of field.tabs){
53
- if (!('name' in tab)) {
54
- const result = iterateFields({
55
- fields: tab.fields,
56
- titleFieldName
57
- });
58
- if (result) {
59
- titleField = result;
60
- }
61
- }
62
- }
63
- }
64
- // If we found the field in recursion, return it
65
- if (titleField) {
66
- return titleField;
67
- }
68
- }
69
- throw new Error(`The hierarchy title field "${titleFieldName}" was not found. It cannot be nested within named fields i.e. named groups, named tabs, etc.`);
70
- }
71
-
72
- //# sourceMappingURL=findUseAsTitle.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/hierarchy/utils/findUseAsTitle.ts"],"sourcesContent":["import type { CollectionConfig } from '../../collections/config/types.js'\nimport type { Field } from '../../fields/config/types.js'\n\nexport function findUseAsTitleField(collectionConfig: CollectionConfig): {\n localized: boolean\n titleFieldName: string\n} {\n const titleFieldName = collectionConfig.admin?.useAsTitle || 'id'\n return iterateFields({ fields: collectionConfig.fields, titleFieldName })\n}\n\nfunction iterateFields({ fields, titleFieldName }: { fields: Field[]; titleFieldName: string }): {\n localized: boolean\n titleFieldName: string\n} {\n let titleField: { localized: boolean; titleFieldName: string } | undefined\n\n if (titleFieldName === 'id') {\n return {\n localized: false,\n titleFieldName,\n }\n }\n\n for (const field of fields) {\n switch (field.type) {\n case 'text':\n case 'number':\n case 'textarea':\n if (field.name === titleFieldName) {\n return {\n localized: Boolean(field.localized),\n titleFieldName: field.name,\n }\n }\n break\n case 'row':\n case 'collapsible':\n {\n const result = iterateFields({ fields: field.fields, titleFieldName })\n if (result) {titleField = result}\n }\n break\n case 'group':\n if (!('name' in field)) {\n const result = iterateFields({ fields: field.fields, titleFieldName })\n if (result) {titleField = result}\n }\n break\n case 'tabs':\n for (const tab of field.tabs) {\n if (!('name' in tab)) {\n const result = iterateFields({ fields: tab.fields, titleFieldName })\n if (result) {titleField = result}\n }\n }\n }\n\n // If we found the field in recursion, return it\n if (titleField) {\n return titleField\n }\n }\n\n throw new Error(\n `The hierarchy title field \"${titleFieldName}\" was not found. It cannot be nested within named fields i.e. named groups, named tabs, etc.`,\n )\n}\n"],"names":["findUseAsTitleField","collectionConfig","titleFieldName","admin","useAsTitle","iterateFields","fields","titleField","localized","field","type","name","Boolean","result","tab","tabs","Error"],"mappings":"AAGA,OAAO,SAASA,oBAAoBC,gBAAkC;IAIpE,MAAMC,iBAAiBD,iBAAiBE,KAAK,EAAEC,cAAc;IAC7D,OAAOC,cAAc;QAAEC,QAAQL,iBAAiBK,MAAM;QAAEJ;IAAe;AACzE;AAEA,SAASG,cAAc,EAAEC,MAAM,EAAEJ,cAAc,EAA+C;IAI5F,IAAIK;IAEJ,IAAIL,mBAAmB,MAAM;QAC3B,OAAO;YACLM,WAAW;YACXN;QACF;IACF;IAEA,KAAK,MAAMO,SAASH,OAAQ;QAC1B,OAAQG,MAAMC,IAAI;YAChB,KAAK;YACL,KAAK;YACL,KAAK;gBACH,IAAID,MAAME,IAAI,KAAKT,gBAAgB;oBACjC,OAAO;wBACLM,WAAWI,QAAQH,MAAMD,SAAS;wBAClCN,gBAAgBO,MAAME,IAAI;oBAC5B;gBACF;gBACA;YACF,KAAK;YACL,KAAK;gBACH;oBACE,MAAME,SAASR,cAAc;wBAAEC,QAAQG,MAAMH,MAAM;wBAAEJ;oBAAe;oBACpE,IAAIW,QAAQ;wBAACN,aAAaM;oBAAM;gBAClC;gBACA;YACF,KAAK;gBACH,IAAI,CAAE,CAAA,UAAUJ,KAAI,GAAI;oBACtB,MAAMI,SAASR,cAAc;wBAAEC,QAAQG,MAAMH,MAAM;wBAAEJ;oBAAe;oBACpE,IAAIW,QAAQ;wBAACN,aAAaM;oBAAM;gBAClC;gBACA;YACF,KAAK;gBACH,KAAK,MAAMC,OAAOL,MAAMM,IAAI,CAAE;oBAC5B,IAAI,CAAE,CAAA,UAAUD,GAAE,GAAI;wBACpB,MAAMD,SAASR,cAAc;4BAAEC,QAAQQ,IAAIR,MAAM;4BAAEJ;wBAAe;wBAClE,IAAIW,QAAQ;4BAACN,aAAaM;wBAAM;oBAClC;gBACF;QACJ;QAEA,gDAAgD;QAChD,IAAIN,YAAY;YACd,OAAOA;QACT;IACF;IAEA,MAAM,IAAIS,MACR,CAAC,2BAA2B,EAAEd,eAAe,4FAA4F,CAAC;AAE9I"}
@@ -1,34 +0,0 @@
1
- import type { CollectionSlug } from '../../index.js';
2
- import type { PayloadRequest } from '../../types/index.js';
3
- export type Ancestor = {
4
- id: number | string;
5
- title: string;
6
- };
7
- type GetAncestorsArgs = {
8
- /**
9
- * The collection slug
10
- */
11
- collectionSlug: CollectionSlug;
12
- /**
13
- * The document ID to get ancestors for
14
- */
15
- id: number | string;
16
- /**
17
- * Include the document itself in the returned ancestors (as last item)
18
- * @default true
19
- */
20
- includeSelf?: boolean;
21
- /**
22
- * The request object
23
- */
24
- req: PayloadRequest;
25
- };
26
- /**
27
- * Get ancestor chain for a hierarchical document.
28
- * Returns array of {id, title} from root to the document.
29
- *
30
- * Uses request context caching for efficiency when called multiple times.
31
- */
32
- export declare function getAncestors({ id, collectionSlug, includeSelf, req, }: GetAncestorsArgs): Promise<Ancestor[]>;
33
- export {};
34
- //# sourceMappingURL=getAncestors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getAncestors.d.ts","sourceRoot":"","sources":["../../../src/hierarchy/utils/getAncestors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAKpE,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB;;OAEG;IACH,cAAc,EAAE,cAAc,CAAA;IAC9B;;OAEG;IACH,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;OAEG;IACH,GAAG,EAAE,cAAc,CAAA;CACpB,CAAA;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,EACjC,EAAE,EACF,cAAc,EACd,WAAkB,EAClB,GAAG,GACJ,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAqGxC"}
@@ -1,94 +0,0 @@
1
- import { findUseAsTitleField } from './findUseAsTitle.js';
2
- import { getLocalizedValue } from './getLocalizedValue.js';
3
- /**
4
- * Get ancestor chain for a hierarchical document.
5
- * Returns array of {id, title} from root to the document.
6
- *
7
- * Uses request context caching for efficiency when called multiple times.
8
- */ export async function getAncestors({ id, collectionSlug, includeSelf = true, req }) {
9
- const { payload, user } = req;
10
- const collectionConfig = payload.collections[collectionSlug]?.config;
11
- if (!collectionConfig) {
12
- throw new Error(`Collection "${collectionSlug}" not found`);
13
- }
14
- const hierarchyConfig = collectionConfig.hierarchy;
15
- if (!hierarchyConfig) {
16
- throw new Error(`Collection "${collectionSlug}" does not have hierarchy enabled`);
17
- }
18
- const parentFieldName = hierarchyConfig.parentFieldName;
19
- const { localized: isTitleLocalized, titleFieldName } = findUseAsTitleField(collectionConfig);
20
- // Initialize cache if needed
21
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
- const context = req.context;
23
- if (!context.hierarchyAncestorCache) {
24
- context.hierarchyAncestorCache = {};
25
- }
26
- if (!context.hierarchyAncestorCache[collectionSlug]) {
27
- context.hierarchyAncestorCache[collectionSlug] = {};
28
- }
29
- const cache = context.hierarchyAncestorCache[collectionSlug];
30
- const ancestors = [];
31
- let currentId = id;
32
- while(currentId !== null){
33
- const cacheKey = `ancestors_${currentId}`;
34
- // Check cache first
35
- let doc = cache[cacheKey];
36
- if (!doc) {
37
- // Cache miss - fetch document
38
- try {
39
- doc = await payload.findByID({
40
- id: currentId,
41
- collection: collectionSlug,
42
- depth: 0,
43
- overrideAccess: false,
44
- req,
45
- select: {
46
- [parentFieldName]: true,
47
- [titleFieldName]: true
48
- },
49
- user
50
- });
51
- cache[cacheKey] = doc;
52
- } catch {
53
- break;
54
- }
55
- }
56
- if (!doc) {
57
- break;
58
- }
59
- // Extract title
60
- const rawTitle = doc[titleFieldName];
61
- let title;
62
- if (isTitleLocalized && rawTitle && typeof rawTitle === 'object' && req.locale) {
63
- const localizedValue = getLocalizedValue({
64
- fallbackLocale: req.fallbackLocale,
65
- fieldType: 'text',
66
- locale: req.locale,
67
- value: rawTitle
68
- });
69
- title = localizedValue || String(doc.id || currentId);
70
- } else if (isTitleLocalized && rawTitle && typeof rawTitle === 'object') {
71
- // No locale set - use first available value
72
- const values = Object.values(rawTitle);
73
- title = values[0] || String(doc.id || currentId);
74
- } else {
75
- title = String(rawTitle || doc.id || currentId);
76
- }
77
- ancestors.unshift({
78
- id: currentId,
79
- title
80
- });
81
- // Get parent ID for next iteration
82
- const parentValue = doc[parentFieldName];
83
- if (!parentValue) {
84
- break;
85
- }
86
- currentId = typeof parentValue === 'object' && parentValue !== null && 'id' in parentValue ? parentValue.id : parentValue;
87
- }
88
- if (!includeSelf && ancestors.length > 0) {
89
- ancestors.pop();
90
- }
91
- return ancestors;
92
- }
93
-
94
- //# sourceMappingURL=getAncestors.js.map