Skip to content

Commit 2df77b9

Browse files
authored
feat: enum name mapping support and several fixes about postgres default schema (#391)
* fix: stricter default schema validation and proper transformation to Prisma schema * feat(orm): support enum name mappings * fix db pusher
1 parent 7a207bf commit 2df77b9

File tree

19 files changed

+602
-119
lines changed

19 files changed

+602
-119
lines changed

packages/language/res/stdlib.zmodel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,9 +457,9 @@ attribute @db.ByteA() @@@targetField([BytesField]) @@@prisma
457457
/**
458458
* Specifies the schema to use in a multi-schema PostgreSQL database.
459459
*
460-
* @param name: The name of the database schema.
460+
* @param map: The name of the database schema.
461461
*/
462-
attribute @@schema(_ name: String) @@@prisma
462+
attribute @@schema(_ map: String) @@@prisma
463463

464464
//////////////////////////////////////////////
465465
// Begin validation attributes and functions

packages/orm/src/client/crud/validator/index.ts

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ import {
3131
type UpdateManyArgs,
3232
type UpsertArgs,
3333
} from '../../crud-types';
34+
import { createInternalError, createInvalidInputError } from '../../errors';
3435
import {
3536
fieldHasDefaultValue,
3637
getDiscriminatorField,
3738
getEnum,
39+
getTypeDef,
3840
getUniqueFields,
3941
requireField,
4042
requireModel,
@@ -47,7 +49,6 @@ import {
4749
addNumberValidation,
4850
addStringValidation,
4951
} from './utils';
50-
import { createInternalError, createInvalidInputError } from '../../errors';
5152

5253
const schemaCache = new WeakMap<SchemaDef, Map<string, ZodType>>();
5354

@@ -281,6 +282,8 @@ export class InputValidator<Schema extends SchemaDef> {
281282
private makePrimitiveSchema(type: string, attributes?: AttributeApplication[]) {
282283
if (this.schema.typeDefs && type in this.schema.typeDefs) {
283284
return this.makeTypeDefSchema(type);
285+
} else if (this.schema.enums && type in this.schema.enums) {
286+
return this.makeEnumSchema(type);
284287
} else {
285288
return match(type)
286289
.with('String', () =>
@@ -314,6 +317,22 @@ export class InputValidator<Schema extends SchemaDef> {
314317
}
315318
}
316319

320+
private makeEnumSchema(type: string) {
321+
const key = stableStringify({
322+
type: 'enum',
323+
name: type,
324+
});
325+
let schema = this.getSchemaCache(key!);
326+
if (schema) {
327+
return schema;
328+
}
329+
const enumDef = getEnum(this.schema, type);
330+
invariant(enumDef, `Enum "${type}" not found in schema`);
331+
schema = z.enum(Object.keys(enumDef.values) as [string, ...string[]]);
332+
this.setSchemaCache(key!, schema);
333+
return schema;
334+
}
335+
317336
private makeTypeDefSchema(type: string): z.ZodType {
318337
const key = stableStringify({
319338
type: 'typedef',
@@ -324,24 +343,22 @@ export class InputValidator<Schema extends SchemaDef> {
324343
if (schema) {
325344
return schema;
326345
}
327-
const typeDef = this.schema.typeDefs?.[type];
346+
const typeDef = getTypeDef(this.schema, type);
328347
invariant(typeDef, `Type definition "${type}" not found in schema`);
329-
schema = z
330-
.object(
331-
Object.fromEntries(
332-
Object.entries(typeDef.fields).map(([field, def]) => {
333-
let fieldSchema = this.makePrimitiveSchema(def.type);
334-
if (def.array) {
335-
fieldSchema = fieldSchema.array();
336-
}
337-
if (def.optional) {
338-
fieldSchema = fieldSchema.optional();
339-
}
340-
return [field, fieldSchema];
341-
}),
342-
),
343-
)
344-
.passthrough();
348+
schema = z.looseObject(
349+
Object.fromEntries(
350+
Object.entries(typeDef.fields).map(([field, def]) => {
351+
let fieldSchema = this.makePrimitiveSchema(def.type);
352+
if (def.array) {
353+
fieldSchema = fieldSchema.array();
354+
}
355+
if (def.optional) {
356+
fieldSchema = fieldSchema.optional();
357+
}
358+
return [field, fieldSchema];
359+
}),
360+
),
361+
);
345362
this.setSchemaCache(key!, schema);
346363
return schema;
347364
}
@@ -392,7 +409,7 @@ export class InputValidator<Schema extends SchemaDef> {
392409
const enumDef = getEnum(this.schema, fieldDef.type);
393410
if (enumDef) {
394411
// enum
395-
if (Object.keys(enumDef).length > 0) {
412+
if (Object.keys(enumDef.values).length > 0) {
396413
fieldSchema = this.makeEnumFilterSchema(enumDef, !!fieldDef.optional, withAggregations);
397414
}
398415
} else if (fieldDef.array) {
@@ -427,7 +444,7 @@ export class InputValidator<Schema extends SchemaDef> {
427444
const enumDef = getEnum(this.schema, def.type);
428445
if (enumDef) {
429446
// enum
430-
if (Object.keys(enumDef).length > 0) {
447+
if (Object.keys(enumDef.values).length > 0) {
431448
fieldSchema = this.makeEnumFilterSchema(enumDef, !!def.optional, false);
432449
} else {
433450
fieldSchema = z.never();
@@ -493,7 +510,7 @@ export class InputValidator<Schema extends SchemaDef> {
493510
}
494511

495512
private makeEnumFilterSchema(enumDef: EnumDef, optional: boolean, withAggregations: boolean) {
496-
const baseSchema = z.enum(Object.keys(enumDef) as [string, ...string[]]);
513+
const baseSchema = z.enum(Object.keys(enumDef.values) as [string, ...string[]]);
497514
const components = this.makeCommonPrimitiveFilterComponents(
498515
baseSchema,
499516
optional,

0 commit comments

Comments
 (0)