All files / modules/75-cf/pages/target-group-detail/components/FlagSettingsPanel flagSettingsInstructions.ts

100% Statements 30/30
81.25% Branches 13/16
100% Functions 12/12
100% Lines 29/29

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                3x       3x       6x 6x 6x   6x 4x     6x 2x     6x     3x       8x 32x     3x       8x 28x       3x       6x     7x         3x       4x     5x                 3x 4x     5x               3x     12x 1x                   11x    
/*
 * Copyright 2022 Harness Inc. All rights reserved.
 * Use of this source code is governed by the PolyForm Shield 1.0.0 license
 * that can be found in the licenses directory at the root of this repository, also available at
 * https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
 */
 
import type { Distribution } from 'services/cf'
import { PERCENTAGE_ROLLOUT_VALUE } from '@cf/constants'
import type { Instruction } from '@cf/utils/instructions'
import type { FlagSettingsFormData, FlagSettingsFormRow, TargetGroupFlagsMap } from '../../TargetGroupDetailPage.types'
 
export function getFlagSettingsInstructions(
  flags: FlagSettingsFormData['flags'],
  targetGroupFlagsMap: TargetGroupFlagsMap
): Instruction[] {
  const instructions = []
  const removedFlagIdentifiers = getRemovedFlagIdentifiers(flags, targetGroupFlagsMap)
  const updatedFlags = getUpdatedFlags(flags, targetGroupFlagsMap)
 
  if (removedFlagIdentifiers.length) {
    instructions.push(getRemoveFlagsInstruction(removedFlagIdentifiers, targetGroupFlagsMap))
  }
 
  if (updatedFlags.length) {
    instructions.push(getUpdateFlagsInstruction(updatedFlags, targetGroupFlagsMap))
  }
 
  return instructions
}
 
export function getRemovedFlagIdentifiers(
  flags: FlagSettingsFormData['flags'],
  targetGroupFlagsMap: TargetGroupFlagsMap
): string[] {
  const newKeys = Object.keys(flags)
  return Object.keys(targetGroupFlagsMap).filter(oldKey => !newKeys.includes(oldKey))
}
 
export function getUpdatedFlags(
  flags: FlagSettingsFormData['flags'],
  targetGroupFlagsMap: TargetGroupFlagsMap
): FlagSettingsFormRow[] {
  return Object.values(flags).filter(
    ({ identifier, variation }) => targetGroupFlagsMap[identifier]?.variation !== variation
  )
}
 
export function getRemoveFlagsInstruction(
  identifiers: string[],
  targetGroupFlagsMap: TargetGroupFlagsMap
): Instruction {
  return {
    kind: 'removeRule',
    parameters: {
      features: identifiers.map(identifier => ({ ruleID: targetGroupFlagsMap[identifier].ruleId }))
    }
  } as any as Instruction
}
 
export function getUpdateFlagsInstruction(
  flags: FlagSettingsFormRow[],
  targetGroupFlagsMap: TargetGroupFlagsMap
): Instruction {
  return {
    kind: 'addRule',
    parameters: {
      features: flags.map(row => ({
        identifier: row.identifier,
        ...getVariationOrServe(row),
        ruleID: targetGroupFlagsMap[row.identifier].ruleId as string
      }))
    }
  } as any as Instruction
}
 
export function getAddFlagsInstruction(flags: FlagSettingsFormRow[]): Instruction {
  return {
    kind: 'addRule',
    parameters: {
      features: flags.map(row => ({
        identifier: row.identifier,
        ...getVariationOrServe(row)
      }))
    }
  } as any as Instruction
}
 
export function getVariationOrServe(
  row: FlagSettingsFormRow
): { variation: string } | { serve: { distribution: Distribution } } {
  if (row.variation === PERCENTAGE_ROLLOUT_VALUE) {
    return {
      serve: {
        distribution: {
          bucketBy: 'identifier',
          variations: row.percentageRollout?.variations || []
        }
      }
    }
  }
 
  return { variation: row.variation }
}