export function parseAvailabilityTags()

in compiler/src/model/utils.ts [1159:1208]


export function parseAvailabilityTags (node: Node | Node[], values: string[]): model.Availability {
  return values.reduce((result, value, index, array) => {
    // Ensure that there is actually a name for this availability definition.
    assert(node, value.split(' ').length >= 1, 'The @availability tag must include a name (either stack or serverless)')
    const [availabilityName, ...values] = value.split(' ')

    // Since we're using reduce() we need to check that there's no duplicates.
    assert(node, !(availabilityName in result), `Duplicate @availability tag: '${availabilityName}'`)

    // Enforce only known availability names.
    assert(node, availabilityName === 'stack' || availabilityName === 'serverless', 'The @availablility <name> value must either be stack or serverless')

    // Now we can parse all the key-values and load them into variables
    // for easier access below.
    const validKeys = ['stability', 'visibility', 'since', 'feature_flag']
    const parsedKeyValues = parseKeyValues(node, values, ...validKeys)
    const visibility = parsedKeyValues.visibility
    const stability = parsedKeyValues.stability
    const since = parsedKeyValues.since
    const featureFlag = parsedKeyValues.feature_flag

    // Remove the 'feature_flag' name used in the annotations
    // in favor of 'featureFlag' as used in the metamodel.
    delete parsedKeyValues.feature_flag

    // Lastly we go through all the fields and validate them.
    if (visibility !== undefined) {
      parsedKeyValues.visibility = model.Visibility[visibility]
      assert(node, parsedKeyValues.visibility !== undefined, `visibility is not valid: ${visibility}`)
      if (visibility === model.Visibility.feature_flag) {
        assert(node, featureFlag !== undefined, '\'feature_flag\' must be defined if visibility is \'feature_flag\'')
      }
    }
    if (stability !== undefined) {
      parsedKeyValues.stability = model.Stability[stability]
      assert(node, parsedKeyValues.stability !== undefined, `stability is not valid: ${stability}`)
    }
    if (since !== undefined) {
      assert(node, semver.valid(since), `'since' is not valid semver: ${since}`)
    }
    if (featureFlag !== undefined) {
      assert(node, visibility === 'feature_flag', '\'visibility\' must be \'feature_flag\' if a feature flag is defined')
      parsedKeyValues.featureFlag = featureFlag
    }

    // Add the computed set of fields to the result.
    result[availabilityName] = parsedKeyValues
    return result
  }, {})
}