diff --git a/packages/schema/src/language-server/validator/attribute-application-validator.ts b/packages/schema/src/language-server/validator/attribute-application-validator.ts index b22a6f372..0efa760b8 100644 --- a/packages/schema/src/language-server/validator/attribute-application-validator.ts +++ b/packages/schema/src/language-server/validator/attribute-application-validator.ts @@ -267,6 +267,12 @@ function assignableToAttributeParam(arg: AttributeArg, param: AttributeParam, at if (dstType === 'ContextType') { // ContextType is inferred from the attribute's container's type if (isDataModelField(attr.$container)) { + // If the field is Typed JSON, and the param is @default, the argument must be a string + const dstIsTypedJson = hasAttribute(attr.$container, '@json'); + if (dstIsTypedJson && param.default) { + return argResolvedType.decl === 'String'; + } + dstIsArray = attr.$container.type.array; } } @@ -327,6 +333,7 @@ function assignableToAttributeParam(arg: AttributeArg, param: AttributeParam, at if (!attr.$container?.type?.type) { return false; } + dstType = mapBuiltinTypeToExpressionType(attr.$container.type.type); dstIsArray = attr.$container.type.array; } else { diff --git a/packages/schema/src/plugins/zod/transformer.ts b/packages/schema/src/plugins/zod/transformer.ts index 8e7364669..899c6c473 100644 --- a/packages/schema/src/plugins/zod/transformer.ts +++ b/packages/schema/src/plugins/zod/transformer.ts @@ -197,7 +197,9 @@ export default class Transformer { if (replaceJsonWithTypeDef) { const dmField = contextDataModel?.fields.find((f) => f.name === field.name); if (isTypeDef(dmField?.type.reference?.ref)) { - alternatives = [`z.lazy(() => ${upperCaseFirst(dmField?.type.reference!.$refText)}Schema)`]; + const isList = dmField.type.array; + const lazyStr = `z.lazy(() => ${upperCaseFirst(dmField.type.reference!.$refText)}Schema)`; + alternatives = [isList ? `${lazyStr}.array()` : lazyStr]; } } diff --git a/tests/regression/tests/issue-2039.test.ts b/tests/regression/tests/issue-2039.test.ts new file mode 100644 index 000000000..bddca560a --- /dev/null +++ b/tests/regression/tests/issue-2039.test.ts @@ -0,0 +1,42 @@ +import { createPostgresDb, loadSchema } from '@zenstackhq/testtools'; + +describe('issue 2039', () => { + it('regression', async () => { + const dbUrl = await createPostgresDb('issue-2039'); + const { zodSchemas, enhance } = await loadSchema( + ` +type Foo { + a String +} + +model Bar { + id String @id @default(cuid()) + foo Foo @json @default("{ \\"a\\": \\"a\\" }") + fooList Foo[] @json @default("[{ \\"a\\": \\"b\\" }]") + @@allow('all', true) +} + `, + { + fullZod: true, + provider: 'postgresql', + dbUrl, + } + ); + + // Ensure default values are correctly set + const db = enhance(); + await expect(db.bar.create({ data: {} })).resolves.toMatchObject({ + id: expect.any(String), + foo: { a: 'a' }, + fooList: [{ a: 'b' }], + }); + + // Ensure Zod Schemas are correctly generated + expect( + zodSchemas.objects.BarCreateInputObjectSchema.safeParse({ + foo: { a: 'a' }, + fooList: [{ a: 'a' }], + }).success + ).toBeTruthy(); + }); +});