UNPKG

@aws-amplify/appsync-modelgen-plugin

Version:
145 lines 7.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.addHasManyKey = exports.hasManyHasImplicitKey = exports.getConnectedFieldsForHasMany = exports.processHasManyConnection = void 0; const constants_1 = require("./constants"); const fieldUtils_1 = require("./fieldUtils"); const fieldUtils_2 = require("./fieldUtils"); const process_connections_1 = require("./process-connections"); const process_connections_v2_1 = require("./process-connections-v2"); function processHasManyConnection(field, model, modelMap, connectionDirective, shouldUseModelNameFieldInHasManyAndBelongsTo, isCustomPKEnabled = false) { if (!field.isList) { throw new Error("A field with hasMany must be a list type"); } const otherSide = modelMap[field.type]; const connectionFields = connectionDirective.arguments.fields || []; const references = connectionDirective.arguments.references || []; if (references.length > 0) { const associatedWithNativeReferences = (0, process_connections_v2_1.getConnectedFieldForReferences)(field, model, otherSide, connectionDirective.name); const associatedWithFields = references.map((reference) => otherSide.fields.find((field) => reference === field.name)); return { kind: process_connections_1.CodeGenConnectionType.HAS_MANY, associatedWith: associatedWithFields[0], associatedWithFields, associatedWithNativeReferences, isConnectingFieldAutoCreated: false, connectedModel: otherSide, }; } const otherSideFields = isCustomPKEnabled ? getConnectedFieldsForHasMany(field, model, otherSide, shouldUseModelNameFieldInHasManyAndBelongsTo) : [(0, process_connections_v2_1.getConnectedFieldV2)(field, model, otherSide, connectionDirective.name, shouldUseModelNameFieldInHasManyAndBelongsTo)]; const otherSideField = otherSideFields[0]; const isConnectingFieldAutoCreated = connectionFields.length === 0; return { kind: process_connections_1.CodeGenConnectionType.HAS_MANY, associatedWith: otherSideField, associatedWithFields: otherSideFields, isConnectingFieldAutoCreated, connectedModel: otherSide, }; } exports.processHasManyConnection = processHasManyConnection; function getConnectedFieldsForHasMany(field, model, connectedModel, shouldUseModelNameFieldInHasManyAndBelongsTo) { var _a, _b, _c; const hasManyDir = (0, fieldUtils_1.getDirective)(field)(constants_1.TransformerV2DirectiveName.HAS_MANY); if (!hasManyDir) { throw new Error(`The ${field.name} on model ${model.name} is not connected`); } let otherSideConnectedField; const indexName = hasManyDir.arguments.indexName; const indexMatchingFields = hasManyDir.arguments.fields; if (indexMatchingFields) { let otherSideConnectedDir; const otherSideFieldDirectives = (0, process_connections_1.flattenFieldDirectives)(connectedModel); if (indexName) { otherSideConnectedDir = otherSideFieldDirectives.find(dir => { return dir.name === constants_1.TransformerV2DirectiveName.INDEX && dir.arguments.name === indexName; }); if (!otherSideConnectedDir) { throw new Error(`Error processing @hasMany directive on ${model.name}.${field.name}, @index directive with name ${indexName} was not found in connected model ${connectedModel.name}`); } } else { otherSideConnectedDir = otherSideFieldDirectives.find(dir => { return dir.name === constants_1.TransformerV2DirectiveName.PRIMARY_KEY; }); } const otherSideConnectedFieldName = (_c = (_a = otherSideConnectedDir === null || otherSideConnectedDir === void 0 ? void 0 : otherSideConnectedDir.fieldName) !== null && _a !== void 0 ? _a : (_b = (0, fieldUtils_1.getOtherSideBelongsToField)(model.name, connectedModel)) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : constants_1.DEFAULT_HASH_KEY_FIELD; otherSideConnectedField = connectedModel.fields .filter(f => f.type === model.name) .find(f => f.directives.find(d => (d.name === constants_1.TransformerV2DirectiveName.BELONGS_TO) && d.arguments.fields && d.arguments.fields[0] === otherSideConnectedFieldName)); if (otherSideConnectedField) { return [otherSideConnectedField]; } otherSideConnectedField = connectedModel.fields.find(f => f.name === otherSideConnectedFieldName); if (!otherSideConnectedField) { throw new Error(`Can not find key field ${otherSideConnectedFieldName} in ${connectedModel.name}`); } return [otherSideConnectedField]; } if (shouldUseModelNameFieldInHasManyAndBelongsTo) { otherSideConnectedField = connectedModel.fields .filter(f => f.type === model.name) .find(f => f.directives.find(d => d.name === constants_1.TransformerV2DirectiveName.BELONGS_TO)); if (otherSideConnectedField) { return [otherSideConnectedField]; } } return (0, fieldUtils_2.getModelPrimaryKeyComponentFields)(model) .map(compField => { const foreignKeyFieldName = (0, process_connections_1.makeConnectionAttributeName)(model.name, field.name, compField.name); otherSideConnectedField = connectedModel.fields.find(f => f.name === foreignKeyFieldName); return otherSideConnectedField !== null && otherSideConnectedField !== void 0 ? otherSideConnectedField : { name: foreignKeyFieldName, directives: [], type: compField.type, isList: false, isNullable: true, }; }); } exports.getConnectedFieldsForHasMany = getConnectedFieldsForHasMany; function addKeyToModel(model, name, fields) { model.directives.push({ name: 'key', arguments: { name, fields, }, }); } function getConnectionAssociatedFields(hasManyConnection) { const associatedFields = hasManyConnection.associatedWithFields && hasManyConnection.associatedWithFields.length > 0 ? hasManyConnection.associatedWithFields : [hasManyConnection.associatedWith]; if (associatedFields.length === 0) { throw new Error('Expected at least one associated field for the hasMany relationship.'); } return associatedFields; } function doesHasManyConnectionHaveCorrespondingBelongsTo(model, hasManyConnection) { const fieldReferencingParent = hasManyConnection.connectedModel.fields.find(f => f.type === model.name); if (!fieldReferencingParent) { return false; } return fieldReferencingParent.directives.some(d => d.name === constants_1.TransformerV2DirectiveName.BELONGS_TO); } function doesHasManySpecifyIndexName(field) { return field.directives.some(d => d.name === constants_1.TransformerV2DirectiveName.HAS_MANY && d.arguments.indexName); } function hasManyHasImplicitKey(field, model, hasManyConnection) { const hasCorrespondingBelongsTo = doesHasManyConnectionHaveCorrespondingBelongsTo(model, hasManyConnection); const hasIndexNameSpecified = doesHasManySpecifyIndexName(field); return !(hasCorrespondingBelongsTo || hasIndexNameSpecified); } exports.hasManyHasImplicitKey = hasManyHasImplicitKey; function addHasManyKey(field, model, hasManyConnection) { const associatedFieldNames = getConnectionAssociatedFields(hasManyConnection).map(f => f.name); const connectedModel = hasManyConnection.connectedModel; const name = `gsi-${model.name}.${field.name}`; addKeyToModel(connectedModel, name, associatedFieldNames); } exports.addHasManyKey = addHasManyKey; //# sourceMappingURL=process-has-many.js.map