diff --git a/CLAUDE.md b/CLAUDE.md index 04e18dee4..151cb5688 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -75,6 +75,10 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - Kysely query builder as escape hatch instead of raw SQL - Schema-first approach with ZModel DSL extension of Prisma schema language +## Pull Requests + +- Always target the `dev` branch (not `main`) when creating PRs + ## Development Notes - Always run `zenstack generate` after modifying ZModel schemas diff --git a/package.json b/package.json index 6bf6bd622..bfd38f904 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-v3", - "version": "3.4.2", + "version": "3.4.3", "description": "ZenStack", "packageManager": "pnpm@10.23.0", "type": "module", diff --git a/packages/auth-adapters/better-auth/package.json b/packages/auth-adapters/better-auth/package.json index 974d52acb..13c02848d 100644 --- a/packages/auth-adapters/better-auth/package.json +++ b/packages/auth-adapters/better-auth/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/better-auth", - "version": "3.4.2", + "version": "3.4.3", "description": "ZenStack Better Auth Adapter. This adapter is modified from better-auth's Prisma adapter.", "type": "module", "scripts": { diff --git a/packages/cli/package.json b/packages/cli/package.json index c084b0403..f86a5dcb8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack CLI", "description": "FullStack database toolkit with built-in access control and automatic API generation.", - "version": "3.4.2", + "version": "3.4.3", "type": "module", "author": { "name": "ZenStack Team" diff --git a/packages/cli/src/actions/init.ts b/packages/cli/src/actions/init.ts index 03635736f..722d15fe6 100644 --- a/packages/cli/src/actions/init.ts +++ b/packages/cli/src/actions/init.ts @@ -13,6 +13,7 @@ import { STARTER_ZMODEL } from './templates'; export async function run(projectPath: string) { const packages = [ { name: '@zenstackhq/cli@latest', dev: true }, + { name: '@zenstackhq/schema@latest', dev: false }, { name: '@zenstackhq/orm@latest', dev: false }, ]; let pm = await detect(); diff --git a/packages/cli/src/actions/pull/provider/sqlite.ts b/packages/cli/src/actions/pull/provider/sqlite.ts index c4b06f367..435da9766 100644 --- a/packages/cli/src/actions/pull/provider/sqlite.ts +++ b/packages/cli/src/actions/pull/provider/sqlite.ts @@ -134,10 +134,11 @@ export const sqlite: IntrospectionProvider = { // List user tables and views from sqlite_schema (the master catalog). // sqlite_schema contains one row per table, view, index, and trigger. - // We filter to only tables/views and exclude internal sqlite_* objects. + // We filter to only tables/views and exclude internal sqlite_* objects + // and the Prisma migration tracking table. // The 'sql' column contains the original CREATE TABLE/VIEW statement. const tablesRaw = all<{ name: string; type: 'table' | 'view'; definition: string | null }>( - "SELECT name, type, sql AS definition FROM sqlite_schema WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' ORDER BY name", + "SELECT name, type, sql AS definition FROM sqlite_schema WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' AND name <> '_prisma_migrations' ORDER BY name", ); // Detect AUTOINCREMENT by parsing the CREATE TABLE statement diff --git a/packages/clients/client-helpers/package.json b/packages/clients/client-helpers/package.json index d890e4a1f..7398fc668 100644 --- a/packages/clients/client-helpers/package.json +++ b/packages/clients/client-helpers/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/client-helpers", - "version": "3.4.2", + "version": "3.4.3", "description": "Helpers for implementing clients that consume ZenStack's CRUD service", "type": "module", "scripts": { diff --git a/packages/clients/tanstack-query/package.json b/packages/clients/tanstack-query/package.json index 75c769c71..10e863990 100644 --- a/packages/clients/tanstack-query/package.json +++ b/packages/clients/tanstack-query/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/tanstack-query", - "version": "3.4.2", + "version": "3.4.3", "description": "TanStack Query Client for consuming ZenStack v3's CRUD service", "type": "module", "scripts": { diff --git a/packages/common-helpers/package.json b/packages/common-helpers/package.json index c4280f4c2..8547a2d16 100644 --- a/packages/common-helpers/package.json +++ b/packages/common-helpers/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/common-helpers", - "version": "3.4.2", + "version": "3.4.3", "description": "ZenStack Common Helpers", "type": "module", "scripts": { diff --git a/packages/config/eslint-config/package.json b/packages/config/eslint-config/package.json index 5ed6a2fa6..7409124f4 100644 --- a/packages/config/eslint-config/package.json +++ b/packages/config/eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/eslint-config", - "version": "3.4.2", + "version": "3.4.3", "type": "module", "private": true, "license": "MIT" diff --git a/packages/config/typescript-config/package.json b/packages/config/typescript-config/package.json index 594812ff1..f835a7ff0 100644 --- a/packages/config/typescript-config/package.json +++ b/packages/config/typescript-config/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/typescript-config", - "version": "3.4.2", + "version": "3.4.3", "private": true, "license": "MIT" } diff --git a/packages/config/vitest-config/package.json b/packages/config/vitest-config/package.json index 6cfa81d9e..43a833584 100644 --- a/packages/config/vitest-config/package.json +++ b/packages/config/vitest-config/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/vitest-config", "type": "module", - "version": "3.4.2", + "version": "3.4.3", "private": true, "license": "MIT", "exports": { diff --git a/packages/create-zenstack/package.json b/packages/create-zenstack/package.json index 15db4dd6d..793339fa5 100644 --- a/packages/create-zenstack/package.json +++ b/packages/create-zenstack/package.json @@ -1,6 +1,6 @@ { "name": "create-zenstack", - "version": "3.4.2", + "version": "3.4.3", "description": "Create a new ZenStack project", "type": "module", "scripts": { diff --git a/packages/create-zenstack/src/index.ts b/packages/create-zenstack/src/index.ts index 6dc8073da..040b46086 100644 --- a/packages/create-zenstack/src/index.ts +++ b/packages/create-zenstack/src/index.ts @@ -67,6 +67,7 @@ function initProject(name: string) { // install packages const packages = [ { name: '@zenstackhq/cli@latest', dev: true }, + { name: '@zenstackhq/schema@latest', dev: false }, { name: '@zenstackhq/orm@latest', dev: false }, { name: 'better-sqlite3', dev: false }, { name: '@types/better-sqlite3', dev: true }, diff --git a/packages/ide/vscode/package.json b/packages/ide/vscode/package.json index 7c9163405..269949542 100644 --- a/packages/ide/vscode/package.json +++ b/packages/ide/vscode/package.json @@ -1,7 +1,7 @@ { "name": "zenstack-v3", "publisher": "zenstack", - "version": "3.4.2", + "version": "3.4.3", "displayName": "ZenStack V3 Language Tools", "description": "VSCode extension for ZenStack (v3) ZModel language", "private": true, diff --git a/packages/language/package.json b/packages/language/package.json index ad5237c09..48dfd281e 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/language", "description": "ZenStack ZModel language specification", - "version": "3.4.2", + "version": "3.4.3", "license": "MIT", "author": "ZenStack Team", "files": [ diff --git a/packages/orm/package.json b/packages/orm/package.json index 94740879c..f5e06b033 100644 --- a/packages/orm/package.json +++ b/packages/orm/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/orm", - "version": "3.4.2", + "version": "3.4.3", "description": "ZenStack ORM", "type": "module", "scripts": { diff --git a/packages/plugins/policy/package.json b/packages/plugins/policy/package.json index 328c836d5..d97ef6e95 100644 --- a/packages/plugins/policy/package.json +++ b/packages/plugins/policy/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/plugin-policy", - "version": "3.4.2", + "version": "3.4.3", "description": "ZenStack Policy Plugin", "type": "module", "scripts": { diff --git a/packages/schema/package.json b/packages/schema/package.json index af505525d..57a0ef2fb 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/schema", - "version": "3.4.2", + "version": "3.4.3", "description": "ZenStack Runtime Schema", "type": "module", "scripts": { @@ -27,6 +27,10 @@ "types": "./dist/index.d.cts", "default": "./dist/index.cjs" } + }, + "./package.json": { + "import": "./package.json", + "require": "./package.json" } }, "dependencies": { diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 9aef48c08..144c5e649 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "3.4.2", + "version": "3.4.3", "description": "ZenStack SDK", "type": "module", "scripts": { diff --git a/packages/server/package.json b/packages/server/package.json index e4064ab63..897f69b7b 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/server", - "version": "3.4.2", + "version": "3.4.3", "description": "ZenStack automatic CRUD API handlers and server adapters", "type": "module", "scripts": { diff --git a/packages/testtools/package.json b/packages/testtools/package.json index 470d51fe7..bface5e91 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "3.4.2", + "version": "3.4.3", "description": "ZenStack Test Tools", "type": "module", "scripts": { diff --git a/packages/zod/package.json b/packages/zod/package.json index b20d9d039..bb5f27e08 100644 --- a/packages/zod/package.json +++ b/packages/zod/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/zod", - "version": "3.4.2", + "version": "3.4.3", "description": "ZenStack Zod integration", "type": "module", "scripts": { diff --git a/packages/zod/src/utils.ts b/packages/zod/src/utils.ts index 27f3c8579..5874d1664 100644 --- a/packages/zod/src/utils.ts +++ b/packages/zod/src/utils.ts @@ -31,11 +31,11 @@ export function addStringValidation( for (const attr of attributes) { switch (attr.name) { case '@length': { - const min = getArgValue(attr.args?.[0]?.value); + const min = getArgValue(attr.args?.find((a) => a.name === 'min')?.value); if (min !== undefined) { result = result.min(min); } - const max = getArgValue(attr.args?.[1]?.value); + const max = getArgValue(attr.args?.find((a) => a.name === 'max')?.value); if (max !== undefined) { result = result.max(max); } @@ -248,11 +248,11 @@ export function addListValidation( let result = schema; for (const attr of attributes) { if (attr.name === '@length') { - const min = getArgValue(attr.args?.[0]?.value); + const min = getArgValue(attr.args?.find((a) => a.name === 'min')?.value); if (min !== undefined) { result = result.min(min); } - const max = getArgValue(attr.args?.[1]?.value); + const max = getArgValue(attr.args?.find((a) => a.name === 'max')?.value); if (max !== undefined) { result = result.max(max); } diff --git a/samples/orm/package.json b/samples/orm/package.json index aa93377b2..43d2aac3c 100644 --- a/samples/orm/package.json +++ b/samples/orm/package.json @@ -1,6 +1,6 @@ { "name": "sample-orm", - "version": "3.4.2", + "version": "3.4.3", "description": "", "main": "index.js", "private": true, diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 6a53fd728..be50da497 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -1,6 +1,6 @@ { "name": "e2e", - "version": "3.4.2", + "version": "3.4.3", "private": true, "type": "module", "scripts": { diff --git a/tests/regression/package.json b/tests/regression/package.json index 9c0c2b7e5..ac9074539 100644 --- a/tests/regression/package.json +++ b/tests/regression/package.json @@ -1,6 +1,6 @@ { "name": "regression", - "version": "3.4.2", + "version": "3.4.3", "private": true, "type": "module", "scripts": { diff --git a/tests/regression/test/issue-2433.test.ts b/tests/regression/test/issue-2433.test.ts new file mode 100644 index 000000000..ca0e93a2d --- /dev/null +++ b/tests/regression/test/issue-2433.test.ts @@ -0,0 +1,43 @@ +import { createTestClient } from '@zenstackhq/testtools'; +import { describe, expect, it } from 'vitest'; + +// https://github.com/zenstackhq/zenstack/issues/2433 +describe('Regression for issue 2433', () => { + it('should accept short string when only @length(max: N) is specified', async () => { + const db = await createTestClient( + ` +model Post { + id String @id @default(cuid()) + content String @length(max: 10000) +} + `, + ); + // Should succeed: short content is within max limit + await expect(db.post.create({ data: { content: 'hello' } })).resolves.toMatchObject({ + content: 'hello', + }); + // Should fail validation: content exceeds max + await expect( + db.post.create({ data: { content: 'x'.repeat(10001) } }), + ).toBeRejectedByValidation(); + }); + + it('should reject short string when only @length(min: N) is specified', async () => { + const db = await createTestClient( + ` +model Post { + id String @id @default(cuid()) + content String @length(min: 5) +} + `, + ); + // Should succeed: content meets min length + await expect(db.post.create({ data: { content: 'hello world' } })).resolves.toMatchObject({ + content: 'hello world', + }); + // Should fail validation: content is too short + await expect( + db.post.create({ data: { content: 'hi' } }), + ).toBeRejectedByValidation(); + }); +}); diff --git a/tests/runtimes/bun/package.json b/tests/runtimes/bun/package.json index c933f0ddb..783aea594 100644 --- a/tests/runtimes/bun/package.json +++ b/tests/runtimes/bun/package.json @@ -1,6 +1,6 @@ { "name": "bun-e2e", - "version": "3.4.2", + "version": "3.4.3", "private": true, "type": "module", "scripts": { diff --git a/tests/runtimes/edge-runtime/package.json b/tests/runtimes/edge-runtime/package.json index a1ca4b4f1..e804c148d 100644 --- a/tests/runtimes/edge-runtime/package.json +++ b/tests/runtimes/edge-runtime/package.json @@ -1,6 +1,6 @@ { "name": "edge-runtime-e2e", - "version": "3.4.2", + "version": "3.4.3", "private": true, "type": "module", "scripts": {