import { CollectionConfig, ResolvedManyToMany, ResolvedRelation, ResolvedVia } from "@rebasepro/types"; import { DrizzleClient } from "../interfaces"; import { PostgresCollectionRegistry } from "../collections/PostgresCollectionRegistry"; import type { NestedPathHop } from "./nested-path"; /** * Writing relations: junction membership, foreign-key stamping, and the links a * nested path creates or removes. * * Split from {@link RelationService}, which now only reads. The two had grown * into one 1700-line class doing two unrelated jobs, and sharing one habit — * warning about a relation it could not resolve and carrying on, which surfaces * as an empty list on the read side and as a successful save on the write side. * Separating them is what made that visible as one class of defect rather than * eighteen scattered log lines. * * The reads it still needs — the source key a link joins on — it asks * {@link RelationService} for rather than reimplementing. */ export declare class RelationWriteService { private db; private registry; private reads; constructor(db: DrizzleClient, registry: PostgresCollectionRegistry); /** * Remove the junction row linking a parent to `targetId`, leaving the target * row itself alone. * * This is what `DELETE authors/1/tags/5` has to mean for a many-to-many: the * target is shared, so deleting the row would remove the tag from every other * post that uses it. It used to do exactly that — resolve the path to the * `tags` table and delete by primary key. */ unlinkRelatedEntity(tx: DrizzleClient, hop: NestedPathHop, targetId: string | number): Promise; /** A collection's id, parsed to the type its primary key column holds. */ private parsedId; /** The same, for the membership list a to-many write names. */ private parsedIds; /** * Update many-to-many and junction relations */ updateRelationsUsingJoins>(tx: DrizzleClient, collection: CollectionConfig, id: string | number, relationValues: Partial): Promise; /** * Update inverse relations (where FK is on the target table) */ updateInverseRelations(tx: DrizzleClient, sourceCollection: CollectionConfig, sourceEntityId: string | number, inverseRelationUpdates: Array<{ relationKey: string; relation: ResolvedRelation; newValue: unknown; }>): Promise; /** * Handle inverse relations with joinPath */ private updateInverseJoinPathRelation; /** * Handle many-to-many inverse relation updates using junction tables */ private updateManyToManyInverseRelation; /** * Update one-to-one relations that use joinPath */ updateJoinPathOneToOneRelations(tx: DrizzleClient, parentCollection: CollectionConfig, parentId: string | number, updates: Array<{ relationKey: string; relation: ResolvedVia; newTargetId: string | number | null; }>): Promise; /** * Resolve joinPath write mapping for one-to-one relations */ resolveJoinPathWriteMapping(parentCollection: CollectionConfig, relation: ResolvedVia): { targetFKColName: string; parentSourceColName: string; }; /** * Handle junction table creation for many-to-many path-based saves */ handleJunctionTableCreation(tx: DrizzleClient, newEntityId: string | number, junctionTableInfo: { parentCollection: CollectionConfig; parentId: string | number; relation: ResolvedManyToMany; relationKey: string; }): Promise; }