diff --git a/tests/regression/test/issue-2639/regression.test.ts b/tests/regression/test/issue-2639/regression.test.ts new file mode 100644 index 000000000..f90800681 --- /dev/null +++ b/tests/regression/test/issue-2639/regression.test.ts @@ -0,0 +1,38 @@ +import { createTestClient } from '@zenstackhq/testtools'; +import { createSchemaFactory } from '@zenstackhq/zod'; +import { describe, expectTypeOf, it } from 'vitest'; +import z from 'zod'; +import { schema } from './schema'; + +// https://github.com/zenstackhq/zenstack/issues/2639 +// +// The user reported that the type inferred from `factory.makeModelSchema('Test')` +// was not assignable to the ORM-inferred model type because the zod-inferred +// `metaData` field included `null` while the ORM `JsonValue` did not. + +const factory = createSchemaFactory(schema); + +describe('Regression for issue #2639', () => { + it('zod-inferred model type is assignable to the ORM model type', async () => { + const db = await createTestClient(schema); + const _schema = factory.makeModelSchema('Test'); + type ZodTest = z.infer; + type OrmTest = Awaited>; + + // Mirrors the user's reproduction: + // function testFunction(test: OrmTest) {} + // testFunction({} as ZodTest) + expectTypeOf().toExtend(); + }); + + it('zod-inferred metaData allows null and is assignable to the ORM metaData', async () => { + const db = await createTestClient(schema); + const _schema = factory.makeModelSchema('Test'); + type ZodTest = z.infer; + type OrmTest = Awaited>; + + expectTypeOf().toExtend(); + expectTypeOf().toExtend(); + expectTypeOf().toExtend(); + }); +}); diff --git a/tests/regression/test/issue-2639/schema.ts b/tests/regression/test/issue-2639/schema.ts new file mode 100644 index 000000000..8e8088b86 --- /dev/null +++ b/tests/regression/test/issue-2639/schema.ts @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////////////////////////// +// DO NOT MODIFY THIS FILE // +// This file is automatically generated by ZenStack CLI and should not be manually updated. // +////////////////////////////////////////////////////////////////////////////////////////////// + +/* eslint-disable */ + +import { type SchemaDef, type AttributeApplication, type FieldDefault, ExpressionUtils } from "@zenstackhq/schema"; +export class SchemaType implements SchemaDef { + provider = { + type: "postgresql" + } as const; + models = { + Test: { + name: "Test", + fields: { + id: { + name: "id", + type: "String", + id: true, + attributes: [{ name: "@id" }, { name: "@default", args: [{ name: "value", value: ExpressionUtils.call("uuid") }] }] as readonly AttributeApplication[], + default: ExpressionUtils.call("uuid") as FieldDefault + }, + createdAt: { + name: "createdAt", + type: "DateTime", + attributes: [{ name: "@default", args: [{ name: "value", value: ExpressionUtils.call("now") }] }] as readonly AttributeApplication[], + default: ExpressionUtils.call("now") as FieldDefault + }, + updatedAt: { + name: "updatedAt", + type: "DateTime", + updatedAt: true, + attributes: [{ name: "@updatedAt" }] as readonly AttributeApplication[] + }, + metaData: { + name: "metaData", + type: "Json", + attributes: [{ name: "@default", args: [{ name: "value", value: ExpressionUtils.literal("{}") }] }] as readonly AttributeApplication[], + default: "{}" as FieldDefault + }, + name: { + name: "name", + type: "String" + } + }, + idFields: ["id"], + uniqueFields: { + id: { type: "String" } + } + } + } as const; + typeDefs = { + BasicFields: { + name: "BasicFields", + fields: { + id: { + name: "id", + type: "String", + attributes: [{ name: "@id" }, { name: "@default", args: [{ name: "value", value: ExpressionUtils.call("uuid") }] }] as readonly AttributeApplication[], + default: ExpressionUtils.call("uuid") as FieldDefault + }, + createdAt: { + name: "createdAt", + type: "DateTime", + attributes: [{ name: "@default", args: [{ name: "value", value: ExpressionUtils.call("now") }] }] as readonly AttributeApplication[], + default: ExpressionUtils.call("now") as FieldDefault + }, + updatedAt: { + name: "updatedAt", + type: "DateTime", + updatedAt: true, + attributes: [{ name: "@updatedAt" }] as readonly AttributeApplication[] + }, + metaData: { + name: "metaData", + type: "Json", + attributes: [{ name: "@default", args: [{ name: "value", value: ExpressionUtils.literal("{}") }] }] as readonly AttributeApplication[], + default: "{}" as FieldDefault + } + } + } + } as const; + plugins = {}; +} +export const schema = new SchemaType(); diff --git a/tests/regression/test/issue-2639/schema.zmodel b/tests/regression/test/issue-2639/schema.zmodel new file mode 100644 index 000000000..2a8c3387d --- /dev/null +++ b/tests/regression/test/issue-2639/schema.zmodel @@ -0,0 +1,15 @@ +datasource db { + provider = 'postgresql' + url = env("DATABASE_URL") +} + +type BasicFields { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + metaData Json @default("{}") +} + +model Test with BasicFields { + name String +}