diff --git a/packages/orm/src/client/zod/factory.ts b/packages/orm/src/client/zod/factory.ts index 0f0eb61e8..8599c37aa 100644 --- a/packages/orm/src/client/zod/factory.ts +++ b/packages/orm/src/client/zod/factory.ts @@ -889,7 +889,7 @@ export class ZodSchemaFactory< if (this.isModelAllowed(fieldDef.type)) { fields[field] = this.makeRelationSelectIncludeSchema(model, field, options).optional(); } - } else { + } else if (fieldDef.type !== 'Unsupported') { fields[field] = z.boolean().optional(); } } @@ -996,7 +996,7 @@ export class ZodSchemaFactory< const fields: Record = {}; for (const field of Object.keys(modelDef.fields)) { const fieldDef = requireField(this.schema, model, field); - if (!fieldDef.relation) { + if (!fieldDef.relation && fieldDef.type !== 'Unsupported') { if (this.options.allowQueryTimeOmitOverride !== false) { // if override is allowed, use boolean fields[field] = z.boolean().optional(); @@ -1067,8 +1067,8 @@ export class ZodSchemaFactory< return relationOrderBy.optional(); }); } - } else { - // scalars + } else if (fieldDef.type !== 'Unsupported') { + // scalars (excluding Unsupported type fields) if (fieldDef.optional) { fields[field] = z .union([ @@ -1099,7 +1099,9 @@ export class ZodSchemaFactory< @cache() private makeDistinctSchema(model: string) { const modelDef = requireModel(this.schema, model); - const nonRelationFields = Object.keys(modelDef.fields).filter((field) => !modelDef.fields[field]?.relation); + const nonRelationFields = Object.keys(modelDef.fields).filter( + (field) => !modelDef.fields[field]?.relation && modelDef.fields[field]?.type !== 'Unsupported', + ); return nonRelationFields.length > 0 ? this.orArray(z.enum(nonRelationFields as any), true) : z.never(); } @@ -1188,6 +1190,11 @@ export class ZodSchemaFactory< return; } + // skip Unsupported type fields, they cannot be set on create + if (fieldDef.type === 'Unsupported') { + return; + } + if (fieldDef.relation) { if (skipRelations) { return; @@ -1542,6 +1549,11 @@ export class ZodSchemaFactory< return; } + // skip Unsupported type fields, they cannot be updated + if (fieldDef.type === 'Unsupported') { + return; + } + if (fieldDef.relation) { if (skipRelations) { return; diff --git a/packages/schema/src/schema.ts b/packages/schema/src/schema.ts index e21b5e30e..00c56a59a 100644 --- a/packages/schema/src/schema.ts +++ b/packages/schema/src/schema.ts @@ -201,11 +201,13 @@ export type ScalarFields< ? never : GetModelField['foreignKeyFor'] extends readonly string[] ? never - : IncludeComputed extends true - ? Key - : FieldIsComputed extends true - ? never - : Key]: Key; + : GetModelField['type'] extends 'Unsupported' + ? never + : IncludeComputed extends true + ? Key + : FieldIsComputed extends true + ? never + : Key]: Key; }; export type ForeignKeyFields> = keyof { @@ -221,7 +223,9 @@ export type ForeignKeyFields> = keyof { [Key in GetModelFields as GetModelField['relation'] extends object ? never - : Key]: Key; + : GetModelField['type'] extends 'Unsupported' + ? never + : Key]: Key; }; export type RelationFields> = keyof { diff --git a/tests/e2e/orm/client-api/zod.test.ts b/tests/e2e/orm/client-api/zod.test.ts index abee059d5..c9e3771fd 100644 --- a/tests/e2e/orm/client-api/zod.test.ts +++ b/tests/e2e/orm/client-api/zod.test.ts @@ -1375,4 +1375,66 @@ describe('Zod schema factory test', () => { }); // #endregion + + // #region Unsupported type fields + + describe('Unsupported type fields', () => { + const unsupportedSchema = { + provider: { type: 'sqlite' as const }, + models: { + Polygon: { + name: 'Polygon', + fields: { + id: { name: 'id', type: 'Int', id: true, default: 0 }, + name: { name: 'name', type: 'String' }, + geometry: { name: 'geometry', type: 'Unsupported' }, + }, + idFields: ['id'], + uniqueFields: { id: { type: 'Int' } }, + }, + }, + enums: {}, + plugins: {}, + } as const; + + it('create schema rejects Unsupported field', () => { + const factory = createQuerySchemaFactory(unsupportedSchema); + const s = factory.makeCreateSchema('Polygon'); + // valid create without unsupported field + expect(s.safeParse({ data: { name: 'poly1' } }).success).toBe(true); + // create with unsupported field is rejected + expect(s.safeParse({ data: { name: 'poly1', geometry: 'some value' } }).success).toBe(false); + }); + + it('update schema rejects Unsupported field', () => { + const factory = createQuerySchemaFactory(unsupportedSchema); + const s = factory.makeUpdateSchema('Polygon'); + // valid update without unsupported field + expect(s.safeParse({ where: { id: 1 }, data: { name: 'poly2' } }).success).toBe(true); + // update with unsupported field is rejected + expect(s.safeParse({ where: { id: 1 }, data: { name: 'poly2', geometry: 'some value' } }).success).toBe( + false, + ); + }); + + it('select schema rejects Unsupported field', () => { + const factory = createQuerySchemaFactory(unsupportedSchema); + const s = factory.makeFindManySchema('Polygon'); + // valid select without unsupported field + expect(s.safeParse({ select: { id: true, name: true } }).success).toBe(true); + // selecting unsupported field is rejected + expect(s.safeParse({ select: { id: true, geometry: true } }).success).toBe(false); + }); + + it('orderBy schema rejects Unsupported field', () => { + const factory = createQuerySchemaFactory(unsupportedSchema); + const s = factory.makeFindManySchema('Polygon'); + // valid orderBy without unsupported field + expect(s.safeParse({ orderBy: { name: 'asc' } }).success).toBe(true); + // orderBy unsupported field is rejected + expect(s.safeParse({ orderBy: { geometry: 'asc' } }).success).toBe(false); + }); + }); + + // #endregion });