Skip to content
Merged
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
38 changes: 38 additions & 0 deletions tests/regression/test/issue-2639/regression.test.ts
Original file line number Diff line number Diff line change
@@ -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<typeof _schema>;
type OrmTest = Awaited<ReturnType<typeof db.test.findFirstOrThrow>>;

// Mirrors the user's reproduction:
// function testFunction(test: OrmTest) {}
// testFunction({} as ZodTest)
expectTypeOf<ZodTest>().toExtend<OrmTest>();
});

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<typeof _schema>;
type OrmTest = Awaited<ReturnType<typeof db.test.findFirstOrThrow>>;

expectTypeOf<null>().toExtend<ZodTest['metaData']>();
expectTypeOf<null>().toExtend<OrmTest['metaData']>();
expectTypeOf<ZodTest['metaData']>().toExtend<OrmTest['metaData']>();
});
});
86 changes: 86 additions & 0 deletions tests/regression/test/issue-2639/schema.ts
Original file line number Diff line number Diff line change
@@ -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();
15 changes: 15 additions & 0 deletions tests/regression/test/issue-2639/schema.zmodel
Original file line number Diff line number Diff line change
@@ -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
}
Loading