Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions packages/orm/src/client/zod/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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') {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of adding a condition here, filter the fields used on the loop. Consider if you should extract a helper method for such filtering.

fields[field] = z.boolean().optional();
}
}
Expand Down Expand Up @@ -996,7 +996,7 @@ export class ZodSchemaFactory<
const fields: Record<string, ZodType> = {};
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();
Expand Down Expand Up @@ -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([
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
16 changes: 10 additions & 6 deletions packages/schema/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,13 @@ export type ScalarFields<
? never
: GetModelField<Schema, Model, Key>['foreignKeyFor'] extends readonly string[]
? never
: IncludeComputed extends true
? Key
: FieldIsComputed<Schema, Model, Key> extends true
? never
: Key]: Key;
: GetModelField<Schema, Model, Key>['type'] extends 'Unsupported'
? never
: IncludeComputed extends true
? Key
: FieldIsComputed<Schema, Model, Key> extends true
? never
: Key]: Key;
};

export type ForeignKeyFields<Schema extends SchemaDef, Model extends GetModels<Schema>> = keyof {
Expand All @@ -221,7 +223,9 @@ export type ForeignKeyFields<Schema extends SchemaDef, Model extends GetModels<S
export type NonRelationFields<Schema extends SchemaDef, Model extends GetModels<Schema>> = keyof {
[Key in GetModelFields<Schema, Model> as GetModelField<Schema, Model, Key>['relation'] extends object
? never
: Key]: Key;
: GetModelField<Schema, Model, Key>['type'] extends 'Unsupported'
? never
: Key]: Key;
};

export type RelationFields<Schema extends SchemaDef, Model extends GetModels<Schema>> = keyof {
Expand Down
62 changes: 62 additions & 0 deletions tests/e2e/orm/client-api/zod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
});
Loading