@aws-amplify/appsync-modelgen-plugin
Version:
177 lines • 8.43 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.processConnections = exports.getConnectedField = exports.flattenFieldDirectives = exports.makeConnectionAttributeName = exports.CodeGenConnectionType = void 0;
const fieldUtils_1 = require("./fieldUtils");
const fieldUtils_2 = require("./fieldUtils");
const constants_1 = require("./constants");
var CodeGenConnectionType;
(function (CodeGenConnectionType) {
CodeGenConnectionType["HAS_ONE"] = "HAS_ONE";
CodeGenConnectionType["BELONGS_TO"] = "BELONGS_TO";
CodeGenConnectionType["HAS_MANY"] = "HAS_MANY";
})(CodeGenConnectionType = exports.CodeGenConnectionType || (exports.CodeGenConnectionType = {}));
function makeConnectionAttributeName(type, field, otherSidePrimaryKeyComponentField = 'id') {
return field ? (0, fieldUtils_1.toCamelCase)([type, field, otherSidePrimaryKeyComponentField]) : (0, fieldUtils_1.toCamelCase)([type, otherSidePrimaryKeyComponentField]);
}
exports.makeConnectionAttributeName = makeConnectionAttributeName;
function flattenFieldDirectives(model) {
let totalDirectives = new Array();
model.fields.forEach(field => {
field.directives.forEach(dir => {
let fieldDir = dir;
fieldDir.fieldName = field.name;
totalDirectives.push(fieldDir);
});
});
return totalDirectives;
}
exports.flattenFieldDirectives = flattenFieldDirectives;
function getConnectedField(field, model, connectedModel) {
const connectionInfo = (0, fieldUtils_2.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';
});
}
const connectedFieldName = keyDirective ? keyDirective.arguments.fields[0] : constants_1.DEFAULT_HASH_KEY_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;
}
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) {
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;
}
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,
};
}
exports.getConnectedField = getConnectedField;
function processConnections(field, model, modelMap, isDataStoreEnabled) {
const connectionDirective = field.directives.find(d => d.name === 'connection');
if (connectionDirective) {
const otherSide = modelMap[field.type];
const connectionFields = connectionDirective.arguments.fields || [];
const otherSideField = getConnectedField(field, model, otherSide);
const isNewField = !otherSide.fields.includes(otherSideField);
const isConnectingFieldAutoCreated = connectionFields.length === 0;
if (!isNewField) {
if (field.isList && !otherSideField.isList) {
return {
kind: CodeGenConnectionType.HAS_MANY,
associatedWith: otherSideField,
associatedWithFields: [],
isConnectingFieldAutoCreated,
connectedModel: otherSide,
};
}
else if (!field.isList && otherSideField.isList) {
if (connectionFields.length > 1) {
throw new Error('DataStore only support one key in field');
}
return {
kind: CodeGenConnectionType.BELONGS_TO,
connectedModel: otherSide,
isConnectingFieldAutoCreated,
targetName: connectionFields[0] || makeConnectionAttributeName(model.name, field.name),
targetNames: []
};
}
else if (!field.isList && !otherSideField.isList) {
if (!field.isNullable && otherSideField.isNullable) {
return {
kind: CodeGenConnectionType.BELONGS_TO,
connectedModel: otherSide,
isConnectingFieldAutoCreated,
targetName: connectionFields[0] || makeConnectionAttributeName(model.name, field.name),
targetNames: []
};
}
else if ((field.isNullable && !otherSideField.isNullable) || !isDataStoreEnabled) {
return {
kind: CodeGenConnectionType.HAS_ONE,
associatedWith: otherSideField,
associatedWithFields: [],
connectedModel: otherSide,
isConnectingFieldAutoCreated,
targetName: connectionFields[0] || makeConnectionAttributeName(model.name, field.name),
targetNames: []
};
}
else {
throw new Error(`DataStore does not support 1 to 1 connection with both sides of connection as optional field: ${model.name}.${field.name}`);
}
}
}
else {
if (field.isList) {
const connectionFieldName = makeConnectionAttributeName(model.name, field.name);
const existingConnectionField = otherSide.fields.find(f => f.name === connectionFieldName);
return {
kind: CodeGenConnectionType.HAS_MANY,
connectedModel: otherSide,
isConnectingFieldAutoCreated,
associatedWith: existingConnectionField || {
name: connectionFieldName,
type: 'ID',
isList: false,
isNullable: true,
directives: [],
},
associatedWithFields: [],
};
}
else {
if (connectionFields.length > 1) {
throw new Error('DataStore only support one key in field');
}
return {
kind: CodeGenConnectionType.BELONGS_TO,
connectedModel: otherSide,
isConnectingFieldAutoCreated,
targetName: connectionFields[0] || makeConnectionAttributeName(model.name, field.name),
targetNames: []
};
}
}
}
}
exports.processConnections = processConnections;
//# sourceMappingURL=process-connections.js.map