77 PrismaErrorCode ,
88 clone ,
99 enumerate ,
10+ requireField ,
1011 getIdFields ,
1112 isPrismaClientKnownRequestError ,
1213} from '@zenstackhq/runtime' ;
@@ -52,6 +53,8 @@ export type Options = {
5253 urlSegmentCharset ?: string ;
5354
5455 modelNameMapping ?: Record < string , string > ;
56+
57+ externalIdMapping ?: Record < string , string > ;
5558} ;
5659
5760type RelationshipInfo = {
@@ -238,6 +241,7 @@ class RequestHandler extends APIHandlerBase {
238241 private urlPatternMap : Record < UrlPatterns , UrlPattern > ;
239242 private modelNameMapping : Record < string , string > ;
240243 private reverseModelNameMapping : Record < string , string > ;
244+ private externalIdMapping : Record < string , string > ;
241245
242246 constructor ( private readonly options : Options ) {
243247 super ( ) ;
@@ -251,6 +255,12 @@ class RequestHandler extends APIHandlerBase {
251255 this . reverseModelNameMapping = Object . fromEntries (
252256 Object . entries ( this . modelNameMapping ) . map ( ( [ k , v ] ) => [ v , k ] )
253257 ) ;
258+
259+ this . externalIdMapping = options . externalIdMapping ?? { } ;
260+ this . externalIdMapping = Object . fromEntries (
261+ Object . entries ( this . externalIdMapping ) . map ( ( [ k , v ] ) => [ lowerCaseFirst ( k ) , v ] )
262+ ) ;
263+
254264 this . urlPatternMap = this . buildUrlPatternMap ( segmentCharset ) ;
255265 }
256266
@@ -1166,11 +1176,28 @@ class RequestHandler extends APIHandlerBase {
11661176 }
11671177
11681178 //#region utilities
1179+ private getIdFields ( modelMeta : ModelMeta , model : string ) : FieldInfo [ ] {
1180+ const modelLower = lowerCaseFirst ( model ) ;
1181+ if ( ! ( modelLower in this . externalIdMapping ) ) {
1182+ return getIdFields ( modelMeta , model ) ;
1183+ }
1184+
1185+ const metaData = modelMeta . models [ modelLower ] ?? { } ;
1186+ const externalIdName = this . externalIdMapping [ modelLower ] ;
1187+ const uniqueConstraints = metaData . uniqueConstraints ?? { } ;
1188+ for ( const [ name , constraint ] of Object . entries ( uniqueConstraints ) ) {
1189+ if ( name === externalIdName ) {
1190+ return constraint . fields . map ( ( f ) => requireField ( modelMeta , model , f ) ) ;
1191+ }
1192+ }
1193+
1194+ throw new Error ( `Model ${ model } does not have unique key ${ externalIdName } ` ) ;
1195+ }
11691196
11701197 private buildTypeMap ( logger : LoggerConfig | undefined , modelMeta : ModelMeta ) : void {
11711198 this . typeMap = { } ;
11721199 for ( const [ model , { fields } ] of Object . entries ( modelMeta . models ) ) {
1173- const idFields = getIdFields ( modelMeta , model ) ;
1200+ const idFields = this . getIdFields ( modelMeta , model ) ;
11741201 if ( idFields . length === 0 ) {
11751202 logWarning ( logger , `Not including model ${ model } in the API because it has no ID field` ) ;
11761203 continue ;
@@ -1186,7 +1213,7 @@ class RequestHandler extends APIHandlerBase {
11861213 if ( ! fieldInfo . isDataModel ) {
11871214 continue ;
11881215 }
1189- const fieldTypeIdFields = getIdFields ( modelMeta , fieldInfo . type ) ;
1216+ const fieldTypeIdFields = this . getIdFields ( modelMeta , fieldInfo . type ) ;
11901217 if ( fieldTypeIdFields . length === 0 ) {
11911218 logWarning (
11921219 logger ,
@@ -1214,7 +1241,7 @@ class RequestHandler extends APIHandlerBase {
12141241 const linkers : Record < string , Linker < any > > = { } ;
12151242
12161243 for ( const model of Object . keys ( modelMeta . models ) ) {
1217- const ids = getIdFields ( modelMeta , model ) ;
1244+ const ids = this . getIdFields ( modelMeta , model ) ;
12181245 const mappedModel = this . mapModelName ( model ) ;
12191246
12201247 if ( ids . length < 1 ) {
@@ -1266,7 +1293,7 @@ class RequestHandler extends APIHandlerBase {
12661293 if ( ! fieldSerializer ) {
12671294 continue ;
12681295 }
1269- const fieldIds = getIdFields ( modelMeta , fieldMeta . type ) ;
1296+ const fieldIds = this . getIdFields ( modelMeta , fieldMeta . type ) ;
12701297 if ( fieldIds . length > 0 ) {
12711298 const mappedModel = this . mapModelName ( model ) ;
12721299
@@ -1306,7 +1333,7 @@ class RequestHandler extends APIHandlerBase {
13061333 if ( ! data ) {
13071334 return undefined ;
13081335 }
1309- const ids = getIdFields ( modelMeta , model ) ;
1336+ const ids = this . getIdFields ( modelMeta , model ) ;
13101337 if ( ids . length === 0 ) {
13111338 return undefined ;
13121339 } else {
0 commit comments