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,14 +0,0 @@
1
- import type { CollectionConfig } from '../collections/config/types.js';
2
- /**
3
- * Injects the HierarchyButton component into a collection's BeforeDocumentMeta slot.
4
- *
5
- * The HierarchyButton provides a header UI for selecting parent hierarchy items
6
- * via miller columns, replacing the standard relationship field input.
7
- */
8
- export declare const injectHierarchyButton: ({ collection, fieldName, hierarchyCollectionSlug, parentFieldName, }: {
9
- collection: CollectionConfig;
10
- fieldName: string;
11
- hierarchyCollectionSlug: string;
12
- parentFieldName: string;
13
- }) => void;
14
- //# sourceMappingURL=injectHierarchyButton.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectHierarchyButton.d.ts","sourceRoot":"","sources":["../../src/hierarchy/injectHierarchyButton.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AAEtE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,yEAK/B;IACD,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,uBAAuB,EAAE,MAAM,CAAA;IAC/B,eAAe,EAAE,MAAM,CAAA;CACxB,KAAG,IAiCH,CAAA"}
@@ -1,37 +0,0 @@
1
- /**
2
- * Injects the HierarchyButton component into a collection's BeforeDocumentMeta slot.
3
- *
4
- * The HierarchyButton provides a header UI for selecting parent hierarchy items
5
- * via miller columns, replacing the standard relationship field input.
6
- */ export const injectHierarchyButton = ({ collection, fieldName, hierarchyCollectionSlug, parentFieldName })=>{
7
- collection.admin = collection.admin || {};
8
- collection.admin.components = collection.admin.components || {};
9
- collection.admin.components.edit = collection.admin.components.edit || {};
10
- const hierarchyComponent = {
11
- path: '@payloadcms/ui/rsc#HierarchyButton',
12
- serverProps: {
13
- fieldName,
14
- hierarchyCollectionSlug,
15
- parentFieldName
16
- }
17
- };
18
- const existingComponents = collection.admin.components.edit.BeforeDocumentMeta || [];
19
- const componentPath = '@payloadcms/ui/rsc#HierarchyButton';
20
- const alreadyInjected = existingComponents.some((c)=>{
21
- if (typeof c === 'string') {
22
- return c === componentPath;
23
- }
24
- if (c && typeof c === 'object' && 'path' in c) {
25
- return c.path === componentPath;
26
- }
27
- return false;
28
- });
29
- if (!alreadyInjected) {
30
- collection.admin.components.edit.BeforeDocumentMeta = [
31
- hierarchyComponent,
32
- ...existingComponents
33
- ];
34
- }
35
- };
36
-
37
- //# sourceMappingURL=injectHierarchyButton.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/hierarchy/injectHierarchyButton.ts"],"sourcesContent":["import type { CollectionConfig } from '../collections/config/types.js'\n\n/**\n * Injects the HierarchyButton component into a collection's BeforeDocumentMeta slot.\n *\n * The HierarchyButton provides a header UI for selecting parent hierarchy items\n * via miller columns, replacing the standard relationship field input.\n */\nexport const injectHierarchyButton = ({\n collection,\n fieldName,\n hierarchyCollectionSlug,\n parentFieldName,\n}: {\n collection: CollectionConfig\n fieldName: string\n hierarchyCollectionSlug: string\n parentFieldName: string\n}): void => {\n collection.admin = collection.admin || {}\n collection.admin.components = collection.admin.components || {}\n collection.admin.components.edit = collection.admin.components.edit || {}\n\n const hierarchyComponent = {\n path: '@payloadcms/ui/rsc#HierarchyButton',\n serverProps: {\n fieldName,\n hierarchyCollectionSlug,\n parentFieldName,\n },\n }\n\n const existingComponents = collection.admin.components.edit.BeforeDocumentMeta || []\n const componentPath = '@payloadcms/ui/rsc#HierarchyButton'\n\n const alreadyInjected = existingComponents.some((c) => {\n if (typeof c === 'string') {\n return c === componentPath\n }\n if (c && typeof c === 'object' && 'path' in c) {\n return c.path === componentPath\n }\n return false\n })\n\n if (!alreadyInjected) {\n collection.admin.components.edit.BeforeDocumentMeta = [\n hierarchyComponent,\n ...existingComponents,\n ]\n }\n}\n"],"names":["injectHierarchyButton","collection","fieldName","hierarchyCollectionSlug","parentFieldName","admin","components","edit","hierarchyComponent","path","serverProps","existingComponents","BeforeDocumentMeta","componentPath","alreadyInjected","some","c"],"mappings":"AAEA;;;;;CAKC,GACD,OAAO,MAAMA,wBAAwB,CAAC,EACpCC,UAAU,EACVC,SAAS,EACTC,uBAAuB,EACvBC,eAAe,EAMhB;IACCH,WAAWI,KAAK,GAAGJ,WAAWI,KAAK,IAAI,CAAC;IACxCJ,WAAWI,KAAK,CAACC,UAAU,GAAGL,WAAWI,KAAK,CAACC,UAAU,IAAI,CAAC;IAC9DL,WAAWI,KAAK,CAACC,UAAU,CAACC,IAAI,GAAGN,WAAWI,KAAK,CAACC,UAAU,CAACC,IAAI,IAAI,CAAC;IAExE,MAAMC,qBAAqB;QACzBC,MAAM;QACNC,aAAa;YACXR;YACAC;YACAC;QACF;IACF;IAEA,MAAMO,qBAAqBV,WAAWI,KAAK,CAACC,UAAU,CAACC,IAAI,CAACK,kBAAkB,IAAI,EAAE;IACpF,MAAMC,gBAAgB;IAEtB,MAAMC,kBAAkBH,mBAAmBI,IAAI,CAAC,CAACC;QAC/C,IAAI,OAAOA,MAAM,UAAU;YACzB,OAAOA,MAAMH;QACf;QACA,IAAIG,KAAK,OAAOA,MAAM,YAAY,UAAUA,GAAG;YAC7C,OAAOA,EAAEP,IAAI,KAAKI;QACpB;QACA,OAAO;IACT;IAEA,IAAI,CAACC,iBAAiB;QACpBb,WAAWI,KAAK,CAACC,UAAU,CAACC,IAAI,CAACK,kBAAkB,GAAG;YACpDJ;eACGG;SACJ;IACH;AACF,EAAC"}
@@ -1,23 +0,0 @@
1
- import type { Config } from '../config/types.js';
2
- /**
3
- * Resolves hierarchy relationships across collections.
4
- *
5
- * This function runs after individual collection sanitization to establish
6
- * cross-collection hierarchy relationships. It discovers which collections
7
- * reference each hierarchy and configures the necessary fields, components,
8
- * and hooks.
9
- *
10
- * @remarks
11
- * Must be called after all collections are sanitized.
12
- *
13
- * **What it does:**
14
- * - Discovers related collections by scanning for hierarchy relationship fields
15
- * - Injects `HierarchyButton` component when `custom.hierarchy.injectHeaderButton` is set
16
- * - Adds `collectionSpecific` validation to ensure hierarchy items accept the document type
17
- * - Injects the `hierarchyType` select field when `collectionSpecific` is enabled
18
- * - Injects join field when `joinField` is configured
19
- * - Adds `afterDelete` hook to clear hierarchy references when items are deleted
20
- * - Populates `relatedCollections` in the sanitized hierarchy config
21
- */
22
- export declare const resolveHierarchyCollections: (config: Config) => void;
23
- //# sourceMappingURL=resolveHierarchyCollections.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolveHierarchyCollections.d.ts","sourceRoot":"","sources":["../../src/hierarchy/resolveHierarchyCollections.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAuBhD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,2BAA2B,WAAY,MAAM,KAAG,IAuI5D,CAAA"}
@@ -1,312 +0,0 @@
1
- import { sanitizeJoinField } from '../fields/config/sanitizeJoinField.js';
2
- import { fieldAffectsData } from '../fields/config/types.js';
3
- import { extractID } from '../utilities/extractID.js';
4
- import { flattenAllFields } from '../utilities/flattenAllFields.js';
5
- import { getHierarchyFieldName } from './constants.js';
6
- import { hierarchyCollectionAfterDelete } from './hooks/collectionAfterDelete.js';
7
- import { injectHierarchyButton } from './injectHierarchyButton.js';
8
- /**
9
- * Resolves hierarchy relationships across collections.
10
- *
11
- * This function runs after individual collection sanitization to establish
12
- * cross-collection hierarchy relationships. It discovers which collections
13
- * reference each hierarchy and configures the necessary fields, components,
14
- * and hooks.
15
- *
16
- * @remarks
17
- * Must be called after all collections are sanitized.
18
- *
19
- * **What it does:**
20
- * - Discovers related collections by scanning for hierarchy relationship fields
21
- * - Injects `HierarchyButton` component when `custom.hierarchy.injectHeaderButton` is set
22
- * - Adds `collectionSpecific` validation to ensure hierarchy items accept the document type
23
- * - Injects the `hierarchyType` select field when `collectionSpecific` is enabled
24
- * - Injects join field when `joinField` is configured
25
- * - Adds `afterDelete` hook to clear hierarchy references when items are deleted
26
- * - Populates `relatedCollections` in the sanitized hierarchy config
27
- */ export const resolveHierarchyCollections = (config)=>{
28
- const hierarchyCollections = config.collections?.filter((col)=>col.hierarchy && typeof col.hierarchy === 'object') || [];
29
- for (const hierarchyCollection of hierarchyCollections){
30
- const hierarchy = hierarchyCollection.hierarchy;
31
- // TypeScript guard - hierarchy is guaranteed to be an object by the filter above
32
- if (!hierarchy || typeof hierarchy !== 'object') {
33
- continue;
34
- }
35
- const hierarchyConfig = hierarchy;
36
- const defaultFieldName = getHierarchyFieldName(hierarchyCollection.slug);
37
- const parentFieldName = hierarchyConfig.parentFieldName ?? defaultFieldName;
38
- const isParentFieldNameOverridden = parentFieldName !== defaultFieldName;
39
- const collectionSpecific = hierarchyConfig.collectionSpecific;
40
- const typeFieldName = collectionSpecific ? collectionSpecific.fieldName : undefined;
41
- const allowHasMany = hierarchyConfig.allowHasMany ?? true;
42
- // Build relatedCollections by scanning all collections for hierarchy fields
43
- const sanitizedRelatedCollections = {};
44
- const selfParentField = hierarchyCollection.fields.find((field)=>fieldAffectsData(field) && field.name === parentFieldName && field.type === 'relationship' && field.relationTo === hierarchyCollection.slug);
45
- // Check if the hierarchy collection's own parent field should be replaced with a header button
46
- if (selfParentField?.custom?.hierarchy?.injectHeaderButton === true) {
47
- injectHierarchyButton({
48
- collection: hierarchyCollection,
49
- fieldName: parentFieldName,
50
- hierarchyCollectionSlug: hierarchyCollection.slug,
51
- parentFieldName: hierarchyConfig.parentFieldName
52
- });
53
- }
54
- for (const collection of config.collections || []){
55
- // Skip the hierarchy collection itself (handled above)
56
- if (collection.slug === hierarchyCollection.slug) {
57
- continue;
58
- }
59
- // Find hierarchy field by the default name (what createFolderField uses)
60
- const hierarchyField = collection.fields.find((field)=>fieldAffectsData(field) && field.name === defaultFieldName && field.type === 'relationship' && field.relationTo === hierarchyCollection.slug);
61
- // If parentFieldName is overridden, rename the field to match
62
- if (hierarchyField && isParentFieldNameOverridden) {
63
- hierarchyField.name = parentFieldName;
64
- }
65
- if (!hierarchyField) {
66
- continue;
67
- }
68
- const fieldHasMany = hierarchyField.hasMany ?? allowHasMany;
69
- // If collectionSpecific, inject validation to check hierarchy allows this collection type
70
- if (collectionSpecific) {
71
- injectCollectionSpecificValidation({
72
- hierarchyField,
73
- hierarchySlug: hierarchyCollection.slug,
74
- typeFieldName: typeFieldName
75
- });
76
- }
77
- // Store discovered collection with hasMany info
78
- sanitizedRelatedCollections[collection.slug] = {
79
- fieldName: parentFieldName,
80
- hasMany: fieldHasMany
81
- };
82
- // Inject HierarchyButton if field requests it
83
- if (hierarchyField.custom?.hierarchy?.injectHeaderButton === true) {
84
- injectHierarchyButton({
85
- collection,
86
- fieldName: parentFieldName,
87
- hierarchyCollectionSlug: hierarchyCollection.slug,
88
- parentFieldName: hierarchyConfig.parentFieldName
89
- });
90
- }
91
- }
92
- // If collectionSpecific, add type field to hierarchy collection
93
- if (hierarchyConfig.collectionSpecific) {
94
- injectTypeField({
95
- config,
96
- hierarchyCollection: hierarchyCollection,
97
- parentFieldName: hierarchyConfig.parentFieldName,
98
- sanitizedRelatedCollections,
99
- typeFieldName: hierarchyConfig.collectionSpecific.fieldName
100
- });
101
- }
102
- // If joinField is configured, add the join field to query children
103
- if (hierarchyConfig.joinField) {
104
- injectJoinField({
105
- config,
106
- hierarchyCollection: hierarchyCollection,
107
- joinFieldConfig: hierarchyConfig.joinField,
108
- parentFieldName,
109
- relatedSlugs: Object.keys(sanitizedRelatedCollections)
110
- });
111
- }
112
- // Update hierarchy config with sanitized relatedCollections
113
- if (hierarchyConfig) {
114
- hierarchyConfig.relatedCollections = sanitizedRelatedCollections;
115
- }
116
- // Add afterDelete hook to clear folder references from related documents
117
- if (Object.keys(sanitizedRelatedCollections).length > 0) {
118
- injectAfterDeleteHook({
119
- hierarchyCollection: hierarchyCollection,
120
- sanitizedRelatedCollections
121
- });
122
- }
123
- // Add sidebar tab for this hierarchy collection
124
- injectSidebarTab({
125
- config,
126
- hierarchyCollection,
127
- hierarchyConfig
128
- });
129
- }
130
- };
131
- /**
132
- * Injects validation for collectionSpecific hierarchy fields.
133
- * Ensures the selected hierarchy item allows documents of this collection type.
134
- */ function injectCollectionSpecificValidation({ hierarchyField, hierarchySlug, typeFieldName }) {
135
- const existingValidate = hierarchyField.validate;
136
- const validate = async (value, options)=>{
137
- // Run existing validation first if present
138
- if (existingValidate) {
139
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
- const existingResult = await existingValidate(value, options);
141
- if (existingResult !== true) {
142
- return existingResult;
143
- }
144
- }
145
- // No hierarchy selected, no validation needed
146
- if (!value) {
147
- return true;
148
- }
149
- const { collectionSlug, overrideAccess, previousValue, req } = options;
150
- const newID = extractID(value);
151
- // Value didn't change, no validation needed
152
- if (previousValue && extractID(previousValue) === newID) {
153
- return true;
154
- }
155
- // Fetch the hierarchy item to check its type field
156
- let parentItem = null;
157
- if (typeof newID === 'string' || typeof newID === 'number') {
158
- try {
159
- parentItem = await req.payload.findByID({
160
- id: newID,
161
- collection: hierarchySlug,
162
- depth: 0,
163
- overrideAccess: overrideAccess ?? false,
164
- req,
165
- select: {
166
- [typeFieldName]: true
167
- }
168
- });
169
- } catch {
170
- return `Hierarchy item with ID ${newID} not found`;
171
- }
172
- }
173
- if (!parentItem) {
174
- return `Hierarchy item with ID ${newID} not found`;
175
- }
176
- const allowedTypes = parentItem[typeFieldName] || [];
177
- // If hierarchy has no types, it accepts all collections
178
- if (allowedTypes.length === 0) {
179
- return true;
180
- }
181
- // Check if this collection is allowed
182
- if (collectionSlug && allowedTypes.includes(collectionSlug)) {
183
- return true;
184
- }
185
- return `Hierarchy item "${newID}" does not allow documents of type "${collectionSlug}"`;
186
- };
187
- hierarchyField.validate = validate;
188
- }
189
- /**
190
- * Injects the hierarchyType select field into a hierarchy collection.
191
- */ function injectTypeField({ config, hierarchyCollection, parentFieldName, sanitizedRelatedCollections, typeFieldName }) {
192
- const collectionOptions = Object.keys(sanitizedRelatedCollections).map((slug)=>{
193
- const relatedCollection = config.collections?.find((c)=>c.slug === slug);
194
- return {
195
- label: relatedCollection?.labels?.plural || slug,
196
- value: slug
197
- };
198
- });
199
- const typeField = {
200
- name: typeFieldName,
201
- type: 'select',
202
- admin: {
203
- components: {
204
- Field: {
205
- path: '@payloadcms/next/rsc#HierarchyTypeFieldServer',
206
- serverProps: {
207
- collectionOptions,
208
- parentFieldName
209
- }
210
- }
211
- },
212
- position: 'sidebar'
213
- },
214
- hasMany: true,
215
- options: collectionOptions
216
- };
217
- hierarchyCollection.fields = hierarchyCollection.fields || [];
218
- hierarchyCollection.fields.push(typeField);
219
- // Recompute flattenedFields since we added a field after initial sanitization
220
- // This is required for the field to be queryable
221
- if ('flattenedFields' in hierarchyCollection) {
222
- hierarchyCollection.flattenedFields = flattenAllFields({
223
- fields: hierarchyCollection.fields
224
- });
225
- }
226
- }
227
- /**
228
- * Injects a join field to query all children of a hierarchy item.
229
- */ function injectJoinField({ config, hierarchyCollection, joinFieldConfig, parentFieldName, relatedSlugs }) {
230
- const { name, admin: userAdmin, ...userConfig } = joinFieldConfig;
231
- const hasJoinField = hierarchyCollection.fields?.some((field)=>'name' in field && field.name === name);
232
- if (hasJoinField) {
233
- return;
234
- }
235
- const joinField = {
236
- // User config (spread first so auto-generated values take precedence for required fields)
237
- ...userConfig,
238
- // Auto-generated values (these cannot be overridden)
239
- name,
240
- type: 'join',
241
- collection: [
242
- hierarchyCollection.slug,
243
- ...relatedSlugs
244
- ],
245
- hasMany: true,
246
- on: parentFieldName,
247
- // Merge admin config
248
- admin: {
249
- ...userAdmin
250
- }
251
- };
252
- hierarchyCollection.fields = hierarchyCollection.fields || [];
253
- hierarchyCollection.fields.push(joinField);
254
- // Sanitize the join field to register it properly
255
- sanitizeJoinField({
256
- config,
257
- field: joinField,
258
- joins: hierarchyCollection.joins,
259
- parentIsLocalized: false,
260
- polymorphicJoins: hierarchyCollection.polymorphicJoins
261
- });
262
- // Recompute flattenedFields since we added a field after initial sanitization
263
- hierarchyCollection.flattenedFields = flattenAllFields({
264
- fields: hierarchyCollection.fields
265
- });
266
- }
267
- /**
268
- * Injects afterDelete hook to clear hierarchy references from related documents.
269
- */ function injectAfterDeleteHook({ hierarchyCollection, sanitizedRelatedCollections }) {
270
- // Build map of collection slugs to their field names
271
- const relatedCollectionFieldMap = {};
272
- for (const [slug, relatedConfig] of Object.entries(sanitizedRelatedCollections)){
273
- relatedCollectionFieldMap[slug] = relatedConfig.fieldName;
274
- }
275
- hierarchyCollection.hooks = hierarchyCollection.hooks || {};
276
- hierarchyCollection.hooks.afterDelete = [
277
- ...hierarchyCollection.hooks.afterDelete || [],
278
- hierarchyCollectionAfterDelete({
279
- relatedCollections: relatedCollectionFieldMap
280
- })
281
- ];
282
- }
283
- /**
284
- * Injects a sidebar tab for a hierarchy collection.
285
- */ function injectSidebarTab({ config, hierarchyCollection, hierarchyConfig }) {
286
- const tabSlug = `hierarchy-${hierarchyCollection.slug}`;
287
- const Icon = hierarchyConfig.admin.components.Icon;
288
- // Initialize admin config structure
289
- config.admin = config.admin || {};
290
- config.admin.components = config.admin.components || {};
291
- config.admin.components.sidebar = config.admin.components.sidebar || {};
292
- config.admin.components.sidebar.tabs = config.admin.components.sidebar.tabs || [];
293
- // Check if tab already exists
294
- const hasTab = config.admin.components.sidebar.tabs.some((tab)=>tab.slug === tabSlug);
295
- if (!hasTab) {
296
- config.admin.components.sidebar.tabs.push({
297
- slug: tabSlug,
298
- components: {
299
- Content: {
300
- clientProps: {
301
- hierarchyCollectionSlug: hierarchyCollection.slug
302
- },
303
- path: '@payloadcms/ui/rsc#HierarchySidebarTabServer'
304
- },
305
- Icon
306
- },
307
- label: hierarchyCollection.labels?.plural || hierarchyCollection.slug
308
- });
309
- }
310
- }
311
-
312
- //# sourceMappingURL=resolveHierarchyCollections.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/hierarchy/resolveHierarchyCollections.ts"],"sourcesContent":["import type { CollectionConfig, SanitizedCollectionConfig } from '../collections/config/types.js'\nimport type { Config } from '../config/types.js'\nimport type {\n JoinField,\n Option,\n RelationshipField,\n SelectField,\n Validate,\n} from '../fields/config/types.js'\nimport type { Document } from '../types/index.js'\nimport type {\n HierarchyJoinFieldConfig,\n SanitizedHierarchyConfig,\n SanitizedHierarchyRelatedCollection,\n} from './types.js'\n\nimport { sanitizeJoinField } from '../fields/config/sanitizeJoinField.js'\nimport { fieldAffectsData } from '../fields/config/types.js'\nimport { extractID } from '../utilities/extractID.js'\nimport { flattenAllFields } from '../utilities/flattenAllFields.js'\nimport { getHierarchyFieldName } from './constants.js'\nimport { hierarchyCollectionAfterDelete } from './hooks/collectionAfterDelete.js'\nimport { injectHierarchyButton } from './injectHierarchyButton.js'\n\n/**\n * Resolves hierarchy relationships across collections.\n *\n * This function runs after individual collection sanitization to establish\n * cross-collection hierarchy relationships. It discovers which collections\n * reference each hierarchy and configures the necessary fields, components,\n * and hooks.\n *\n * @remarks\n * Must be called after all collections are sanitized.\n *\n * **What it does:**\n * - Discovers related collections by scanning for hierarchy relationship fields\n * - Injects `HierarchyButton` component when `custom.hierarchy.injectHeaderButton` is set\n * - Adds `collectionSpecific` validation to ensure hierarchy items accept the document type\n * - Injects the `hierarchyType` select field when `collectionSpecific` is enabled\n * - Injects join field when `joinField` is configured\n * - Adds `afterDelete` hook to clear hierarchy references when items are deleted\n * - Populates `relatedCollections` in the sanitized hierarchy config\n */\nexport const resolveHierarchyCollections = (config: Config): void => {\n const hierarchyCollections =\n config.collections?.filter((col) => col.hierarchy && typeof col.hierarchy === 'object') || []\n\n for (const hierarchyCollection of hierarchyCollections) {\n const hierarchy = hierarchyCollection.hierarchy\n\n // TypeScript guard - hierarchy is guaranteed to be an object by the filter above\n if (!hierarchy || typeof hierarchy !== 'object') {\n continue\n }\n\n const hierarchyConfig = hierarchy as SanitizedHierarchyConfig\n const defaultFieldName = getHierarchyFieldName(hierarchyCollection.slug)\n const parentFieldName = hierarchyConfig.parentFieldName ?? defaultFieldName\n const isParentFieldNameOverridden = parentFieldName !== defaultFieldName\n const collectionSpecific = hierarchyConfig.collectionSpecific\n const typeFieldName = collectionSpecific ? collectionSpecific.fieldName : undefined\n const allowHasMany = hierarchyConfig.allowHasMany ?? true\n\n // Build relatedCollections by scanning all collections for hierarchy fields\n const sanitizedRelatedCollections: Record<string, SanitizedHierarchyRelatedCollection> = {}\n\n const selfParentField = hierarchyCollection.fields.find(\n (field) =>\n fieldAffectsData(field) &&\n field.name === parentFieldName &&\n field.type === 'relationship' &&\n (field as RelationshipField).relationTo === hierarchyCollection.slug,\n ) as RelationshipField | undefined\n\n // Check if the hierarchy collection's own parent field should be replaced with a header button\n if (selfParentField?.custom?.hierarchy?.injectHeaderButton === true) {\n injectHierarchyButton({\n collection: hierarchyCollection,\n fieldName: parentFieldName,\n hierarchyCollectionSlug: hierarchyCollection.slug,\n parentFieldName: hierarchyConfig.parentFieldName,\n })\n }\n\n for (const collection of config.collections || []) {\n // Skip the hierarchy collection itself (handled above)\n if (collection.slug === hierarchyCollection.slug) {\n continue\n }\n\n // Find hierarchy field by the default name (what createFolderField uses)\n const hierarchyField = collection.fields.find(\n (field) =>\n fieldAffectsData(field) &&\n field.name === defaultFieldName &&\n field.type === 'relationship' &&\n (field as RelationshipField).relationTo === hierarchyCollection.slug,\n ) as RelationshipField | undefined\n\n // If parentFieldName is overridden, rename the field to match\n if (hierarchyField && isParentFieldNameOverridden) {\n hierarchyField.name = parentFieldName\n }\n\n if (!hierarchyField) {\n continue\n }\n\n const fieldHasMany = hierarchyField.hasMany ?? allowHasMany\n\n // If collectionSpecific, inject validation to check hierarchy allows this collection type\n if (collectionSpecific) {\n injectCollectionSpecificValidation({\n hierarchyField,\n hierarchySlug: hierarchyCollection.slug,\n typeFieldName: typeFieldName!,\n })\n }\n\n // Store discovered collection with hasMany info\n sanitizedRelatedCollections[collection.slug] = {\n fieldName: parentFieldName,\n hasMany: fieldHasMany,\n }\n\n // Inject HierarchyButton if field requests it\n if (hierarchyField.custom?.hierarchy?.injectHeaderButton === true) {\n injectHierarchyButton({\n collection,\n fieldName: parentFieldName,\n hierarchyCollectionSlug: hierarchyCollection.slug,\n parentFieldName: hierarchyConfig.parentFieldName,\n })\n }\n }\n\n // If collectionSpecific, add type field to hierarchy collection\n if (hierarchyConfig.collectionSpecific) {\n injectTypeField({\n config,\n hierarchyCollection: hierarchyCollection as SanitizedCollectionConfig,\n parentFieldName: hierarchyConfig.parentFieldName,\n sanitizedRelatedCollections,\n typeFieldName: hierarchyConfig.collectionSpecific.fieldName,\n })\n }\n\n // If joinField is configured, add the join field to query children\n if (hierarchyConfig.joinField) {\n injectJoinField({\n config,\n hierarchyCollection: hierarchyCollection as SanitizedCollectionConfig,\n joinFieldConfig: hierarchyConfig.joinField,\n parentFieldName,\n relatedSlugs: Object.keys(sanitizedRelatedCollections),\n })\n }\n\n // Update hierarchy config with sanitized relatedCollections\n if (hierarchyConfig) {\n hierarchyConfig.relatedCollections = sanitizedRelatedCollections\n }\n\n // Add afterDelete hook to clear folder references from related documents\n if (Object.keys(sanitizedRelatedCollections).length > 0) {\n injectAfterDeleteHook({\n hierarchyCollection: hierarchyCollection as SanitizedCollectionConfig,\n sanitizedRelatedCollections,\n })\n }\n\n // Add sidebar tab for this hierarchy collection\n injectSidebarTab({\n config,\n hierarchyCollection,\n hierarchyConfig,\n })\n }\n}\n\n/**\n * Injects validation for collectionSpecific hierarchy fields.\n * Ensures the selected hierarchy item allows documents of this collection type.\n */\nfunction injectCollectionSpecificValidation({\n hierarchyField,\n hierarchySlug,\n typeFieldName,\n}: {\n hierarchyField: RelationshipField\n hierarchySlug: string\n typeFieldName: string\n}): void {\n const existingValidate = hierarchyField.validate\n\n const validate: Validate<unknown> = async (value, options) => {\n // Run existing validation first if present\n if (existingValidate) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const existingResult = await existingValidate(value as any, options as any)\n if (existingResult !== true) {\n return existingResult\n }\n }\n\n // No hierarchy selected, no validation needed\n if (!value) {\n return true\n }\n\n const { collectionSlug, overrideAccess, previousValue, req } = options\n const newID = extractID<Document>(value)\n\n // Value didn't change, no validation needed\n if (previousValue && extractID<Document>(previousValue) === newID) {\n return true\n }\n\n // Fetch the hierarchy item to check its type field\n let parentItem: Document | null = null\n if (typeof newID === 'string' || typeof newID === 'number') {\n try {\n parentItem = await req.payload.findByID({\n id: newID,\n collection: hierarchySlug,\n depth: 0,\n overrideAccess: overrideAccess ?? false,\n req,\n select: { [typeFieldName]: true },\n })\n } catch {\n return `Hierarchy item with ID ${newID} not found`\n }\n }\n\n if (!parentItem) {\n return `Hierarchy item with ID ${newID} not found`\n }\n\n const allowedTypes: string[] = (parentItem[typeFieldName] as string[]) || []\n\n // If hierarchy has no types, it accepts all collections\n if (allowedTypes.length === 0) {\n return true\n }\n\n // Check if this collection is allowed\n if (collectionSlug && allowedTypes.includes(collectionSlug)) {\n return true\n }\n\n return `Hierarchy item \"${newID}\" does not allow documents of type \"${collectionSlug}\"`\n }\n\n hierarchyField.validate = validate\n}\n\n/**\n * Injects the hierarchyType select field into a hierarchy collection.\n */\nfunction injectTypeField({\n config,\n hierarchyCollection,\n parentFieldName,\n sanitizedRelatedCollections,\n typeFieldName,\n}: {\n config: Config\n hierarchyCollection: CollectionConfig | SanitizedCollectionConfig\n parentFieldName: string\n sanitizedRelatedCollections: Record<string, SanitizedHierarchyRelatedCollection>\n typeFieldName: string\n}): void {\n const collectionOptions: Option[] = Object.keys(sanitizedRelatedCollections).map((slug) => {\n const relatedCollection = config.collections?.find((c) => c.slug === slug)\n return {\n label: relatedCollection?.labels?.plural || slug,\n value: slug,\n }\n })\n\n const typeField: SelectField = {\n name: typeFieldName,\n type: 'select',\n admin: {\n components: {\n Field: {\n path: '@payloadcms/next/rsc#HierarchyTypeFieldServer',\n serverProps: {\n collectionOptions,\n parentFieldName,\n },\n },\n },\n position: 'sidebar',\n },\n hasMany: true,\n options: collectionOptions,\n }\n\n hierarchyCollection.fields = hierarchyCollection.fields || []\n hierarchyCollection.fields.push(typeField)\n\n // Recompute flattenedFields since we added a field after initial sanitization\n // This is required for the field to be queryable\n if ('flattenedFields' in hierarchyCollection) {\n hierarchyCollection.flattenedFields = flattenAllFields({\n fields: hierarchyCollection.fields,\n })\n }\n}\n\n/**\n * Injects a join field to query all children of a hierarchy item.\n */\nfunction injectJoinField({\n config,\n hierarchyCollection,\n joinFieldConfig,\n parentFieldName,\n relatedSlugs,\n}: {\n config: Config\n hierarchyCollection: SanitizedCollectionConfig\n joinFieldConfig: HierarchyJoinFieldConfig\n parentFieldName: string\n relatedSlugs: string[]\n}): void {\n const { name, admin: userAdmin, ...userConfig } = joinFieldConfig\n\n const hasJoinField = hierarchyCollection.fields?.some(\n (field) => 'name' in field && field.name === name,\n )\n\n if (hasJoinField) {\n return\n }\n\n const joinField: JoinField = {\n // User config (spread first so auto-generated values take precedence for required fields)\n ...userConfig,\n // Auto-generated values (these cannot be overridden)\n name,\n type: 'join',\n collection: [hierarchyCollection.slug, ...relatedSlugs],\n hasMany: true,\n on: parentFieldName,\n // Merge admin config\n admin: {\n ...userAdmin,\n },\n }\n\n hierarchyCollection.fields = hierarchyCollection.fields || []\n hierarchyCollection.fields.push(joinField)\n\n // Sanitize the join field to register it properly\n sanitizeJoinField({\n config,\n field: joinField,\n joins: hierarchyCollection.joins,\n parentIsLocalized: false,\n polymorphicJoins: hierarchyCollection.polymorphicJoins,\n })\n\n // Recompute flattenedFields since we added a field after initial sanitization\n hierarchyCollection.flattenedFields = flattenAllFields({\n fields: hierarchyCollection.fields,\n })\n}\n\n/**\n * Injects afterDelete hook to clear hierarchy references from related documents.\n */\nfunction injectAfterDeleteHook({\n hierarchyCollection,\n sanitizedRelatedCollections,\n}: {\n hierarchyCollection: CollectionConfig | SanitizedCollectionConfig\n sanitizedRelatedCollections: Record<string, SanitizedHierarchyRelatedCollection>\n}): void {\n // Build map of collection slugs to their field names\n const relatedCollectionFieldMap: Record<string, string> = {}\n for (const [slug, relatedConfig] of Object.entries(sanitizedRelatedCollections)) {\n relatedCollectionFieldMap[slug] = relatedConfig.fieldName\n }\n\n hierarchyCollection.hooks = hierarchyCollection.hooks || {}\n hierarchyCollection.hooks.afterDelete = [\n ...(hierarchyCollection.hooks.afterDelete || []),\n hierarchyCollectionAfterDelete({ relatedCollections: relatedCollectionFieldMap }),\n ]\n}\n\n/**\n * Injects a sidebar tab for a hierarchy collection.\n */\nfunction injectSidebarTab({\n config,\n hierarchyCollection,\n hierarchyConfig,\n}: {\n config: Config\n hierarchyCollection: CollectionConfig\n hierarchyConfig: SanitizedHierarchyConfig\n}): void {\n const tabSlug = `hierarchy-${hierarchyCollection.slug}`\n const Icon = hierarchyConfig.admin.components.Icon\n\n // Initialize admin config structure\n config.admin = config.admin || {}\n config.admin.components = config.admin.components || {}\n config.admin.components.sidebar = config.admin.components.sidebar || {}\n config.admin.components.sidebar.tabs = config.admin.components.sidebar.tabs || []\n\n // Check if tab already exists\n const hasTab = config.admin.components.sidebar.tabs.some((tab) => tab.slug === tabSlug)\n\n if (!hasTab) {\n config.admin.components.sidebar.tabs.push({\n slug: tabSlug,\n components: {\n Content: {\n clientProps: {\n hierarchyCollectionSlug: hierarchyCollection.slug,\n },\n path: '@payloadcms/ui/rsc#HierarchySidebarTabServer',\n },\n Icon,\n },\n label: hierarchyCollection.labels?.plural || hierarchyCollection.slug,\n })\n }\n}\n"],"names":["sanitizeJoinField","fieldAffectsData","extractID","flattenAllFields","getHierarchyFieldName","hierarchyCollectionAfterDelete","injectHierarchyButton","resolveHierarchyCollections","config","hierarchyCollections","collections","filter","col","hierarchy","hierarchyCollection","hierarchyConfig","defaultFieldName","slug","parentFieldName","isParentFieldNameOverridden","collectionSpecific","typeFieldName","fieldName","undefined","allowHasMany","sanitizedRelatedCollections","selfParentField","fields","find","field","name","type","relationTo","custom","injectHeaderButton","collection","hierarchyCollectionSlug","hierarchyField","fieldHasMany","hasMany","injectCollectionSpecificValidation","hierarchySlug","injectTypeField","joinField","injectJoinField","joinFieldConfig","relatedSlugs","Object","keys","relatedCollections","length","injectAfterDeleteHook","injectSidebarTab","existingValidate","validate","value","options","existingResult","collectionSlug","overrideAccess","previousValue","req","newID","parentItem","payload","findByID","id","depth","select","allowedTypes","includes","collectionOptions","map","relatedCollection","c","label","labels","plural","typeField","admin","components","Field","path","serverProps","position","push","flattenedFields","userAdmin","userConfig","hasJoinField","some","on","joins","parentIsLocalized","polymorphicJoins","relatedCollectionFieldMap","relatedConfig","entries","hooks","afterDelete","tabSlug","Icon","sidebar","tabs","hasTab","tab","Content","clientProps"],"mappings":"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"}
@@ -1,14 +0,0 @@
1
- import type { CollectionConfig } from '../collections/config/types.js';
2
- import type { Config } from '../config/types.js';
3
- /**
4
- * Sanitizes hierarchy configuration for a single collection.
5
- *
6
- * This is phase 1 of hierarchy setup, called during individual collection sanitization.
7
- * It normalizes the hierarchy config, creates the parent field if needed, adds hooks,
8
- * and sets up the sanitized config structure.
9
- *
10
- * Phase 2 (`resolveHierarchyCollections`) runs after all collections are sanitized
11
- * to establish cross-collection relationships.
12
- */
13
- export declare const sanitizeHierarchyCollection: (collectionConfig: CollectionConfig, _config: Config) => void;
14
- //# sourceMappingURL=sanitizeHierarchyCollection.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sanitizeHierarchyCollection.d.ts","sourceRoot":"","sources":["../../src/hierarchy/sanitizeHierarchyCollection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAgBhD;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,qBACpB,gBAAgB,WACzB,MAAM,KACd,IA4HF,CAAA"}
@@ -1,112 +0,0 @@
1
- import { fieldAffectsData } from '../fields/config/types.js';
2
- import { slugify as defaultSlugify } from '../utilities/slugify.js';
3
- import { addHierarchyToCollection } from './addHierarchyToCollection.js';
4
- import { buildParentField } from './buildParentField.js';
5
- import { DEFAULT_ALLOW_HAS_MANY, DEFAULT_HIERARCHY_TREE_LIMIT, getHierarchyFieldName, HIERARCHY_SLUG_PATH_FIELD, HIERARCHY_TITLE_PATH_FIELD } from './constants.js';
6
- import { ensureSafeCollectionsChange } from './hooks/ensureSafeCollectionsChange.js';
7
- /**
8
- * Sanitizes hierarchy configuration for a single collection.
9
- *
10
- * This is phase 1 of hierarchy setup, called during individual collection sanitization.
11
- * It normalizes the hierarchy config, creates the parent field if needed, adds hooks,
12
- * and sets up the sanitized config structure.
13
- *
14
- * Phase 2 (`resolveHierarchyCollections`) runs after all collections are sanitized
15
- * to establish cross-collection relationships.
16
- */ export const sanitizeHierarchyCollection = (collectionConfig, _config)=>{
17
- if (!collectionConfig.hierarchy) {
18
- collectionConfig.hierarchy = false;
19
- return;
20
- }
21
- // Normalize boolean to object and apply parentFieldName default
22
- const defaultParentFieldName = getHierarchyFieldName(collectionConfig.slug);
23
- if (collectionConfig.hierarchy === true) {
24
- collectionConfig.hierarchy = {
25
- parentFieldName: defaultParentFieldName
26
- };
27
- }
28
- const parentFieldName = collectionConfig.hierarchy.parentFieldName ?? defaultParentFieldName;
29
- // Check if parent field already exists
30
- const existingParentField = collectionConfig.fields.find((field)=>fieldAffectsData(field) && field.name === parentFieldName);
31
- if (existingParentField) {
32
- // Validate existing parent field configuration
33
- if (existingParentField.type !== 'relationship') {
34
- throw new Error(`Hierarchy parent field "${parentFieldName}" in collection "${collectionConfig.slug}" must be a relationship field`);
35
- }
36
- if (existingParentField.hasMany !== false) {
37
- throw new Error(`Hierarchy parent field "${parentFieldName}" in collection "${collectionConfig.slug}" must have hasMany set to false`);
38
- }
39
- if (existingParentField.localized === true) {
40
- throw new Error(`Hierarchy parent field "${parentFieldName}" in collection "${collectionConfig.slug}" cannot be localized. The parent relationship must be consistent across all locales.`);
41
- }
42
- } else {
43
- // Auto-create parent field if it doesn't exist
44
- // useHeaderButton defaults to true - parent selection via header button with miller columns
45
- const useHeaderButton = collectionConfig.hierarchy.admin?.useHeaderButton ?? true;
46
- const parentField = buildParentField({
47
- collectionSlug: collectionConfig.slug,
48
- injectHeaderButton: useHeaderButton,
49
- parentFieldName
50
- });
51
- collectionConfig.fields.unshift(parentField);
52
- }
53
- // Apply defaults for optional fields
54
- const slugPathFieldName = collectionConfig.hierarchy.slugPathFieldName || HIERARCHY_SLUG_PATH_FIELD;
55
- const titlePathFieldName = collectionConfig.hierarchy.titlePathFieldName || HIERARCHY_TITLE_PATH_FIELD;
56
- const allowHasMany = collectionConfig.hierarchy.allowHasMany ?? DEFAULT_ALLOW_HAS_MANY;
57
- const rawCollectionSpecific = collectionConfig.hierarchy.collectionSpecific;
58
- const collectionSpecific = rawCollectionSpecific === true ? {
59
- fieldName: 'hierarchyType'
60
- } : rawCollectionSpecific ? {
61
- fieldName: rawCollectionSpecific.fieldName ?? 'hierarchyType'
62
- } : false;
63
- const joinField = collectionConfig.hierarchy.joinField ? collectionConfig.hierarchy.joinField : undefined;
64
- const slugify = collectionConfig.hierarchy.slugify ?? ((text)=>defaultSlugify(text) ?? '');
65
- const treeLimit = collectionConfig.hierarchy.admin?.treeLimit ?? DEFAULT_HIERARCHY_TREE_LIMIT;
66
- const iconComponent = collectionConfig.hierarchy.admin?.components?.Icon;
67
- // Apply hierarchy to collection (adds fields and hooks)
68
- addHierarchyToCollection({
69
- collectionConfig,
70
- parentFieldName: collectionConfig.hierarchy.parentFieldName,
71
- slugPathFieldName,
72
- titlePathFieldName
73
- });
74
- // If collectionSpecific, add beforeValidate hook to enforce scope inheritance
75
- // (hierarchyType field is added in resolveHierarchyCollections after discovery)
76
- if (collectionSpecific) {
77
- // Use parentFieldName for both - backward compatible configs use the same field name everywhere
78
- if (!collectionConfig.hooks) {
79
- collectionConfig.hooks = {};
80
- }
81
- if (!collectionConfig.hooks.beforeValidate) {
82
- collectionConfig.hooks.beforeValidate = [];
83
- }
84
- collectionConfig.hooks.beforeValidate.push(ensureSafeCollectionsChange({
85
- folderFieldName: parentFieldName,
86
- foldersSlug: collectionConfig.slug,
87
- parentFieldName,
88
- typeFieldName: collectionSpecific.fieldName
89
- }));
90
- }
91
- // Set sanitized hierarchy config (cast needed as we're transitioning from HierarchyConfig to SanitizedHierarchyConfig)
92
- const useHeaderButton = collectionConfig.hierarchy.admin?.useHeaderButton ?? false;
93
- collectionConfig.hierarchy = {
94
- admin: {
95
- components: {
96
- Icon: iconComponent || '@payloadcms/ui#TagIcon'
97
- },
98
- treeLimit,
99
- useHeaderButton
100
- },
101
- allowHasMany,
102
- collectionSpecific,
103
- joinField,
104
- parentFieldName,
105
- relatedCollections: {},
106
- slugify,
107
- slugPathFieldName,
108
- titlePathFieldName
109
- };
110
- };
111
-
112
- //# sourceMappingURL=sanitizeHierarchyCollection.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/hierarchy/sanitizeHierarchyCollection.ts"],"sourcesContent":["import type { CollectionConfig } from '../collections/config/types.js'\nimport type { Config } from '../config/types.js'\nimport type { SanitizedHierarchyConfig } from './types.js'\n\nimport { fieldAffectsData } from '../fields/config/types.js'\nimport { slugify as defaultSlugify } from '../utilities/slugify.js'\nimport { addHierarchyToCollection } from './addHierarchyToCollection.js'\nimport { buildParentField } from './buildParentField.js'\nimport {\n DEFAULT_ALLOW_HAS_MANY,\n DEFAULT_HIERARCHY_TREE_LIMIT,\n getHierarchyFieldName,\n HIERARCHY_SLUG_PATH_FIELD,\n HIERARCHY_TITLE_PATH_FIELD,\n} from './constants.js'\nimport { ensureSafeCollectionsChange } from './hooks/ensureSafeCollectionsChange.js'\n\n/**\n * Sanitizes hierarchy configuration for a single collection.\n *\n * This is phase 1 of hierarchy setup, called during individual collection sanitization.\n * It normalizes the hierarchy config, creates the parent field if needed, adds hooks,\n * and sets up the sanitized config structure.\n *\n * Phase 2 (`resolveHierarchyCollections`) runs after all collections are sanitized\n * to establish cross-collection relationships.\n */\nexport const sanitizeHierarchyCollection = (\n collectionConfig: CollectionConfig,\n _config: Config,\n): void => {\n if (!collectionConfig.hierarchy) {\n collectionConfig.hierarchy = false\n return\n }\n\n // Normalize boolean to object and apply parentFieldName default\n const defaultParentFieldName = getHierarchyFieldName(collectionConfig.slug)\n\n if (collectionConfig.hierarchy === true) {\n collectionConfig.hierarchy = {\n parentFieldName: defaultParentFieldName,\n }\n }\n\n const parentFieldName = collectionConfig.hierarchy.parentFieldName ?? defaultParentFieldName\n\n // Check if parent field already exists\n const existingParentField = collectionConfig.fields.find(\n (field) => fieldAffectsData(field) && field.name === parentFieldName,\n )\n\n if (existingParentField) {\n // Validate existing parent field configuration\n if (existingParentField.type !== 'relationship') {\n throw new Error(\n `Hierarchy parent field \"${parentFieldName}\" in collection \"${collectionConfig.slug}\" must be a relationship field`,\n )\n }\n\n if (existingParentField.hasMany !== false) {\n throw new Error(\n `Hierarchy parent field \"${parentFieldName}\" in collection \"${collectionConfig.slug}\" must have hasMany set to false`,\n )\n }\n\n if (existingParentField.localized === true) {\n throw new Error(\n `Hierarchy parent field \"${parentFieldName}\" in collection \"${collectionConfig.slug}\" cannot be localized. The parent relationship must be consistent across all locales.`,\n )\n }\n } else {\n // Auto-create parent field if it doesn't exist\n // useHeaderButton defaults to true - parent selection via header button with miller columns\n const useHeaderButton = collectionConfig.hierarchy.admin?.useHeaderButton ?? true\n\n const parentField = buildParentField({\n collectionSlug: collectionConfig.slug,\n injectHeaderButton: useHeaderButton,\n parentFieldName,\n })\n\n collectionConfig.fields.unshift(parentField)\n }\n\n // Apply defaults for optional fields\n const slugPathFieldName =\n collectionConfig.hierarchy.slugPathFieldName || HIERARCHY_SLUG_PATH_FIELD\n const titlePathFieldName =\n collectionConfig.hierarchy.titlePathFieldName || HIERARCHY_TITLE_PATH_FIELD\n const allowHasMany = collectionConfig.hierarchy.allowHasMany ?? DEFAULT_ALLOW_HAS_MANY\n const rawCollectionSpecific = collectionConfig.hierarchy.collectionSpecific\n const collectionSpecific: { fieldName: string } | false =\n rawCollectionSpecific === true\n ? { fieldName: 'hierarchyType' }\n : rawCollectionSpecific\n ? { fieldName: rawCollectionSpecific.fieldName ?? 'hierarchyType' }\n : false\n const joinField = collectionConfig.hierarchy.joinField\n ? collectionConfig.hierarchy.joinField\n : undefined\n const slugify =\n collectionConfig.hierarchy.slugify ?? ((text: string) => defaultSlugify(text) ?? '')\n const treeLimit = collectionConfig.hierarchy.admin?.treeLimit ?? DEFAULT_HIERARCHY_TREE_LIMIT\n const iconComponent = collectionConfig.hierarchy.admin?.components?.Icon\n\n // Apply hierarchy to collection (adds fields and hooks)\n addHierarchyToCollection({\n collectionConfig,\n parentFieldName: collectionConfig.hierarchy.parentFieldName,\n slugPathFieldName,\n titlePathFieldName,\n })\n\n // If collectionSpecific, add beforeValidate hook to enforce scope inheritance\n // (hierarchyType field is added in resolveHierarchyCollections after discovery)\n if (collectionSpecific) {\n // Use parentFieldName for both - backward compatible configs use the same field name everywhere\n if (!collectionConfig.hooks) {\n collectionConfig.hooks = {}\n }\n if (!collectionConfig.hooks.beforeValidate) {\n collectionConfig.hooks.beforeValidate = []\n }\n collectionConfig.hooks.beforeValidate.push(\n ensureSafeCollectionsChange({\n folderFieldName: parentFieldName,\n foldersSlug: collectionConfig.slug,\n parentFieldName,\n typeFieldName: collectionSpecific.fieldName,\n }),\n )\n }\n\n // Set sanitized hierarchy config (cast needed as we're transitioning from HierarchyConfig to SanitizedHierarchyConfig)\n const useHeaderButton = collectionConfig.hierarchy.admin?.useHeaderButton ?? false\n\n ;(collectionConfig as unknown as { hierarchy: SanitizedHierarchyConfig }).hierarchy = {\n admin: {\n components: {\n Icon: iconComponent || '@payloadcms/ui#TagIcon',\n },\n treeLimit,\n useHeaderButton,\n },\n allowHasMany,\n collectionSpecific,\n joinField,\n parentFieldName,\n relatedCollections: {},\n slugify,\n slugPathFieldName,\n titlePathFieldName,\n }\n}\n"],"names":["fieldAffectsData","slugify","defaultSlugify","addHierarchyToCollection","buildParentField","DEFAULT_ALLOW_HAS_MANY","DEFAULT_HIERARCHY_TREE_LIMIT","getHierarchyFieldName","HIERARCHY_SLUG_PATH_FIELD","HIERARCHY_TITLE_PATH_FIELD","ensureSafeCollectionsChange","sanitizeHierarchyCollection","collectionConfig","_config","hierarchy","defaultParentFieldName","slug","parentFieldName","existingParentField","fields","find","field","name","type","Error","hasMany","localized","useHeaderButton","admin","parentField","collectionSlug","injectHeaderButton","unshift","slugPathFieldName","titlePathFieldName","allowHasMany","rawCollectionSpecific","collectionSpecific","fieldName","joinField","undefined","text","treeLimit","iconComponent","components","Icon","hooks","beforeValidate","push","folderFieldName","foldersSlug","typeFieldName","relatedCollections"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,4BAA2B;AAC5D,SAASC,WAAWC,cAAc,QAAQ,0BAAyB;AACnE,SAASC,wBAAwB,QAAQ,gCAA+B;AACxE,SAASC,gBAAgB,QAAQ,wBAAuB;AACxD,SACEC,sBAAsB,EACtBC,4BAA4B,EAC5BC,qBAAqB,EACrBC,yBAAyB,EACzBC,0BAA0B,QACrB,iBAAgB;AACvB,SAASC,2BAA2B,QAAQ,yCAAwC;AAEpF;;;;;;;;;CASC,GACD,OAAO,MAAMC,8BAA8B,CACzCC,kBACAC;IAEA,IAAI,CAACD,iBAAiBE,SAAS,EAAE;QAC/BF,iBAAiBE,SAAS,GAAG;QAC7B;IACF;IAEA,gEAAgE;IAChE,MAAMC,yBAAyBR,sBAAsBK,iBAAiBI,IAAI;IAE1E,IAAIJ,iBAAiBE,SAAS,KAAK,MAAM;QACvCF,iBAAiBE,SAAS,GAAG;YAC3BG,iBAAiBF;QACnB;IACF;IAEA,MAAME,kBAAkBL,iBAAiBE,SAAS,CAACG,eAAe,IAAIF;IAEtE,uCAAuC;IACvC,MAAMG,sBAAsBN,iBAAiBO,MAAM,CAACC,IAAI,CACtD,CAACC,QAAUrB,iBAAiBqB,UAAUA,MAAMC,IAAI,KAAKL;IAGvD,IAAIC,qBAAqB;QACvB,+CAA+C;QAC/C,IAAIA,oBAAoBK,IAAI,KAAK,gBAAgB;YAC/C,MAAM,IAAIC,MACR,CAAC,wBAAwB,EAAEP,gBAAgB,iBAAiB,EAAEL,iBAAiBI,IAAI,CAAC,8BAA8B,CAAC;QAEvH;QAEA,IAAIE,oBAAoBO,OAAO,KAAK,OAAO;YACzC,MAAM,IAAID,MACR,CAAC,wBAAwB,EAAEP,gBAAgB,iBAAiB,EAAEL,iBAAiBI,IAAI,CAAC,gCAAgC,CAAC;QAEzH;QAEA,IAAIE,oBAAoBQ,SAAS,KAAK,MAAM;YAC1C,MAAM,IAAIF,MACR,CAAC,wBAAwB,EAAEP,gBAAgB,iBAAiB,EAAEL,iBAAiBI,IAAI,CAAC,qFAAqF,CAAC;QAE9K;IACF,OAAO;QACL,+CAA+C;QAC/C,4FAA4F;QAC5F,MAAMW,kBAAkBf,iBAAiBE,SAAS,CAACc,KAAK,EAAED,mBAAmB;QAE7E,MAAME,cAAczB,iBAAiB;YACnC0B,gBAAgBlB,iBAAiBI,IAAI;YACrCe,oBAAoBJ;YACpBV;QACF;QAEAL,iBAAiBO,MAAM,CAACa,OAAO,CAACH;IAClC;IAEA,qCAAqC;IACrC,MAAMI,oBACJrB,iBAAiBE,SAAS,CAACmB,iBAAiB,IAAIzB;IAClD,MAAM0B,qBACJtB,iBAAiBE,SAAS,CAACoB,kBAAkB,IAAIzB;IACnD,MAAM0B,eAAevB,iBAAiBE,SAAS,CAACqB,YAAY,IAAI9B;IAChE,MAAM+B,wBAAwBxB,iBAAiBE,SAAS,CAACuB,kBAAkB;IAC3E,MAAMA,qBACJD,0BAA0B,OACtB;QAAEE,WAAW;IAAgB,IAC7BF,wBACE;QAAEE,WAAWF,sBAAsBE,SAAS,IAAI;IAAgB,IAChE;IACR,MAAMC,YAAY3B,iBAAiBE,SAAS,CAACyB,SAAS,GAClD3B,iBAAiBE,SAAS,CAACyB,SAAS,GACpCC;IACJ,MAAMvC,UACJW,iBAAiBE,SAAS,CAACb,OAAO,IAAK,CAAA,CAACwC,OAAiBvC,eAAeuC,SAAS,EAAC;IACpF,MAAMC,YAAY9B,iBAAiBE,SAAS,CAACc,KAAK,EAAEc,aAAapC;IACjE,MAAMqC,gBAAgB/B,iBAAiBE,SAAS,CAACc,KAAK,EAAEgB,YAAYC;IAEpE,wDAAwD;IACxD1C,yBAAyB;QACvBS;QACAK,iBAAiBL,iBAAiBE,SAAS,CAACG,eAAe;QAC3DgB;QACAC;IACF;IAEA,8EAA8E;IAC9E,gFAAgF;IAChF,IAAIG,oBAAoB;QACtB,gGAAgG;QAChG,IAAI,CAACzB,iBAAiBkC,KAAK,EAAE;YAC3BlC,iBAAiBkC,KAAK,GAAG,CAAC;QAC5B;QACA,IAAI,CAAClC,iBAAiBkC,KAAK,CAACC,cAAc,EAAE;YAC1CnC,iBAAiBkC,KAAK,CAACC,cAAc,GAAG,EAAE;QAC5C;QACAnC,iBAAiBkC,KAAK,CAACC,cAAc,CAACC,IAAI,CACxCtC,4BAA4B;YAC1BuC,iBAAiBhC;YACjBiC,aAAatC,iBAAiBI,IAAI;YAClCC;YACAkC,eAAed,mBAAmBC,SAAS;QAC7C;IAEJ;IAEA,uHAAuH;IACvH,MAAMX,kBAAkBf,iBAAiBE,SAAS,CAACc,KAAK,EAAED,mBAAmB;IAE3Ef,iBAAwEE,SAAS,GAAG;QACpFc,OAAO;YACLgB,YAAY;gBACVC,MAAMF,iBAAiB;YACzB;YACAD;YACAf;QACF;QACAQ;QACAE;QACAE;QACAtB;QACAmC,oBAAoB,CAAC;QACrBnD;QACAgC;QACAC;IACF;AACF,EAAC"}