diff --git a/packages/schema/src/plugins/zod/utils/schema-gen.ts b/packages/schema/src/plugins/zod/utils/schema-gen.ts index e6a335221..5f3321b94 100644 --- a/packages/schema/src/plugins/zod/utils/schema-gen.ts +++ b/packages/schema/src/plugins/zod/utils/schema-gen.ts @@ -141,10 +141,14 @@ export function makeFieldSchema(field: DataModelField) { } if (field.attributes.some(isDefaultWithAuth)) { - // field uses `auth()` in `@default()`, this was transformed into a pseudo default - // value, while compiling to zod we should turn it into an optional field instead - // of `.default()` - schema += '.nullish()'; + if (field.type.optional) { + schema += '.nullish()'; + } else { + // field uses `auth()` in `@default()`, this was transformed into a pseudo default + // value, while compiling to zod we should turn it into an optional field instead + // of `.default()` + schema += '.optional()'; + } } else { const schemaDefault = getFieldSchemaDefault(field); if (schemaDefault !== undefined) { diff --git a/packages/schema/src/utils/pkg-utils.ts b/packages/schema/src/utils/pkg-utils.ts index 82b5ef019..067810a8e 100644 --- a/packages/schema/src/utils/pkg-utils.ts +++ b/packages/schema/src/utils/pkg-utils.ts @@ -13,7 +13,7 @@ export type PackageManagers = 'npm' | 'yarn' | 'pnpm'; * @export * @template e A type parameter that extends boolean */ -export type FindUp = e extends true ? string[] | undefined : string | undefined +export type FindUp = e extends true ? string[] | undefined : string | undefined; /** * Find and return file paths by searching parent directories based on the given names list and current working directory (cwd) path. * Optionally return a single path or multiple paths. @@ -28,7 +28,12 @@ export type FindUp = e extends true ? string[] | undefined : * @param [result=[]] An array of strings representing the accumulated results used in multiple results * @returns Path(s) to a specific file or folder within the directory or parent directories */ -export function findUp(names: string[], cwd: string = process.cwd(), multiple: e = false as e, result: string[] = []): FindUp { +export function findUp( + names: string[], + cwd: string = process.cwd(), + multiple: e = false as e, + result: string[] = [] +): FindUp { if (!names.some((name) => !!name)) return undefined; const target = names.find((name) => fs.existsSync(path.join(cwd, name))); if (multiple == false && target) return path.join(cwd, target) as FindUp; @@ -38,7 +43,6 @@ export function findUp(names: string[], cwd: string = return findUp(names, up, multiple, result); } - /** * Find a Node module/file given its name in a specific directory, with a fallback to the current working directory. * If the name is empty, return undefined. @@ -54,11 +58,11 @@ export function findNodeModulesFile(name: string, cwd: string = process.cwd()) { if (!name) return undefined; try { // Use require.resolve to find the module/file. The paths option allows specifying the directory to start from. - const resolvedPath = require.resolve(name, { paths: [cwd] }) - return resolvedPath + const resolvedPath = require.resolve(name, { paths: [cwd] }); + return resolvedPath; } catch (error) { // If require.resolve fails to find the module/file, it will throw an error. - return undefined + return undefined; } } @@ -86,7 +90,7 @@ export function installPackage( projectPath = '.', exactVersion = true ) { - const manager = pkgManager ?? getPackageManager(projectPath); + const manager = pkgManager ?? getPackageManager(projectPath).packageManager; console.log(`Installing package "${pkg}@${tag}" with ${manager}`); switch (manager) { case 'yarn': diff --git a/tests/regression/tests/issue-1378.test.ts b/tests/regression/tests/issue-1378.test.ts new file mode 100644 index 000000000..29d4b16a8 --- /dev/null +++ b/tests/regression/tests/issue-1378.test.ts @@ -0,0 +1,47 @@ +import { loadSchema } from '@zenstackhq/testtools'; + +describe('issue 1378', () => { + it('regression', async () => { + await loadSchema( + ` + model User { + id String @id @default(cuid()) + todos Todo[] + } + + model Todo { + id String @id @default(cuid()) + name String @length(3,255) + userId String @default(auth().id) + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + @@allow("all", auth() == user) + } + `, + { + extraDependencies: ['zod'], + extraSourceFiles: [ + { + name: 'main.ts', + content: ` + import { z } from 'zod'; + import { PrismaClient } from '@prisma/client'; + import { enhance } from '.zenstack/enhance'; + import { TodoCreateSchema } from '.zenstack/zod/models'; + + const prisma = new PrismaClient(); + const db = enhance(prisma); + + export const onSubmit = async (values: z.infer) => { + await db.todo.create({ + data: values, + }); + }; + `, + }, + ], + compile: true, + } + ); + }); +});