New Features
A solid batch of additions in this release 🥳 !
Soft-Delete Plugin
A new @zenstackhq/plugin-soft-delete package implements soft delete by intercepting Kysely queries. Instead of physically removing rows, delete operations mark them with a timestamp, and reads automatically exclude the marked rows. doc
Declare the plugin and mark a nullable DateTime field with @deletedAt:
plugin softDelete {
provider = '@zenstackhq/plugin-soft-delete'
}
model User {
id Int @id @default(autoincrement())
email String @unique
deletedAt DateTime? @deletedAt
}Install it on your client at runtime:
import { ZenStackClient } from '@zenstackhq/orm';
import { SoftDeletePlugin } from '@zenstackhq/plugin-soft-delete';
const db = new ZenStackClient(schema, { ... }).$use(new SoftDeletePlugin());
// rewritten to set `deletedAt` — the row is kept in the database
await db.user.delete({ where: { id: user.id } });
// returns `null` — soft-deleted rows are hidden from reads
await db.user.findUnique({ where: { id: user.id } });Date and Time Validation
You can now validate string fields as ISO date and time values with the new @date and @time attributes (backed by zod.iso.date() and zod.iso.time() ). Contributed by @sanny-io.
model Event {
id Int @id @default(autoincrement())
startDate String @date
startTime String @time(3)
}Auto-Detect Import File Extension
The CLI now auto-detects the import file extension (e.g. .js vs extensionless) from your tsconfig.json when generating code, so generated imports match your module setup out of the box.
Faster Type Checking
We sped up type checking by short-circuiting some of the most expensive tsc traversals and type comparisons. We're seeing 70% speed-up and 70% fewer type instantiations with complex schemas.
For AI Coding Agents
We've published official ZenStack skills to skills.sh. See Setting Up AI Agents for more details.
Fixes and Improvements
- [policy] Fixed the
inoperator against enum lists with native enums #2718 - [tanstack-query] Fixed
pageParamin infinite queries for Vue by @caiotarifa #2713 - [orm] Fixed
_countwhen nested inside aninclude#2669 - [deps] Upgraded Langium to 4.2 to drop vulnerable
lodash-es#2704 - [orm] Forbid selecting
@omitfields whenallowQueryTimeOmitOverrideis false #2671 - [server] Omit relations to sliced-away models from the OpenAPI spec #2628
- [orm] Fixed the
isEmptyfunction when using thepostgresqldialect by @sanny-io - [language] Forbid duplicate
@defaultapplications by @sanny-io
Full Changelog: v3.7.2...v3.8.0