@@ -4,6 +4,7 @@ import type {
44 ZeroRelationship ,
55 TransformedSchema ,
66 Config ,
7+ ZeroTypeMapping ,
78} from '../types' ;
89import { mapPrismaTypeToZero } from './type-mapper' ;
910import camelCase from 'camelcase' ;
@@ -107,6 +108,13 @@ function createImplicitManyToManyModel(
107108 const columnAType = mapPrismaTypeToZero ( idFieldA ) ;
108109 const columnBType = mapPrismaTypeToZero ( idFieldB ) ;
109110
111+ if ( ! columnAType || ! columnBType ) {
112+ const unsupportedModel = ! columnAType ? modelA : modelB ;
113+ throw new Error (
114+ `Implicit relation ${ relationName ?? 'unknown' } : Model ${ unsupportedModel . name } has an unsupported @id field.` ,
115+ ) ;
116+ }
117+
110118 return {
111119 tableName,
112120 originalTableName,
@@ -141,6 +149,20 @@ function mapRelationships(
141149) : Record < string , ZeroRelationship > {
142150 const relationships : Record < string , ZeroRelationship > = { } ;
143151
152+ const isSupportedField = ( target : DMMF . Model , fieldName : string ) : boolean => {
153+ const field = target . fields . find ( f => f . name === fieldName ) ;
154+ if ( ! field ) {
155+ return true ;
156+ }
157+ return mapPrismaTypeToZero ( field ) !== null ;
158+ } ;
159+
160+ const areFieldsSupported = (
161+ target : DMMF . Model ,
162+ fieldNames : string [ ] ,
163+ ) : boolean =>
164+ fieldNames . every ( fieldName => isSupportedField ( target , fieldName ) ) ;
165+
144166 model . fields
145167 . filter ( field => field . relationName )
146168 . forEach ( field => {
@@ -189,18 +211,31 @@ function mapRelationships(
189211 : true
190212 : model . name === modelA . name ;
191213
214+ const sourceField = [ model . fields . find ( f => f . isId ) ?. name || 'id' ] ;
215+ const destField = [ isModelA ? 'A' : 'B' ] ;
216+ const targetDestField = [
217+ targetModel . fields . find ( f => f . isId ) ?. name || 'id' ,
218+ ] ;
219+
220+ if (
221+ ! areFieldsSupported ( model , sourceField ) ||
222+ ! areFieldsSupported ( targetModel , targetDestField )
223+ ) {
224+ return ;
225+ }
226+
192227 // Create a chained relationship through the join table
193228 relationships [ field . name ] = {
194229 type : 'many' ,
195230 chain : [
196231 {
197- sourceField : [ model . fields . find ( f => f . isId ) ?. name || 'id' ] ,
198- destField : [ isModelA ? 'A' : 'B' ] ,
232+ sourceField,
233+ destField,
199234 destSchema : getZeroTableName ( joinTableName ) ,
200235 } ,
201236 {
202237 sourceField : [ isModelA ? 'B' : 'A' ] ,
203- destField : [ targetModel . fields . find ( f => f . isId ) ?. name || 'id' ] ,
238+ destField : targetDestField ,
204239 destSchema : getZeroTableName ( targetModel . name ) ,
205240 } ,
206241 ] ,
@@ -216,6 +251,13 @@ function mapRelationships(
216251 ? ensureStringArray ( backReference . relationFromFields )
217252 : [ ] ;
218253
254+ if (
255+ ! areFieldsSupported ( model , sourceFields ) ||
256+ ! areFieldsSupported ( targetModel , destFields )
257+ ) {
258+ return ;
259+ }
260+
219261 relationships [ field . name ] = {
220262 sourceField : sourceFields ,
221263 destField : destFields ,
@@ -240,6 +282,13 @@ function mapRelationships(
240282 destFields = ensureStringArray ( backReference . relationFromFields ) ;
241283 }
242284
285+ if (
286+ ! areFieldsSupported ( model , sourceFields ) ||
287+ ! areFieldsSupported ( targetModel , destFields )
288+ ) {
289+ return ;
290+ }
291+
243292 relationships [ field . name ] = {
244293 sourceField : sourceFields ,
245294 destField : destFields ,
@@ -257,12 +306,16 @@ function mapModel(
257306 dmmf : DMMF . Document ,
258307 config : Config ,
259308) : ZeroModel {
260- const columns : Record < string , ReturnType < typeof mapPrismaTypeToZero > > = { } ;
309+ const columns : Record < string , ZeroTypeMapping > = { } ;
261310
262311 model . fields
263312 . filter ( field => ! field . relationName )
264313 . forEach ( field => {
265- columns [ field . name ] = mapPrismaTypeToZero ( field ) ;
314+ const mapping = mapPrismaTypeToZero ( field ) ;
315+ if ( ! mapping ) {
316+ return ;
317+ }
318+ columns [ field . name ] = mapping ;
266319 } ) ;
267320
268321 const idField = model . fields . find ( f => f . isId ) ?. name ;
@@ -271,6 +324,20 @@ function mapModel(
271324 throw new Error ( `No primary key found for ${ model . name } ` ) ;
272325 }
273326
327+ const unsupportedPrimaryKeys = primaryKey . filter ( fieldName => {
328+ const field = model . fields . find ( f => f . name === fieldName ) ;
329+ if ( ! field ) {
330+ return false ;
331+ }
332+ return mapPrismaTypeToZero ( field ) === null ;
333+ } ) ;
334+
335+ if ( unsupportedPrimaryKeys . length > 0 ) {
336+ throw new Error (
337+ `Primary key field(s) ${ unsupportedPrimaryKeys . join ( ', ' ) } in ${ model . name } are not supported by Zero.` ,
338+ ) ;
339+ }
340+
274341 // Use the Prisma model name (optionally camelCased) for the Zero table name.
275342 // If the Prisma model is mapped to a different DB table (@@map) or camelCase
276343 // changes the casing, capture the DB table name in originalTableName so we
0 commit comments