All files / libs/data-capture/connectors/library/src/validation/jsonSchema dataConnectorObjectToSchema.transformer.ts

92.59% Statements 100/108
83.33% Branches 20/24
100% Functions 5/5
92.59% Lines 100/108

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 1091x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 1x 1x 1x 1x 1x 1x 9x 9x 1x 9x 1x 9x 9x 2x 9x   9x 1x 9x 1x 9x 2x 9x         9x 1x 9x 9x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 9x 1x 1x       1x 1x 9x 9x 9x 1x  
import { keyBy } from 'lodash-es';
 
import { type DataConnectorObjectField } from '@amalia/data-capture/connectors/types';
import { FormatsEnum, PropertyRef, type Property } from '@amalia/data-capture/fields/types';
import { type Properties } from '@amalia/data-capture/record-models/types';
import { StringUtils } from '@amalia/ext/string';
 
export class DataConnectorObjectToSchemaTransformer {
  public static transform(
    fields: DataConnectorObjectField[],
    shouldCamelCaseNames: boolean = true,
  ): { properties: Properties; requiredProperties: string[] } {
    const properties = this.transformToComputedSchema(fields, shouldCamelCaseNames);
    const requiredProperties = Object.values(properties)
      .filter((p): p is Property => !!p && !!p.isRequired)
      .map((p) => p.machineName);
 
    return {
      requiredProperties,
      properties,
    };
  }
 
  private static transformToComputedSchema(
    fields: DataConnectorObjectField[],
    shouldCamelCaseNames: boolean,
  ): Properties {
    return keyBy(
      fields.map((field) => {
        const { format, isEnum } = this.getFieldFormat(field);
        const ref = this.getFieldRef(field);
 
        return {
          name: field.label,
          machineName: this.getFieldMachineName(field, shouldCamelCaseNames),
          isEnum,
          format,
          isRequired: !!field.isId,
          ...(ref && { ref }),
        };
      }),
      'machineName',
    );
  }
 
  private static getFieldFormat(field: DataConnectorObjectField): { format: FormatsEnum; isEnum?: boolean } {
    switch (field.type) {
      case 'currency':
        return { format: FormatsEnum.currency };
      case 'date':
        return { format: FormatsEnum.date };
      case 'datetime':
      case 'time':
        return { format: FormatsEnum['date-time'] };
      case 'boolean':
        return { format: FormatsEnum.boolean };
      case 'percent':
        return { format: FormatsEnum.percent };
      case 'number':
        return { format: FormatsEnum.number };
      case 'string':
        return { format: FormatsEnum.text };
      case 'enum':
        return {
          format: FormatsEnum.text,
          isEnum: true,
        };
      default:
        return { format: FormatsEnum.text };
    }
  }
 
  /**
   * Get field ref if present, otherwise return undefined.
   * The field ref is used to link a field to another object.
   *
   * @example
   *
   * {
   *   "isId": false,
   *   "name": "OwnerId",
   *   "type": "string",
   *   "label": "Owner ID",
   *   "isName": false,
   *   "unique": false,
   *   "isMandatory": true,
   *   "referenceTo": [
   *     "User"
   *   ],
   *   "matchingField": "",
   *   "relationshipName": "Owner"
   * },
   *
   * This will return PropertyRef.USER
   */
  private static getFieldRef(field: DataConnectorObjectField): PropertyRef | null {
    if (!field.referenceTo) return null;
 
    if (field.referenceTo.includes('User')) return PropertyRef.USER;

    return null;
  }
 
  private static getFieldMachineName(field: DataConnectorObjectField, shouldCamelCase: boolean): string {
    const fieldName = field.overrideName || field.name;
    return shouldCamelCase ? StringUtils.camelCase(fieldName) : fieldName;
  }
}