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