# All files / build-tools massage-spec.ts

61.53% Statements 16/26
45.45% Branches 5/11
71.42% Functions 5/7
61.53% Lines 16/26

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
    711x
    1x

    1x
    1x
    1x
    1x

    1x
    1x

    1x
    1x
    1x
    1x
    2x
    2x
    1x

    1x

     import { schema } from '../lib';
    import { detectScrutinyTypes } from './scrutiny';

    export function massageSpec(spec: schema.Specification) {
      detectScrutinyTypes(spec);
      replaceIncompleteTypes(spec);
      dropTypelessAttributes(spec);
    }

    /**
     * Fix incomplete type definitions in PropertyTypes
     *
     * Some user-defined types are defined to not have any properties, and not
     * be a collection of other types either. They have no definition at all.
     *
     * Add a property object type with empty properties.
     */
    function replaceIncompleteTypes(spec: schema.Specification) {
      for (const [name, definition] of Object.entries(spec.PropertyTypes)) {
        Iif (!schema.isRecordType(definition)
        && !schema.isCollectionProperty(definition)
        && !schema.isScalarProperty(definition)
        && !schema.isPrimitiveProperty(definition)) {
          // eslint-disable-next-line no-console
          console.log(`[${name}] Incomplete type, adding empty "Properties" field`);

          (definition as unknown as schema.RecordProperty).Properties = {};
        }
      }
    }

    /**
     * Drop Attributes specified with the different ResourceTypes that have
     * no type specified.
     */
    function dropTypelessAttributes(spec: schema.Specification) {
      const resourceTypes = spec.ResourceTypes;
      Object.values(resourceTypes).forEach((resourceType) => {
        const attributes = resourceType.Attributes ?? {};
        Object.keys(attributes).forEach((attrKey) => {
          const attrVal = attributes[attrKey];
          if (Object.keys(attrVal).length === 0) {
            delete attributes[attrKey];
          }
        });
      });
    }

    /**
     * Modifies the provided specification so that ``ResourceTypes`` and ``PropertyTypes`` are listed in alphabetical order.
     *
     * @param spec an AWS CloudFormation Resource Specification document.
     *
     * @returns ``spec``, after having sorted the ``ResourceTypes`` and ``PropertyTypes`` sections alphabetically.
     */
    export function normalize(spec: schema.Specification): schema.Specification {
      spec.ResourceTypes = normalizeSection(spec.ResourceTypes);
      Iif (spec.PropertyTypes) {
        spec.PropertyTypes = normalizeSection(spec.PropertyTypes);
      }
      return spec;

      function normalizeSection<T>(section: { [name: string]: T }): { [name: string]: T } {
        const result: { [name: string]: T } = {};
        for (const key of Object.keys(section).sort()) {
          result[key] = section[key];
        }
        return result;
      }
    }