export function getConnectedField()

in packages/appsync-modelgen-plugin/src/utils/process-connections.ts [52:119]


export function getConnectedField(field: CodeGenField, model: CodeGenModel, connectedModel: CodeGenModel): CodeGenField {
  const connectionInfo = getDirective(field)('connection');
  if (!connectionInfo) {
    throw new Error(`The ${field.name} on model ${model.name} is not connected`);
  }

  const connectionName = connectionInfo.arguments.name;
  const keyName = connectionInfo.arguments.keyName;
  const connectionFields = connectionInfo.arguments.fields;
  if (connectionFields) {
    let keyDirective;
    if (keyName) {
      keyDirective = connectedModel.directives.find(dir => {
        return dir.name === 'key' && dir.arguments.name === keyName;
      });
      if (!keyDirective) {
        throw new Error(
          `Error processing @connection directive on ${model.name}.${field.name}, @key directive with name ${keyName} was not found in connected model ${connectedModel.name}`,
        );
      }
    } else {
      keyDirective = connectedModel.directives.find(dir => {
        return dir.name === 'key' && typeof dir.arguments.name === 'undefined';
      });
    }

    // when there is a fields argument in the connection
    const connectedFieldName = keyDirective ? keyDirective.arguments.fields[0] : DEFAULT_HASH_KEY_FIELD;

    // Find a field on the other side which connected by a @connection and has the same fields[0] as keyName field
    const otherSideConnectedField = connectedModel.fields.find(f => {
      return f.directives.find(d => {
        return d.name === 'connection' && d.arguments.fields && d.arguments.fields[0] === connectedFieldName;
      });
    });
    if (otherSideConnectedField) {
      return otherSideConnectedField;
    }
    // If there are no field with @connection with keyName then try to find a field that has same name as connection name
    const connectedField = connectedModel.fields.find(f => f.name === connectedFieldName);

    if (!connectedField) {
      throw new Error(`Can not find key field ${connectedFieldName} in ${connectedModel}`);
    }
    return connectedField;
  } else if (connectionName) {
    // when the connection is named
    const connectedField = connectedModel.fields.find(f =>
      f.directives.find(d => d.name === 'connection' && d.arguments.name === connectionName && f !== field),
    );
    if (!connectedField) {
      throw new Error(`Can not find key field with connection name ${connectionName} in ${connectedModel}`);
    }
    return connectedField;
  }
  // un-named connection. Use an existing field or generate a new field
  const connectedFieldName = makeConnectionAttributeName(model.name, field.name);
  const connectedField = connectedModel.fields.find(f => f.name === connectedFieldName);
  return connectedField
    ? connectedField
    : {
        name: connectedFieldName,
        directives: [],
        type: 'ID',
        isList: false,
        isNullable: true,
      };
}