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;
  }
}