mirror of
https://github.com/bknd-io/bknd/
synced 2026-08-02 16:16:02 +00:00
public commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import type { Entity, EntityManager } from "../entities";
|
||||
import { ManyToOneRelation, type ManyToOneRelationConfig } from "./ManyToOneRelation";
|
||||
import type { MutationInstructionResponse } from "./RelationMutator";
|
||||
import { type RelationType, RelationTypes } from "./relation-types";
|
||||
|
||||
/**
|
||||
* Both source and target receive a mapping field
|
||||
* @todo: determine if it should be removed
|
||||
*/
|
||||
export type OneToOneRelationConfig = ManyToOneRelationConfig;
|
||||
|
||||
/* export type OneToOneRelationConfig = {
|
||||
mappedBy?: string; // author|users
|
||||
inversedBy?: string; // posts
|
||||
required?: boolean;
|
||||
}; */
|
||||
|
||||
export class OneToOneRelation extends ManyToOneRelation {
|
||||
constructor(source: Entity, target: Entity, config?: OneToOneRelationConfig) {
|
||||
const { mappedBy, inversedBy, required } = config || {};
|
||||
super(source, target, {
|
||||
mappedBy,
|
||||
inversedBy,
|
||||
sourceCardinality: 1,
|
||||
required
|
||||
});
|
||||
}
|
||||
|
||||
override type(): RelationType {
|
||||
return RelationTypes.OneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* One-to-one relations are not listable in either direction
|
||||
*/
|
||||
override isListableFor(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
// need to override since it inherits manytoone
|
||||
override async $set(
|
||||
em: EntityManager<any>,
|
||||
key: string,
|
||||
value: object
|
||||
): Promise<MutationInstructionResponse> {
|
||||
throw new Error("$set is not allowed");
|
||||
}
|
||||
|
||||
override async $create(
|
||||
em: EntityManager<any>,
|
||||
key: string,
|
||||
value: unknown
|
||||
): Promise<void | MutationInstructionResponse> {
|
||||
if (value === null || typeof value !== "object") {
|
||||
throw new Error(`Invalid value for relation field "${key}" given, expected object.`);
|
||||
}
|
||||
|
||||
const target = this.other(this.source.entity).entity;
|
||||
const helper = this.helper(this.source.entity.name);
|
||||
const info = helper.getMutationInfo();
|
||||
const primary = info.primary;
|
||||
const local_field = info.local_field;
|
||||
if (!info.$create || !primary || !local_field) {
|
||||
throw new Error(`Cannot perform $create for relation "${key}"`);
|
||||
}
|
||||
|
||||
// create the relational entity
|
||||
try {
|
||||
const { data } = await em.mutator(target).insertOne(value);
|
||||
|
||||
const retrieved_value = data[primary];
|
||||
return [local_field, retrieved_value] satisfies MutationInstructionResponse;
|
||||
} catch (e) {
|
||||
throw new Error(`Error performing $create on "${target.name}".`);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user