22/* eslint-disable @typescript-eslint/no-explicit-any */
33
44import deepcopy from 'deepcopy' ;
5- import { FieldInfo , NestedWriteVisitor , PrismaWriteActionType , enumerate , getFields } from '../cross' ;
5+ import { FieldInfo , NestedWriteVisitor , PrismaWriteActionType , enumerate , getFields , requireField } from '../cross' ;
66import { DbClientContract } from '../types' ;
77import { EnhancementContext , InternalEnhancementOptions } from './create-enhancement' ;
88import { DefaultPrismaProxyHandler , PrismaProxyActions , makeProxy } from './proxy' ;
9+ import { isUnsafeMutate } from './utils' ;
910
1011/**
1112 * Gets an enhanced Prisma client that supports `@default(auth())` attribute.
@@ -68,7 +69,7 @@ class DefaultAuthHandler extends DefaultPrismaProxyHandler {
6869 const authDefaultValue = this . getDefaultValueFromAuth ( fieldInfo ) ;
6970 if ( authDefaultValue !== undefined ) {
7071 // set field value extracted from `auth()`
71- data [ fieldInfo . name ] = authDefaultValue ;
72+ this . setAuthDefaultValue ( fieldInfo , model , data , authDefaultValue ) ;
7273 }
7374 }
7475 } ;
@@ -90,6 +91,47 @@ class DefaultAuthHandler extends DefaultPrismaProxyHandler {
9091 return newArgs ;
9192 }
9293
94+ private setAuthDefaultValue ( fieldInfo : FieldInfo , model : string , data : any , authDefaultValue : unknown ) {
95+ if ( fieldInfo . isForeignKey && ! isUnsafeMutate ( model , data , this . options . modelMeta ) ) {
96+ // if the field is a fk, and the create payload is not unsafe, we need to translate
97+ // the fk field setting to a `connect` of the corresponding relation field
98+ const relFieldName = fieldInfo . relationField ;
99+ if ( ! relFieldName ) {
100+ throw new Error (
101+ `Field \`${ fieldInfo . name } \` is a foreign key field but no corresponding relation field is found`
102+ ) ;
103+ }
104+ const relationField = requireField ( this . options . modelMeta , model , relFieldName ) ;
105+
106+ // construct a `{ connect: { ... } }` payload
107+ let connect = data [ relationField . name ] ?. connect ;
108+ if ( ! connect ) {
109+ connect = { } ;
110+ data [ relationField . name ] = { connect } ;
111+ }
112+
113+ // sets the opposite fk field to value `authDefaultValue`
114+ const oppositeFkFieldName = this . getOppositeFkFieldName ( relationField , fieldInfo ) ;
115+ if ( ! oppositeFkFieldName ) {
116+ throw new Error (
117+ `Cannot find opposite foreign key field for \`${ fieldInfo . name } \` in relation field \`${ relFieldName } \``
118+ ) ;
119+ }
120+ connect [ oppositeFkFieldName ] = authDefaultValue ;
121+ } else {
122+ // set default value directly
123+ data [ fieldInfo . name ] = authDefaultValue ;
124+ }
125+ }
126+
127+ private getOppositeFkFieldName ( relationField : FieldInfo , fieldInfo : FieldInfo ) {
128+ if ( ! relationField . foreignKeyMapping ) {
129+ return undefined ;
130+ }
131+ const entry = Object . entries ( relationField . foreignKeyMapping ) . find ( ( [ , v ] ) => v === fieldInfo . name ) ;
132+ return entry ?. [ 0 ] ;
133+ }
134+
93135 private getDefaultValueFromAuth ( fieldInfo : FieldInfo ) {
94136 if ( ! this . userContext ) {
95137 throw new Error ( `Evaluating default value of field \`${ fieldInfo . name } \` requires a user context` ) ;
0 commit comments