payload 3.84.1 → 4.0.0-internal.d28e9fb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/admin/elements/Nav.d.ts +13 -0
- package/dist/admin/elements/Nav.d.ts.map +1 -1
- package/dist/admin/elements/Nav.js.map +1 -1
- package/dist/admin/functions/index.d.ts +1 -38
- package/dist/admin/functions/index.d.ts.map +1 -1
- package/dist/admin/functions/index.js.map +1 -1
- package/dist/admin/types.d.ts +5 -4
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/admin/types.js.map +1 -1
- package/dist/admin/views/hierarchyList.d.ts +9 -0
- package/dist/admin/views/hierarchyList.d.ts.map +1 -0
- package/dist/admin/views/hierarchyList.js +3 -0
- package/dist/admin/views/hierarchyList.js.map +1 -0
- package/dist/admin/views/index.d.ts +1 -3
- package/dist/admin/views/index.d.ts.map +1 -1
- package/dist/admin/views/index.js.map +1 -1
- package/dist/admin/views/list.d.ts +43 -2
- package/dist/admin/views/list.d.ts.map +1 -1
- package/dist/admin/views/list.js.map +1 -1
- package/dist/bin/generateImportMap/iterateCollections.d.ts.map +1 -1
- package/dist/bin/generateImportMap/iterateCollections.js +1 -0
- package/dist/bin/generateImportMap/iterateCollections.js.map +1 -1
- package/dist/bin/generateImportMap/iterateConfig.d.ts.map +1 -1
- package/dist/bin/generateImportMap/iterateConfig.js +7 -0
- package/dist/bin/generateImportMap/iterateConfig.js.map +1 -1
- package/dist/bin/generateImportMap/iterateGlobals.d.ts.map +1 -1
- package/dist/bin/generateImportMap/iterateGlobals.js +20 -8
- package/dist/bin/generateImportMap/iterateGlobals.js.map +1 -1
- package/dist/bin/index.d.ts.map +1 -1
- package/dist/bin/index.js +1 -3
- package/dist/bin/index.js.map +1 -1
- package/dist/collections/config/client.d.ts +4 -2
- package/dist/collections/config/client.d.ts.map +1 -1
- package/dist/collections/config/client.js +13 -1
- package/dist/collections/config/client.js.map +1 -1
- package/dist/collections/config/defaults.js +1 -1
- package/dist/collections/config/defaults.js.map +1 -1
- package/dist/collections/config/sanitize.d.ts.map +1 -1
- package/dist/collections/config/sanitize.js +231 -184
- package/dist/collections/config/sanitize.js.map +1 -1
- package/dist/collections/config/types.d.ts +76 -91
- package/dist/collections/config/types.d.ts.map +1 -1
- package/dist/collections/config/types.js.map +1 -1
- package/dist/collections/operations/create.d.ts.map +1 -1
- package/dist/collections/operations/create.js +24 -19
- package/dist/collections/operations/create.js.map +1 -1
- package/dist/collections/operations/delete.d.ts.map +1 -1
- package/dist/collections/operations/delete.js +7 -2
- package/dist/collections/operations/delete.js.map +1 -1
- package/dist/collections/operations/deleteByID.d.ts.map +1 -1
- package/dist/collections/operations/deleteByID.js +7 -2
- package/dist/collections/operations/deleteByID.js.map +1 -1
- package/dist/collections/operations/find.d.ts.map +1 -1
- package/dist/collections/operations/find.js +7 -2
- package/dist/collections/operations/find.js.map +1 -1
- package/dist/collections/operations/findByID.d.ts.map +1 -1
- package/dist/collections/operations/findByID.js +10 -5
- package/dist/collections/operations/findByID.js.map +1 -1
- package/dist/collections/operations/findVersionByID.d.ts.map +1 -1
- package/dist/collections/operations/findVersionByID.js +6 -4
- package/dist/collections/operations/findVersionByID.js.map +1 -1
- package/dist/collections/operations/findVersions.d.ts.map +1 -1
- package/dist/collections/operations/findVersions.js +6 -4
- package/dist/collections/operations/findVersions.js.map +1 -1
- package/dist/collections/operations/restoreVersion.d.ts.map +1 -1
- package/dist/collections/operations/restoreVersion.js +7 -2
- package/dist/collections/operations/restoreVersion.js.map +1 -1
- package/dist/collections/operations/update.d.ts.map +1 -1
- package/dist/collections/operations/update.js +7 -2
- package/dist/collections/operations/update.js.map +1 -1
- package/dist/collections/operations/updateByID.d.ts.map +1 -1
- package/dist/collections/operations/updateByID.js +7 -2
- package/dist/collections/operations/updateByID.js.map +1 -1
- package/dist/collections/operations/utilities/update.d.ts.map +1 -1
- package/dist/collections/operations/utilities/update.js +5 -4
- package/dist/collections/operations/utilities/update.js.map +1 -1
- package/dist/config/client.d.ts.map +1 -1
- package/dist/config/client.js +0 -10
- package/dist/config/client.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +0 -15
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/orderable/index.d.ts.map +1 -1
- package/dist/config/orderable/index.js +0 -4
- package/dist/config/orderable/index.js.map +1 -1
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +252 -266
- package/dist/config/sanitize.js.map +1 -1
- package/dist/config/types.d.ts +120 -13
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/exports/internal.d.ts +1 -0
- package/dist/exports/internal.d.ts.map +1 -1
- package/dist/exports/internal.js +1 -0
- package/dist/exports/internal.js.map +1 -1
- package/dist/exports/shared.d.ts +5 -3
- package/dist/exports/shared.d.ts.map +1 -1
- package/dist/exports/shared.js +3 -2
- package/dist/exports/shared.js.map +1 -1
- package/dist/fields/baseFields/slug/index.d.ts.map +1 -1
- package/dist/fields/baseFields/slug/index.js +6 -4
- package/dist/fields/baseFields/slug/index.js.map +1 -1
- package/dist/fields/config/client.d.ts.map +1 -1
- package/dist/fields/config/client.js +3 -2
- package/dist/fields/config/client.js.map +1 -1
- package/dist/fields/config/sanitize.d.ts.map +1 -1
- package/dist/fields/config/sanitize.js +335 -322
- package/dist/fields/config/sanitize.js.map +1 -1
- package/dist/fields/config/sanitizeJoinField.d.ts.map +1 -1
- package/dist/fields/config/sanitizeJoinField.js +3 -0
- package/dist/fields/config/sanitizeJoinField.js.map +1 -1
- package/dist/fields/config/types.d.ts +17 -73
- package/dist/fields/config/types.d.ts.map +1 -1
- package/dist/fields/config/types.js +11 -1
- package/dist/fields/config/types.js.map +1 -1
- package/dist/fields/isFieldDisabled.d.ts +12 -0
- package/dist/fields/isFieldDisabled.d.ts.map +1 -0
- package/dist/fields/isFieldDisabled.js +15 -0
- package/dist/fields/isFieldDisabled.js.map +1 -0
- package/dist/fields/isFieldDisabled.spec.js +134 -0
- package/dist/fields/isFieldDisabled.spec.js.map +1 -0
- package/dist/fields/validations.js +1 -1
- package/dist/fields/validations.js.map +1 -1
- package/dist/globals/config/client.d.ts +1 -1
- package/dist/globals/config/client.d.ts.map +1 -1
- package/dist/globals/config/client.js +2 -1
- package/dist/globals/config/client.js.map +1 -1
- package/dist/globals/config/sanitize.d.ts.map +1 -1
- package/dist/globals/config/sanitize.js +132 -122
- package/dist/globals/config/sanitize.js.map +1 -1
- package/dist/globals/config/types.d.ts +4 -57
- package/dist/globals/config/types.d.ts.map +1 -1
- package/dist/globals/config/types.js.map +1 -1
- package/dist/globals/operations/findOne.d.ts.map +1 -1
- package/dist/globals/operations/findOne.js +7 -2
- package/dist/globals/operations/findOne.js.map +1 -1
- package/dist/globals/operations/findVersionByID.d.ts.map +1 -1
- package/dist/globals/operations/findVersionByID.js +6 -4
- package/dist/globals/operations/findVersionByID.js.map +1 -1
- package/dist/globals/operations/findVersions.d.ts.map +1 -1
- package/dist/globals/operations/findVersions.js +6 -4
- package/dist/globals/operations/findVersions.js.map +1 -1
- package/dist/globals/operations/update.d.ts.map +1 -1
- package/dist/globals/operations/update.js +7 -2
- package/dist/globals/operations/update.js.map +1 -1
- package/dist/hierarchy/addHierarchyToCollection.d.ts +9 -0
- package/dist/hierarchy/addHierarchyToCollection.d.ts.map +1 -0
- package/dist/hierarchy/addHierarchyToCollection.js +76 -0
- package/dist/hierarchy/addHierarchyToCollection.js.map +1 -0
- package/dist/hierarchy/buildParentField.d.ts +11 -0
- package/dist/hierarchy/buildParentField.d.ts.map +1 -0
- package/dist/hierarchy/buildParentField.js +42 -0
- package/dist/hierarchy/buildParentField.js.map +1 -0
- package/dist/hierarchy/constants.d.ts +15 -0
- package/dist/hierarchy/constants.d.ts.map +1 -0
- package/dist/hierarchy/constants.js +11 -0
- package/dist/hierarchy/constants.js.map +1 -0
- package/dist/hierarchy/createFolderField.d.ts +39 -0
- package/dist/hierarchy/createFolderField.d.ts.map +1 -0
- package/dist/hierarchy/createFolderField.js +54 -0
- package/dist/hierarchy/createFolderField.js.map +1 -0
- package/dist/hierarchy/createTagField.d.ts +44 -0
- package/dist/hierarchy/createTagField.d.ts.map +1 -0
- package/dist/hierarchy/createTagField.js +48 -0
- package/dist/hierarchy/createTagField.js.map +1 -0
- package/dist/hierarchy/getInitialTreeData.d.ts +27 -0
- package/dist/hierarchy/getInitialTreeData.d.ts.map +1 -0
- package/dist/hierarchy/getInitialTreeData.js +125 -0
- package/dist/hierarchy/getInitialTreeData.js.map +1 -0
- package/dist/hierarchy/hooks/collectionAfterDelete.d.ts +14 -0
- package/dist/hierarchy/hooks/collectionAfterDelete.d.ts.map +1 -0
- package/dist/hierarchy/hooks/collectionAfterDelete.js +21 -0
- package/dist/hierarchy/hooks/collectionAfterDelete.js.map +1 -0
- package/dist/hierarchy/hooks/collectionAfterRead.d.ts +27 -0
- package/dist/hierarchy/hooks/collectionAfterRead.d.ts.map +1 -0
- package/dist/hierarchy/hooks/collectionAfterRead.js +72 -0
- package/dist/hierarchy/hooks/collectionAfterRead.js.map +1 -0
- package/dist/hierarchy/hooks/collectionBeforeChange.d.ts +19 -0
- package/dist/hierarchy/hooks/collectionBeforeChange.d.ts.map +1 -0
- package/dist/hierarchy/hooks/collectionBeforeChange.js +90 -0
- package/dist/hierarchy/hooks/collectionBeforeChange.js.map +1 -0
- package/dist/hierarchy/hooks/collectionBeforeDelete.d.ts +15 -0
- package/dist/hierarchy/hooks/collectionBeforeDelete.d.ts.map +1 -0
- package/dist/hierarchy/hooks/collectionBeforeDelete.js +20 -0
- package/dist/hierarchy/hooks/collectionBeforeDelete.js.map +1 -0
- package/dist/hierarchy/hooks/collectionBeforeOperation.d.ts +33 -0
- package/dist/hierarchy/hooks/collectionBeforeOperation.d.ts.map +1 -0
- package/dist/hierarchy/hooks/collectionBeforeOperation.js +66 -0
- package/dist/hierarchy/hooks/collectionBeforeOperation.js.map +1 -0
- package/dist/hierarchy/hooks/ensureSafeCollectionsChange.d.ts +8 -0
- package/dist/hierarchy/hooks/ensureSafeCollectionsChange.d.ts.map +1 -0
- package/dist/hierarchy/hooks/ensureSafeCollectionsChange.js +108 -0
- package/dist/hierarchy/hooks/ensureSafeCollectionsChange.js.map +1 -0
- package/dist/hierarchy/injectHierarchyButton.d.ts +14 -0
- package/dist/hierarchy/injectHierarchyButton.d.ts.map +1 -0
- package/dist/hierarchy/injectHierarchyButton.js +37 -0
- package/dist/hierarchy/injectHierarchyButton.js.map +1 -0
- package/dist/hierarchy/presets.d.ts +13 -0
- package/dist/hierarchy/presets.d.ts.map +1 -0
- package/dist/hierarchy/presets.js +52 -0
- package/dist/hierarchy/presets.js.map +1 -0
- package/dist/hierarchy/resolveHierarchyCollections.d.ts +23 -0
- package/dist/hierarchy/resolveHierarchyCollections.d.ts.map +1 -0
- package/dist/hierarchy/resolveHierarchyCollections.js +321 -0
- package/dist/hierarchy/resolveHierarchyCollections.js.map +1 -0
- package/dist/hierarchy/sanitizeHierarchyCollection.d.ts +14 -0
- package/dist/hierarchy/sanitizeHierarchyCollection.d.ts.map +1 -0
- package/dist/hierarchy/sanitizeHierarchyCollection.js +117 -0
- package/dist/hierarchy/sanitizeHierarchyCollection.js.map +1 -0
- package/dist/hierarchy/types.d.ts +155 -0
- package/dist/hierarchy/types.d.ts.map +1 -0
- package/dist/hierarchy/types.js +6 -0
- package/dist/hierarchy/types.js.map +1 -0
- package/dist/hierarchy/utils/buildLocalizedHierarchyPaths.d.ts +77 -0
- package/dist/hierarchy/utils/buildLocalizedHierarchyPaths.d.ts.map +1 -0
- package/dist/hierarchy/utils/buildLocalizedHierarchyPaths.js +77 -0
- package/dist/hierarchy/utils/buildLocalizedHierarchyPaths.js.map +1 -0
- package/dist/hierarchy/utils/computePaths.d.ts +31 -0
- package/dist/hierarchy/utils/computePaths.d.ts.map +1 -0
- package/dist/hierarchy/utils/computePaths.js +445 -0
- package/dist/hierarchy/utils/computePaths.js.map +1 -0
- package/dist/hierarchy/utils/findUseAsTitle.d.ts +14 -0
- package/dist/hierarchy/utils/findUseAsTitle.d.ts.map +1 -0
- package/dist/hierarchy/utils/findUseAsTitle.js +89 -0
- package/dist/hierarchy/utils/findUseAsTitle.js.map +1 -0
- package/dist/hierarchy/utils/getAncestors.d.ts +34 -0
- package/dist/hierarchy/utils/getAncestors.d.ts.map +1 -0
- package/dist/hierarchy/utils/getAncestors.js +94 -0
- package/dist/hierarchy/utils/getAncestors.js.map +1 -0
- package/dist/hierarchy/utils/getLocalizedValue.d.ts +30 -0
- package/dist/hierarchy/utils/getLocalizedValue.d.ts.map +1 -0
- package/dist/hierarchy/utils/getLocalizedValue.js +46 -0
- package/dist/hierarchy/utils/getLocalizedValue.js.map +1 -0
- package/dist/hierarchy/utils/getLocalizedValue.spec.js +250 -0
- package/dist/hierarchy/utils/getLocalizedValue.spec.js.map +1 -0
- package/dist/index.bundled.d.ts +709 -530
- package/dist/index.d.ts +28 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -8
- package/dist/index.js.map +1 -1
- package/dist/preferences/keys.d.ts +8 -4
- package/dist/preferences/keys.d.ts.map +1 -1
- package/dist/preferences/keys.js +7 -4
- package/dist/preferences/keys.js.map +1 -1
- package/dist/preferences/types.d.ts +1 -1
- package/dist/preferences/types.d.ts.map +1 -1
- package/dist/preferences/types.js.map +1 -1
- package/dist/query-presets/config.d.ts.map +1 -1
- package/dist/query-presets/config.js +5 -1
- package/dist/query-presets/config.js.map +1 -1
- package/dist/queues/config/types/index.d.ts +0 -21
- package/dist/queues/config/types/index.d.ts.map +1 -1
- package/dist/queues/config/types/index.js.map +1 -1
- package/dist/queues/config/types/taskTypes.d.ts +0 -20
- package/dist/queues/config/types/taskTypes.d.ts.map +1 -1
- package/dist/queues/config/types/taskTypes.js.map +1 -1
- package/dist/queues/errors/handleWorkflowError.d.ts.map +1 -1
- package/dist/queues/errors/handleWorkflowError.js +9 -1
- package/dist/queues/errors/handleWorkflowError.js.map +1 -1
- package/dist/queues/localAPI.d.ts.map +1 -1
- package/dist/queues/localAPI.js +26 -67
- package/dist/queues/localAPI.js.map +1 -1
- package/dist/queues/operations/handleSchedules/index.d.ts.map +1 -1
- package/dist/queues/operations/handleSchedules/index.js +1 -4
- package/dist/queues/operations/handleSchedules/index.js.map +1 -1
- package/dist/queues/operations/runJobs/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/index.js +40 -37
- package/dist/queues/operations/runJobs/index.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js +3 -22
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.js +0 -2
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.js.map +1 -1
- package/dist/queues/utilities/updateJob.d.ts +1 -3
- package/dist/queues/utilities/updateJob.d.ts.map +1 -1
- package/dist/queues/utilities/updateJob.js +2 -18
- package/dist/queues/utilities/updateJob.js.map +1 -1
- package/dist/types/index.d.ts +44 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/uploads/getBaseFields.d.ts.map +1 -1
- package/dist/uploads/getBaseFields.js +35 -69
- package/dist/uploads/getBaseFields.js.map +1 -1
- package/dist/uploads/getSafeFilename.d.ts +9 -4
- package/dist/uploads/getSafeFilename.d.ts.map +1 -1
- package/dist/uploads/getSafeFilename.js +5 -5
- package/dist/uploads/getSafeFilename.js.map +1 -1
- package/dist/utilities/appendDateTimezoneSelectFields.d.ts +13 -0
- package/dist/utilities/appendDateTimezoneSelectFields.d.ts.map +1 -0
- package/dist/utilities/appendDateTimezoneSelectFields.js +47 -0
- package/dist/utilities/appendDateTimezoneSelectFields.js.map +1 -0
- package/dist/utilities/appendUploadSelectFields.d.ts.map +1 -1
- package/dist/utilities/appendUploadSelectFields.js +3 -0
- package/dist/utilities/appendUploadSelectFields.js.map +1 -1
- package/dist/utilities/extractID.js +1 -1
- package/dist/utilities/extractID.js.map +1 -1
- package/dist/utilities/flattenAllFields.d.ts.map +1 -1
- package/dist/utilities/flattenAllFields.js +102 -93
- package/dist/utilities/flattenAllFields.js.map +1 -1
- package/dist/utilities/formatAdminURL.d.ts +13 -2
- package/dist/utilities/formatAdminURL.d.ts.map +1 -1
- package/dist/utilities/formatAdminURL.js.map +1 -1
- package/dist/utilities/handleEndpoints.d.ts.map +1 -1
- package/dist/utilities/handleEndpoints.js +0 -1
- package/dist/utilities/handleEndpoints.js.map +1 -1
- package/dist/utilities/resolveSelect.d.ts +16 -0
- package/dist/utilities/resolveSelect.d.ts.map +1 -0
- package/dist/utilities/resolveSelect.js +19 -0
- package/dist/utilities/resolveSelect.js.map +1 -0
- package/dist/utilities/sanitizeProfiler.d.ts +38 -0
- package/dist/utilities/sanitizeProfiler.d.ts.map +1 -0
- package/dist/utilities/sanitizeProfiler.js +101 -0
- package/dist/utilities/sanitizeProfiler.js.map +1 -0
- package/dist/utilities/sanitizeSelect.d.ts +1 -2
- package/dist/utilities/sanitizeSelect.d.ts.map +1 -1
- package/dist/utilities/sanitizeSelect.js +19 -25
- package/dist/utilities/sanitizeSelect.js.map +1 -1
- package/dist/versions/baseFields.d.ts.map +1 -1
- package/dist/versions/baseFields.js +3 -2
- package/dist/versions/baseFields.js.map +1 -1
- package/dist/versions/buildCollectionFields.d.ts.map +1 -1
- package/dist/versions/buildCollectionFields.js +0 -1
- package/dist/versions/buildCollectionFields.js.map +1 -1
- package/dist/versions/buildGlobalFields.d.ts.map +1 -1
- package/dist/versions/buildGlobalFields.js +0 -1
- package/dist/versions/buildGlobalFields.js.map +1 -1
- package/dist/versions/payloadPackageList.d.ts.map +1 -1
- package/dist/versions/payloadPackageList.js +0 -1
- package/dist/versions/payloadPackageList.js.map +1 -1
- package/package.json +4 -4
- package/dist/admin/views/folderList.d.ts +0 -56
- package/dist/admin/views/folderList.d.ts.map +0 -1
- package/dist/admin/views/folderList.js +0 -3
- package/dist/admin/views/folderList.js.map +0 -1
- package/dist/folders/addFolderCollection.d.ts +0 -10
- package/dist/folders/addFolderCollection.d.ts.map +0 -1
- package/dist/folders/addFolderCollection.js +0 -26
- package/dist/folders/addFolderCollection.js.map +0 -1
- package/dist/folders/addFolderFieldToCollection.d.ts +0 -8
- package/dist/folders/addFolderFieldToCollection.d.ts.map +0 -1
- package/dist/folders/addFolderFieldToCollection.js +0 -20
- package/dist/folders/addFolderFieldToCollection.js.map +0 -1
- package/dist/folders/buildFolderField.d.ts +0 -8
- package/dist/folders/buildFolderField.d.ts.map +0 -1
- package/dist/folders/buildFolderField.js +0 -87
- package/dist/folders/buildFolderField.js.map +0 -1
- package/dist/folders/constants.d.ts +0 -3
- package/dist/folders/constants.d.ts.map +0 -1
- package/dist/folders/constants.js +0 -4
- package/dist/folders/constants.js.map +0 -1
- package/dist/folders/createFolderCollection.d.ts +0 -11
- package/dist/folders/createFolderCollection.d.ts.map +0 -1
- package/dist/folders/createFolderCollection.js +0 -115
- package/dist/folders/createFolderCollection.js.map +0 -1
- package/dist/folders/hooks/deleteSubfoldersAfterDelete.d.ts +0 -8
- package/dist/folders/hooks/deleteSubfoldersAfterDelete.d.ts.map +0 -1
- package/dist/folders/hooks/deleteSubfoldersAfterDelete.js +0 -15
- package/dist/folders/hooks/deleteSubfoldersAfterDelete.js.map +0 -1
- package/dist/folders/hooks/dissasociateAfterDelete.d.ts +0 -8
- package/dist/folders/hooks/dissasociateAfterDelete.d.ts.map +0 -1
- package/dist/folders/hooks/dissasociateAfterDelete.js +0 -20
- package/dist/folders/hooks/dissasociateAfterDelete.js.map +0 -1
- package/dist/folders/hooks/ensureSafeCollectionsChange.d.ts +0 -5
- package/dist/folders/hooks/ensureSafeCollectionsChange.d.ts.map +0 -1
- package/dist/folders/hooks/ensureSafeCollectionsChange.js +0 -107
- package/dist/folders/hooks/ensureSafeCollectionsChange.js.map +0 -1
- package/dist/folders/hooks/reparentChildFolder.d.ts +0 -24
- package/dist/folders/hooks/reparentChildFolder.d.ts.map +0 -1
- package/dist/folders/hooks/reparentChildFolder.js +0 -72
- package/dist/folders/hooks/reparentChildFolder.js.map +0 -1
- package/dist/folders/types.d.ts +0 -118
- package/dist/folders/types.d.ts.map +0 -1
- package/dist/folders/types.js +0 -3
- package/dist/folders/types.js.map +0 -1
- package/dist/folders/utils/buildFolderWhereConstraints.d.ts +0 -13
- package/dist/folders/utils/buildFolderWhereConstraints.d.ts.map +0 -1
- package/dist/folders/utils/buildFolderWhereConstraints.js +0 -45
- package/dist/folders/utils/buildFolderWhereConstraints.js.map +0 -1
- package/dist/folders/utils/formatFolderOrDocumentItem.d.ts +0 -12
- package/dist/folders/utils/formatFolderOrDocumentItem.d.ts.map +0 -1
- package/dist/folders/utils/formatFolderOrDocumentItem.js +0 -30
- package/dist/folders/utils/formatFolderOrDocumentItem.js.map +0 -1
- package/dist/folders/utils/getFolderBreadcrumbs.d.ts +0 -14
- package/dist/folders/utils/getFolderBreadcrumbs.d.ts.map +0 -1
- package/dist/folders/utils/getFolderBreadcrumbs.js +0 -45
- package/dist/folders/utils/getFolderBreadcrumbs.js.map +0 -1
- package/dist/folders/utils/getFolderData.d.ts +0 -33
- package/dist/folders/utils/getFolderData.d.ts.map +0 -1
- package/dist/folders/utils/getFolderData.js +0 -88
- package/dist/folders/utils/getFolderData.js.map +0 -1
- package/dist/folders/utils/getFoldersAndDocumentsFromJoin.d.ts +0 -24
- package/dist/folders/utils/getFoldersAndDocumentsFromJoin.d.ts.map +0 -1
- package/dist/folders/utils/getFoldersAndDocumentsFromJoin.js +0 -66
- package/dist/folders/utils/getFoldersAndDocumentsFromJoin.js.map +0 -1
- package/dist/folders/utils/getOrphanedDocs.d.ts +0 -15
- package/dist/folders/utils/getOrphanedDocs.d.ts.map +0 -1
- package/dist/folders/utils/getOrphanedDocs.js +0 -40
- package/dist/folders/utils/getOrphanedDocs.js.map +0 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { APIError } from '../../index.js';
|
|
2
|
+
import { extractID } from '../../utilities/extractID.js';
|
|
3
|
+
import { getTranslatedLabel } from '../../utilities/getTranslatedLabel.js';
|
|
4
|
+
export const ensureSafeCollectionsChange = ({ folderFieldName, foldersSlug, parentFieldName = 'folder', typeFieldName = 'hierarchyType' })=>async ({ data, originalDoc, req })=>{
|
|
5
|
+
const currentParentDocID = extractID(originalDoc || {});
|
|
6
|
+
const newParentDocID = extractID(data?.[parentFieldName] || originalDoc?.[parentFieldName] || {});
|
|
7
|
+
if (Array.isArray(data?.[typeFieldName]) && data[typeFieldName].length > 0) {
|
|
8
|
+
const typeFieldValue = data[typeFieldName];
|
|
9
|
+
const currentlyAssignedCollections = Array.isArray(originalDoc?.[typeFieldName]) && originalDoc[typeFieldName].length > 0 ? originalDoc[typeFieldName] : undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Check if the assigned collections have changed.
|
|
12
|
+
* example:
|
|
13
|
+
* - originalAssignedCollections: ['posts', 'pages']
|
|
14
|
+
* - folderType: ['posts']
|
|
15
|
+
*
|
|
16
|
+
* The user is narrowing the types of documents that can be associated with this folder.
|
|
17
|
+
* If the user is only expanding the types of documents that can be associated with this folder,
|
|
18
|
+
* we do not need to do anything.
|
|
19
|
+
*/ const newCollections = currentlyAssignedCollections ? currentlyAssignedCollections.filter((c)=>!typeFieldValue.includes(c)) : typeFieldValue;
|
|
20
|
+
if (newCollections && newCollections.length > 0) {
|
|
21
|
+
let dependentCollection = null;
|
|
22
|
+
if (typeof currentParentDocID === 'string' || typeof currentParentDocID === 'number') {
|
|
23
|
+
// Check each collection being removed for dependent documents
|
|
24
|
+
for (const collectionSlug of newCollections){
|
|
25
|
+
const result = await req.payload.find({
|
|
26
|
+
collection: collectionSlug,
|
|
27
|
+
limit: 1,
|
|
28
|
+
overrideAccess: true,
|
|
29
|
+
req,
|
|
30
|
+
where: {
|
|
31
|
+
[folderFieldName]: {
|
|
32
|
+
equals: currentParentDocID
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
if (result.totalDocs > 0) {
|
|
37
|
+
dependentCollection = collectionSlug;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Also check for child folders with these types
|
|
42
|
+
if (!dependentCollection) {
|
|
43
|
+
const childFoldersResult = await req.payload.find({
|
|
44
|
+
collection: foldersSlug,
|
|
45
|
+
limit: 1,
|
|
46
|
+
overrideAccess: true,
|
|
47
|
+
req,
|
|
48
|
+
where: {
|
|
49
|
+
and: [
|
|
50
|
+
{
|
|
51
|
+
[typeFieldName]: {
|
|
52
|
+
in: newCollections
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
[parentFieldName]: {
|
|
57
|
+
equals: currentParentDocID
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
if (childFoldersResult.totalDocs > 0) {
|
|
64
|
+
dependentCollection = foldersSlug;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (dependentCollection) {
|
|
69
|
+
const translatedLabels = newCollections.map((collectionSlug)=>{
|
|
70
|
+
if (req.payload.collections[collectionSlug]?.config.labels.singular) {
|
|
71
|
+
return getTranslatedLabel(req.payload.collections[collectionSlug]?.config.labels.plural, req.i18n);
|
|
72
|
+
}
|
|
73
|
+
return collectionSlug;
|
|
74
|
+
});
|
|
75
|
+
const isFolder = dependentCollection === foldersSlug;
|
|
76
|
+
throw new APIError(`The folder "${data.name || originalDoc.name}" contains ${isFolder ? 'folders' : 'documents'} that still belong to the following collections: ${translatedLabels.join(', ')}`, 400);
|
|
77
|
+
}
|
|
78
|
+
return data;
|
|
79
|
+
}
|
|
80
|
+
} else if ((data?.[typeFieldName] === null || Array.isArray(data?.[typeFieldName]) && data?.[typeFieldName].length === 0) && newParentDocID) {
|
|
81
|
+
// attempting to set the type to catch-all, so we need to ensure that the parent allows this
|
|
82
|
+
let parentFolder;
|
|
83
|
+
if (typeof newParentDocID === 'string' || typeof newParentDocID === 'number') {
|
|
84
|
+
try {
|
|
85
|
+
parentFolder = await req.payload.findByID({
|
|
86
|
+
id: newParentDocID,
|
|
87
|
+
collection: foldersSlug,
|
|
88
|
+
overrideAccess: true,
|
|
89
|
+
req,
|
|
90
|
+
select: {
|
|
91
|
+
name: true,
|
|
92
|
+
[typeFieldName]: true
|
|
93
|
+
},
|
|
94
|
+
user: req.user
|
|
95
|
+
});
|
|
96
|
+
} catch (_) {
|
|
97
|
+
// parent folder does not exist
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const parentTypeValue = parentFolder?.[typeFieldName];
|
|
101
|
+
if (parentFolder && parentTypeValue && Array.isArray(parentTypeValue) && parentTypeValue.length > 0) {
|
|
102
|
+
throw new APIError(`The folder "${data?.name || originalDoc.name}" must have folder-type set since its parent folder ${parentFolder?.name ? `"${parentFolder?.name}" ` : ''}has a folder-type set.`, 400);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return data;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
//# sourceMappingURL=ensureSafeCollectionsChange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/hierarchy/hooks/ensureSafeCollectionsChange.ts"],"sourcesContent":["import { APIError, type CollectionBeforeValidateHook, type CollectionSlug } from '../../index.js'\nimport { extractID } from '../../utilities/extractID.js'\nimport { getTranslatedLabel } from '../../utilities/getTranslatedLabel.js'\n\nexport const ensureSafeCollectionsChange =\n ({\n folderFieldName,\n foldersSlug,\n parentFieldName = 'folder',\n typeFieldName = 'hierarchyType',\n }: {\n folderFieldName: string\n foldersSlug: CollectionSlug\n parentFieldName?: string\n typeFieldName?: string\n }): CollectionBeforeValidateHook =>\n async ({ data, originalDoc, req }) => {\n const currentParentDocID = extractID(originalDoc || {})\n const newParentDocID = extractID(\n data?.[parentFieldName] || originalDoc?.[parentFieldName] || {},\n )\n if (Array.isArray(data?.[typeFieldName]) && data[typeFieldName].length > 0) {\n const typeFieldValue = data[typeFieldName] as string[]\n const currentlyAssignedCollections: string[] | undefined =\n Array.isArray(originalDoc?.[typeFieldName]) && originalDoc[typeFieldName].length > 0\n ? originalDoc[typeFieldName]\n : undefined\n /**\n * Check if the assigned collections have changed.\n * example:\n * - originalAssignedCollections: ['posts', 'pages']\n * - folderType: ['posts']\n *\n * The user is narrowing the types of documents that can be associated with this folder.\n * If the user is only expanding the types of documents that can be associated with this folder,\n * we do not need to do anything.\n */\n const newCollections = currentlyAssignedCollections\n ? // user is narrowing the current scope of the folder\n currentlyAssignedCollections.filter((c) => !typeFieldValue.includes(c))\n : // user is adding a scope to the folder\n typeFieldValue\n\n if (newCollections && newCollections.length > 0) {\n let dependentCollection: null | string = null\n\n if (typeof currentParentDocID === 'string' || typeof currentParentDocID === 'number') {\n // Check each collection being removed for dependent documents\n for (const collectionSlug of newCollections) {\n const result = await req.payload.find({\n collection: collectionSlug,\n limit: 1,\n overrideAccess: true,\n req,\n where: {\n [folderFieldName]: { equals: currentParentDocID },\n },\n })\n\n if (result.totalDocs > 0) {\n dependentCollection = collectionSlug\n break\n }\n }\n\n // Also check for child folders with these types\n if (!dependentCollection) {\n const childFoldersResult = await req.payload.find({\n collection: foldersSlug,\n limit: 1,\n overrideAccess: true,\n req,\n where: {\n and: [\n { [typeFieldName]: { in: newCollections } },\n { [parentFieldName]: { equals: currentParentDocID } },\n ],\n },\n })\n\n if (childFoldersResult.totalDocs > 0) {\n dependentCollection = foldersSlug\n }\n }\n }\n\n if (dependentCollection) {\n const translatedLabels = newCollections.map((collectionSlug) => {\n if (req.payload.collections[collectionSlug]?.config.labels.singular) {\n return getTranslatedLabel(\n req.payload.collections[collectionSlug]?.config.labels.plural,\n req.i18n,\n )\n }\n return collectionSlug\n })\n\n const isFolder = dependentCollection === foldersSlug\n throw new APIError(\n `The folder \"${data.name || originalDoc.name}\" contains ${isFolder ? 'folders' : 'documents'} that still belong to the following collections: ${translatedLabels.join(', ')}`,\n 400,\n )\n }\n\n return data\n }\n } else if (\n (data?.[typeFieldName] === null ||\n (Array.isArray(data?.[typeFieldName]) && data?.[typeFieldName].length === 0)) &&\n newParentDocID\n ) {\n // attempting to set the type to catch-all, so we need to ensure that the parent allows this\n let parentFolder\n if (typeof newParentDocID === 'string' || typeof newParentDocID === 'number') {\n try {\n parentFolder = await req.payload.findByID({\n id: newParentDocID,\n collection: foldersSlug,\n overrideAccess: true,\n req,\n select: {\n name: true,\n [typeFieldName]: true,\n },\n user: req.user,\n })\n } catch (_) {\n // parent folder does not exist\n }\n }\n\n const parentTypeValue = parentFolder?.[typeFieldName]\n if (\n parentFolder &&\n parentTypeValue &&\n Array.isArray(parentTypeValue) &&\n parentTypeValue.length > 0\n ) {\n throw new APIError(\n `The folder \"${data?.name || originalDoc.name}\" must have folder-type set since its parent folder ${parentFolder?.name ? `\"${parentFolder?.name}\" ` : ''}has a folder-type set.`,\n 400,\n )\n }\n }\n\n return data\n }\n"],"names":["APIError","extractID","getTranslatedLabel","ensureSafeCollectionsChange","folderFieldName","foldersSlug","parentFieldName","typeFieldName","data","originalDoc","req","currentParentDocID","newParentDocID","Array","isArray","length","typeFieldValue","currentlyAssignedCollections","undefined","newCollections","filter","c","includes","dependentCollection","collectionSlug","result","payload","find","collection","limit","overrideAccess","where","equals","totalDocs","childFoldersResult","and","in","translatedLabels","map","collections","config","labels","singular","plural","i18n","isFolder","name","join","parentFolder","findByID","id","select","user","_","parentTypeValue"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FoldersConfig, TagsConfig } from '../collections/config/types.js';
|
|
2
|
+
import type { HierarchyConfig } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Builds hierarchy config from folders preset.
|
|
5
|
+
* Applies folder defaults: allowHasMany: false, FolderIcon, useHeaderButton: true
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildFoldersHierarchy(config: FoldersConfig | true, slug: string): HierarchyConfig;
|
|
8
|
+
/**
|
|
9
|
+
* Builds hierarchy config from tags preset.
|
|
10
|
+
* Applies tag defaults: allowHasMany: true, TagIcon
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildTagsHierarchy(config: TagsConfig | true, slug: string): HierarchyConfig;
|
|
13
|
+
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/hierarchy/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAIjD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAqBjG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAoB3F"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getHierarchyFieldName } from './constants.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds hierarchy config from folders preset.
|
|
4
|
+
* Applies folder defaults: allowHasMany: false, FolderIcon, useHeaderButton: true
|
|
5
|
+
*/ export function buildFoldersHierarchy(config, slug) {
|
|
6
|
+
const options = config === true ? {} : config;
|
|
7
|
+
const parentFieldName = options.parentFieldName ?? getHierarchyFieldName(slug);
|
|
8
|
+
return {
|
|
9
|
+
...options,
|
|
10
|
+
admin: {
|
|
11
|
+
...options.admin,
|
|
12
|
+
components: {
|
|
13
|
+
Icon: {
|
|
14
|
+
clientProps: {
|
|
15
|
+
color: 'muted'
|
|
16
|
+
},
|
|
17
|
+
path: '@payloadcms/ui#FolderIcon'
|
|
18
|
+
},
|
|
19
|
+
...options.admin?.components
|
|
20
|
+
},
|
|
21
|
+
useHeaderButton: options.admin?.useHeaderButton ?? true
|
|
22
|
+
},
|
|
23
|
+
allowHasMany: false,
|
|
24
|
+
parentFieldName
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Builds hierarchy config from tags preset.
|
|
29
|
+
* Applies tag defaults: allowHasMany: true, TagIcon
|
|
30
|
+
*/ export function buildTagsHierarchy(config, slug) {
|
|
31
|
+
const options = config === true ? {} : config;
|
|
32
|
+
const parentFieldName = options.parentFieldName ?? getHierarchyFieldName(slug);
|
|
33
|
+
return {
|
|
34
|
+
...options,
|
|
35
|
+
admin: {
|
|
36
|
+
...options.admin,
|
|
37
|
+
components: {
|
|
38
|
+
Icon: {
|
|
39
|
+
clientProps: {
|
|
40
|
+
color: 'muted'
|
|
41
|
+
},
|
|
42
|
+
path: '@payloadcms/ui#TagIcon'
|
|
43
|
+
},
|
|
44
|
+
...options.admin?.components
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
allowHasMany: options.allowHasMany ?? true,
|
|
48
|
+
parentFieldName
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hierarchy/presets.ts"],"sourcesContent":["import type { FoldersConfig, TagsConfig } from '../collections/config/types.js'\nimport type { HierarchyConfig } from './types.js'\n\nimport { getHierarchyFieldName } from './constants.js'\n\n/**\n * Builds hierarchy config from folders preset.\n * Applies folder defaults: allowHasMany: false, FolderIcon, useHeaderButton: true\n */\nexport function buildFoldersHierarchy(config: FoldersConfig | true, slug: string): HierarchyConfig {\n const options = config === true ? {} : config\n\n const parentFieldName = options.parentFieldName ?? getHierarchyFieldName(slug)\n\n return {\n ...options,\n admin: {\n ...options.admin,\n components: {\n Icon: {\n clientProps: { color: 'muted' },\n path: '@payloadcms/ui#FolderIcon',\n },\n ...options.admin?.components,\n },\n useHeaderButton: options.admin?.useHeaderButton ?? true,\n },\n allowHasMany: false, // Enforced for folders\n parentFieldName,\n }\n}\n\n/**\n * Builds hierarchy config from tags preset.\n * Applies tag defaults: allowHasMany: true, TagIcon\n */\nexport function buildTagsHierarchy(config: TagsConfig | true, slug: string): HierarchyConfig {\n const options = config === true ? {} : config\n\n const parentFieldName = options.parentFieldName ?? getHierarchyFieldName(slug)\n\n return {\n ...options,\n admin: {\n ...options.admin,\n components: {\n Icon: {\n clientProps: { color: 'muted' },\n path: '@payloadcms/ui#TagIcon',\n },\n ...options.admin?.components,\n },\n },\n allowHasMany: options.allowHasMany ?? true, // Default true, can override\n parentFieldName,\n }\n}\n"],"names":["getHierarchyFieldName","buildFoldersHierarchy","config","slug","options","parentFieldName","admin","components","Icon","clientProps","color","path","useHeaderButton","allowHasMany","buildTagsHierarchy"],"mappings":"AAGA,SAASA,qBAAqB,QAAQ,iBAAgB;AAEtD;;;CAGC,GACD,OAAO,SAASC,sBAAsBC,MAA4B,EAAEC,IAAY;IAC9E,MAAMC,UAAUF,WAAW,OAAO,CAAC,IAAIA;IAEvC,MAAMG,kBAAkBD,QAAQC,eAAe,IAAIL,sBAAsBG;IAEzE,OAAO;QACL,GAAGC,OAAO;QACVE,OAAO;YACL,GAAGF,QAAQE,KAAK;YAChBC,YAAY;gBACVC,MAAM;oBACJC,aAAa;wBAAEC,OAAO;oBAAQ;oBAC9BC,MAAM;gBACR;gBACA,GAAGP,QAAQE,KAAK,EAAEC,UAAU;YAC9B;YACAK,iBAAiBR,QAAQE,KAAK,EAAEM,mBAAmB;QACrD;QACAC,cAAc;QACdR;IACF;AACF;AAEA;;;CAGC,GACD,OAAO,SAASS,mBAAmBZ,MAAyB,EAAEC,IAAY;IACxE,MAAMC,UAAUF,WAAW,OAAO,CAAC,IAAIA;IAEvC,MAAMG,kBAAkBD,QAAQC,eAAe,IAAIL,sBAAsBG;IAEzE,OAAO;QACL,GAAGC,OAAO;QACVE,OAAO;YACL,GAAGF,QAAQE,KAAK;YAChBC,YAAY;gBACVC,MAAM;oBACJC,aAAa;wBAAEC,OAAO;oBAAQ;oBAC9BC,MAAM;gBACR;gBACA,GAAGP,QAAQE,KAAK,EAAEC,UAAU;YAC9B;QACF;QACAM,cAAcT,QAAQS,YAAY,IAAI;QACtCR;IACF;AACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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,IAiJ5D,CAAA"}
|
|
@@ -0,0 +1,321 @@
|
|
|
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 (unless explicitly disabled)
|
|
124
|
+
if (hierarchyConfig.admin.injectSidebarTab !== false) {
|
|
125
|
+
injectSidebarTab({
|
|
126
|
+
config,
|
|
127
|
+
hierarchyCollection,
|
|
128
|
+
hierarchyConfig
|
|
129
|
+
});
|
|
130
|
+
// Hide from nav when sidebar tab is injected (unless user explicitly set group)
|
|
131
|
+
if (hierarchyCollection.admin?.group === undefined) {
|
|
132
|
+
hierarchyCollection.admin = {
|
|
133
|
+
...hierarchyCollection.admin,
|
|
134
|
+
group: false
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Injects validation for collectionSpecific hierarchy fields.
|
|
142
|
+
* Ensures the selected hierarchy item allows documents of this collection type.
|
|
143
|
+
*/ function injectCollectionSpecificValidation({ hierarchyField, hierarchySlug, typeFieldName }) {
|
|
144
|
+
const existingValidate = hierarchyField.validate;
|
|
145
|
+
const validate = async (value, options)=>{
|
|
146
|
+
// Run existing validation first if present
|
|
147
|
+
if (existingValidate) {
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
149
|
+
const existingResult = await existingValidate(value, options);
|
|
150
|
+
if (existingResult !== true) {
|
|
151
|
+
return existingResult;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// No hierarchy selected, no validation needed
|
|
155
|
+
if (!value) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
const { collectionSlug, overrideAccess, previousValue, req } = options;
|
|
159
|
+
const newID = extractID(value);
|
|
160
|
+
// Value didn't change, no validation needed
|
|
161
|
+
if (previousValue && extractID(previousValue) === newID) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
// Fetch the hierarchy item to check its type field
|
|
165
|
+
let parentItem = null;
|
|
166
|
+
if (typeof newID === 'string' || typeof newID === 'number') {
|
|
167
|
+
try {
|
|
168
|
+
parentItem = await req.payload.findByID({
|
|
169
|
+
id: newID,
|
|
170
|
+
collection: hierarchySlug,
|
|
171
|
+
depth: 0,
|
|
172
|
+
overrideAccess: overrideAccess ?? false,
|
|
173
|
+
req,
|
|
174
|
+
select: {
|
|
175
|
+
[typeFieldName]: true
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
} catch {
|
|
179
|
+
return `Hierarchy item with ID ${newID} not found`;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (!parentItem) {
|
|
183
|
+
return `Hierarchy item with ID ${newID} not found`;
|
|
184
|
+
}
|
|
185
|
+
const allowedTypes = parentItem[typeFieldName] || [];
|
|
186
|
+
// If hierarchy has no types, it accepts all collections
|
|
187
|
+
if (allowedTypes.length === 0) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
// Check if this collection is allowed
|
|
191
|
+
if (collectionSlug && allowedTypes.includes(collectionSlug)) {
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
return `Hierarchy item "${newID}" does not allow documents of type "${collectionSlug}"`;
|
|
195
|
+
};
|
|
196
|
+
hierarchyField.validate = validate;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Injects the hierarchyType select field into a hierarchy collection.
|
|
200
|
+
*/ function injectTypeField({ config, hierarchyCollection, parentFieldName, sanitizedRelatedCollections, typeFieldName }) {
|
|
201
|
+
const collectionOptions = Object.keys(sanitizedRelatedCollections).map((slug)=>{
|
|
202
|
+
const relatedCollection = config.collections?.find((c)=>c.slug === slug);
|
|
203
|
+
return {
|
|
204
|
+
label: relatedCollection?.labels?.plural || slug,
|
|
205
|
+
value: slug
|
|
206
|
+
};
|
|
207
|
+
});
|
|
208
|
+
const typeField = {
|
|
209
|
+
name: typeFieldName,
|
|
210
|
+
type: 'select',
|
|
211
|
+
admin: {
|
|
212
|
+
components: {
|
|
213
|
+
Field: {
|
|
214
|
+
path: '@payloadcms/next/rsc#HierarchyTypeFieldServer',
|
|
215
|
+
serverProps: {
|
|
216
|
+
collectionOptions,
|
|
217
|
+
parentFieldName
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
position: 'sidebar'
|
|
222
|
+
},
|
|
223
|
+
hasMany: true,
|
|
224
|
+
options: collectionOptions
|
|
225
|
+
};
|
|
226
|
+
hierarchyCollection.fields = hierarchyCollection.fields || [];
|
|
227
|
+
hierarchyCollection.fields.push(typeField);
|
|
228
|
+
// Recompute flattenedFields since we added a field after initial sanitization
|
|
229
|
+
// This is required for the field to be queryable
|
|
230
|
+
if ('flattenedFields' in hierarchyCollection) {
|
|
231
|
+
hierarchyCollection.flattenedFields = flattenAllFields({
|
|
232
|
+
fields: hierarchyCollection.fields
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Injects a join field to query all children of a hierarchy item.
|
|
238
|
+
*/ function injectJoinField({ config, hierarchyCollection, joinFieldConfig, parentFieldName, relatedSlugs }) {
|
|
239
|
+
const { name, admin: userAdmin, ...userConfig } = joinFieldConfig;
|
|
240
|
+
const hasJoinField = hierarchyCollection.fields?.some((field)=>'name' in field && field.name === name);
|
|
241
|
+
if (hasJoinField) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const joinField = {
|
|
245
|
+
// User config (spread first so auto-generated values take precedence for required fields)
|
|
246
|
+
...userConfig,
|
|
247
|
+
// Auto-generated values (these cannot be overridden)
|
|
248
|
+
name,
|
|
249
|
+
type: 'join',
|
|
250
|
+
collection: [
|
|
251
|
+
hierarchyCollection.slug,
|
|
252
|
+
...relatedSlugs
|
|
253
|
+
],
|
|
254
|
+
hasMany: true,
|
|
255
|
+
on: parentFieldName,
|
|
256
|
+
// Merge admin config
|
|
257
|
+
admin: {
|
|
258
|
+
...userAdmin
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
hierarchyCollection.fields = hierarchyCollection.fields || [];
|
|
262
|
+
hierarchyCollection.fields.push(joinField);
|
|
263
|
+
// Sanitize the join field to register it properly
|
|
264
|
+
sanitizeJoinField({
|
|
265
|
+
config,
|
|
266
|
+
field: joinField,
|
|
267
|
+
joins: hierarchyCollection.joins,
|
|
268
|
+
parentIsLocalized: false,
|
|
269
|
+
polymorphicJoins: hierarchyCollection.polymorphicJoins
|
|
270
|
+
});
|
|
271
|
+
// Recompute flattenedFields since we added a field after initial sanitization
|
|
272
|
+
hierarchyCollection.flattenedFields = flattenAllFields({
|
|
273
|
+
fields: hierarchyCollection.fields
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Injects afterDelete hook to clear hierarchy references from related documents.
|
|
278
|
+
*/ function injectAfterDeleteHook({ hierarchyCollection, sanitizedRelatedCollections }) {
|
|
279
|
+
// Build map of collection slugs to their field names
|
|
280
|
+
const relatedCollectionFieldMap = {};
|
|
281
|
+
for (const [slug, relatedConfig] of Object.entries(sanitizedRelatedCollections)){
|
|
282
|
+
relatedCollectionFieldMap[slug] = relatedConfig.fieldName;
|
|
283
|
+
}
|
|
284
|
+
hierarchyCollection.hooks = hierarchyCollection.hooks || {};
|
|
285
|
+
hierarchyCollection.hooks.afterDelete = [
|
|
286
|
+
...hierarchyCollection.hooks.afterDelete || [],
|
|
287
|
+
hierarchyCollectionAfterDelete({
|
|
288
|
+
relatedCollections: relatedCollectionFieldMap
|
|
289
|
+
})
|
|
290
|
+
];
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Injects a sidebar tab for a hierarchy collection.
|
|
294
|
+
*/ function injectSidebarTab({ config, hierarchyCollection, hierarchyConfig }) {
|
|
295
|
+
const tabSlug = `hierarchy-${hierarchyCollection.slug}`;
|
|
296
|
+
const Icon = hierarchyConfig.admin.components.Icon;
|
|
297
|
+
// Initialize admin config structure
|
|
298
|
+
config.admin = config.admin || {};
|
|
299
|
+
config.admin.components = config.admin.components || {};
|
|
300
|
+
config.admin.components.sidebar = config.admin.components.sidebar || {};
|
|
301
|
+
config.admin.components.sidebar.tabs = config.admin.components.sidebar.tabs || [];
|
|
302
|
+
// Check if tab already exists
|
|
303
|
+
const hasTab = config.admin.components.sidebar.tabs.some((tab)=>tab.slug === tabSlug);
|
|
304
|
+
if (!hasTab) {
|
|
305
|
+
config.admin.components.sidebar.tabs.push({
|
|
306
|
+
slug: tabSlug,
|
|
307
|
+
components: {
|
|
308
|
+
Content: {
|
|
309
|
+
clientProps: {
|
|
310
|
+
hierarchyCollectionSlug: hierarchyCollection.slug
|
|
311
|
+
},
|
|
312
|
+
path: '@payloadcms/ui/rsc#HierarchySidebarTabServer'
|
|
313
|
+
},
|
|
314
|
+
Icon
|
|
315
|
+
},
|
|
316
|
+
label: hierarchyCollection.labels?.plural || hierarchyCollection.slug
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
//# sourceMappingURL=resolveHierarchyCollections.js.map
|