All files / src/utils generatePermissions.ts

100% Statements 20/20
75% Branches 6/8
100% Functions 5/5
100% Lines 19/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132  3x   3x     3x                                                                             3x                 66x 303x     303x                 1212x                               303x 1x                   303x       66x   4x 4x   4x             66x                       3x 1212x           1212x    
import type { CollectionConfig } from 'payload'
import { CRUD_OPERATIONS, PERMISSIONS } from '../constants'
import type { Permission } from '../types'
import { formatLabel } from './formatLabel'
 
// Pre-defined special permissions for better performance
const SPECIAL_PERMISSIONS: Permission[] = [
  {
    label: '⭐ Full Access (Super Admin)',
    value: PERMISSIONS.ALL,
    category: 'Special',
    description: 'Complete system access'
  },
  {
    label: '📖 All Read Access',
    value: PERMISSIONS.ALL_READ,
    category: 'Special',
    description: 'Read access to all collections'
  },
  {
    label: '✏️ All Create Access',
    value: PERMISSIONS.ALL_CREATE,
    category: 'Special',
    description: 'Create access to all collections'
  },
  {
    label: '📝 All Update Access',
    value: PERMISSIONS.ALL_UPDATE,
    category: 'Special',
    description: 'Update access to all collections'
  },
  {
    label: '🗑️ All Delete Access',
    value: PERMISSIONS.ALL_DELETE,
    category: 'Special',
    description: 'Delete access to all collections'
  }
]
 
 
 
/**
 * Generate permissions for all collections dynamically
 * Optimized with functional programming and pre-computed constants
 */
export const generateCollectionPermissions = (
  collections: CollectionConfig[],
  customPermissions?: Array<{
    label: string
    value: string
    description?: string
  }>
): Permission[] => {
  // Use flatMap for more efficient array building
  const collectionPermissions = collections.flatMap(collection => {
    const collectionLabel = formatLabel(collection.slug)
    
    // Build all permissions for this collection in one array
    const basePermissions: Permission[] = [
      // Collection wildcard
      {
        label: `All ${collectionLabel} Operations`,
        value: `${collection.slug}.*`,
        category: collectionLabel,
        description: `All operations for ${collectionLabel}`
      },
      // CRUD permissions using map
      ...CRUD_OPERATIONS.map(operation => ({
        label: `${getOperationLabel(operation)} ${collectionLabel}`,
        value: `${collection.slug}.${operation}`,
        category: collectionLabel,
        description: `${operation} permission for ${collectionLabel}`
      })),
      // Manage permission
      {
        label: `Manage ${collectionLabel}`,
        value: `${collection.slug}.manage`,
        category: collectionLabel,
        description: `Full management of ${collectionLabel}`
      }
    ]
 
    // Add conditional permissions inline
    if (collection.versions) {
      basePermissions.push({
        label: `Publish ${collectionLabel}`,
        value: `${collection.slug}.publish`,
        category: collectionLabel,
        description: `Publish ${collectionLabel} versions`
      })
    }
 
 
 
    return basePermissions
  })
 
  // Process custom permissions - extract and format namespace as category
  const processedCustomPermissions: Permission[] = customPermissions?.map(perm => {
    // Extract namespace from value (part before the dot)
    const namespace = perm.value.split('.')[0]
    const formattedCategory = namespace ? formatLabel(namespace) : undefined
    
    return {
      ...perm,
      category: formattedCategory
    }
  }) || []
 
  // Combine all permissions in a single return
  return [
    ...SPECIAL_PERMISSIONS,
    ...collectionPermissions,
    ...processedCustomPermissions
  ]
}
 
 
 
/**
 * Get operation label
 */
const getOperationLabel = (operation: string): string => {
  const labels: Record<string, string> = {
    create: 'Create',
    read: 'Read',
    update: 'Edit',
    delete: 'Delete',
  }
  return labels[operation] || operation
}