@grapi/server
Version:
Grapi Schema Generator For GraphQL Server
149 lines (148 loc) • 7.07 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const __1 = require("..");
const dataModel_1 = require("../dataModel");
const utils_1 = require("../dataSource/utils");
const lodash_1 = require("../lodash");
const index_1 = require("./index");
const createForeignKey = (field, model) => `${field.toLowerCase()}${model.getNamings().capitalSingular}Id`;
class BiOneToOne {
owningSideModel;
owningSideField;
refSideModel;
refSideField;
foreignKey;
constructor({ modelA, modelB, modelAField, modelBField, foreignKey, owningSideModelName, }) {
if (!(0, utils_1.supportFindOneByRelation)(modelA) && !(0, utils_1.supportFindOneByRelation)(modelB)) {
throw new Error(`Both ${modelA.getName()} & ${modelB.getName()} dont support findOneByRelation`);
}
if (owningSideModelName) {
const owningSideModelWithField = (0, lodash_1.find)([
{ model: modelA, field: modelAField },
{ model: modelB, field: modelBField },
], obj => obj.model.getName() === owningSideModelName);
if (!owningSideModelWithField) {
throw new Error(`no model found from name \`${owningSideModelName}\``);
}
if (!(0, utils_1.supportFindOneByRelation)(owningSideModelWithField.model)) {
throw new Error(`specified model \`${owningSideModelName}\` dont support findOneByRelation`);
}
this.owningSideModel = owningSideModelWithField.model;
this.owningSideField = owningSideModelWithField.field;
const otherSideModelField = owningSideModelWithField.model === modelA
? { model: modelB, field: modelBField }
: { model: modelA, field: modelAField };
this.refSideModel = otherSideModelField.model;
this.refSideField = otherSideModelField.field;
}
else {
const orderedModelWithField = (0, lodash_1.sortBy)([
{ model: modelA, field: modelAField },
{ model: modelB, field: modelBField },
], obj => obj.model.getName());
const firstModelWithField = orderedModelWithField[0];
const secondModelWithField = orderedModelWithField[1];
if ((0, utils_1.supportFindOneByRelation)(firstModelWithField.model)) {
this.owningSideModel = firstModelWithField.model;
this.owningSideField = firstModelWithField.field;
this.refSideModel = secondModelWithField.model;
this.refSideField = secondModelWithField.field;
}
else {
this.owningSideModel = secondModelWithField.model;
this.owningSideField = secondModelWithField.field;
this.refSideModel = firstModelWithField.model;
this.refSideField = firstModelWithField.field;
}
}
this.foreignKey = foreignKey || createForeignKey(this.owningSideField, this.refSideModel);
}
getType() {
return dataModel_1.RelationType.biOneToOne;
}
getForeignKey() {
return this.foreignKey;
}
getForeignKeyConfig() {
return [{
model: this.owningSideModel,
foreignKey: this.getForeignKey(),
}];
}
getOwningSide() {
return this.owningSideModel;
}
getOwningSideField() {
return this.owningSideField;
}
getRefSide() {
return this.refSideModel;
}
getRefSideField() {
return this.refSideField;
}
setForeignKeyOnOwningSide(targetId) {
return { [this.foreignKey]: targetId };
}
async createAndSetForeignKeyOnOwningSide(targetData, context) {
const execution = async (data) => {
const mutation = this.refSideModel.getCreateMutationFactory().createMutation(data);
const created = await this.refSideModel.getDataSource().create(mutation, context);
return { data: this.setForeignKeyOnOwningSide(created.id), object: created };
};
const { rootData, createdData, executed } = await (0, index_1.InputRecursiveRelation)(targetData, this.refSideModel, context, execution);
if (executed)
return executed.data;
return (await execution({ ...rootData, ...createdData })).data;
}
unsetForeignKeyOnOwningSide() {
return { [this.foreignKey]: null };
}
async deleteAndUnsetForeignKeyOnOwningSide(data, context) {
const foreignId = data[this.foreignKey];
if (!foreignId) {
return;
}
await this.refSideModel.getDataSource().delete({ id: { [__1.Operator.eq]: foreignId } }, context);
return this.unsetForeignKeyOnOwningSide();
}
async connectOnRefSide(refSideId, owningSideId, context) {
const owningSideDataSource = this.owningSideModel.getDataSource();
await owningSideDataSource.updateOneRelation(owningSideId, this.foreignKey, refSideId, context);
}
async createAndConnectOnRefSide(refSideId, data, context) {
const execution = async (dataRecord) => {
const mutation = this.owningSideModel.getCreateMutationFactory().createMutation({
...dataRecord, [this.foreignKey]: refSideId
});
return { object: await this.owningSideModel.getDataSource().create(mutation, context) };
};
const { executed } = await (0, index_1.InputRecursiveRelation)(data, this.owningSideModel, context, execution);
if (!executed)
await execution(data);
}
async disconnectOnRefSide(refSideId, context) {
const owningSideDataSource = this.owningSideModel.getDataSource();
const owningSideRecord = await owningSideDataSource.findOneByRelation(this.foreignKey, refSideId, context);
const mutation = this.owningSideModel.getUpdateMutationFactory().createMutation({ [this.foreignKey]: null });
await owningSideDataSource.update({ id: { [__1.Operator.eq]: owningSideRecord.id } }, mutation, context);
}
async deleteAndDisconnectOnRefSide(refSideId, context) {
const owningSideDataSource = this.owningSideModel.getDataSource();
const owningSideRecord = await owningSideDataSource.findOneByRelation(this.foreignKey, refSideId, context);
return owningSideDataSource.delete({ id: { [__1.Operator.eq]: owningSideRecord.id } }, context);
}
async joinOnOwningSide(data, context) {
const targetId = data[this.foreignKey];
if (!targetId) {
return null;
}
const toOneData = await this.refSideModel.getDataSource().findOneById(targetId, context);
return (0, lodash_1.isEmpty)(toOneData) ? null : toOneData;
}
async joinOnRefSide(data, context) {
const toOneData = await this.owningSideModel.getDataSource().findOneByRelation(this.foreignKey, data.id, context);
return (0, lodash_1.isEmpty)(toOneData) ? null : toOneData;
}
}
exports.default = BiOneToOne;