diff --git a/.changeset/file-image-nullish.md b/.changeset/file-image-nullish.md deleted file mode 100644 index ce5442cc..00000000 --- a/.changeset/file-image-nullish.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@opensaas/stack-storage': patch ---- - -Fix file()/image() fields being required on create/update: their Zod schema now uses key-optionality (.nullish()) so an omitted field validates and stores null (Zod 4). diff --git a/.changeset/quiet-otters-gather.md b/.changeset/quiet-otters-gather.md deleted file mode 100644 index 16e2b3ae..00000000 --- a/.changeset/quiet-otters-gather.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -'@opensaas/stack-core': minor ---- - -Add `context.transaction()` — an interactive, hook-firing transaction - -You can now run multiple access-checked `context.db.*` operations atomically in one transaction while preserving the access/hook boundary (unlike raw `prisma.$transaction`, which bypasses both). The callback receives a full context whose `db.*` operations enforce access control and run list/field hooks, but persist against a single interactive transaction — so a throw anywhere rolls the whole transaction back. - -Options (notably `isolationLevel`, plus `maxWait`/`timeout`) pass through to Prisma, and serialization failures (Prisma `P2034`) propagate to the caller so you own the retry loop. This makes concurrency-sensitive invariants such as a capacity gate enforceable: - -```typescript -async function bookSlot(context, slotId) { - for (let attempt = 0; attempt < 5; attempt++) { - try { - return await context.transaction( - async (tx) => { - const count = await tx.db.booking.count({ where: { slotId } }) - if (count >= CAPACITY) return { booked: false } - return { booked: true, item: await tx.db.booking.create({ data: { slotId } }) } - }, - { isolationLevel: 'Serializable' }, - ) - } catch (err) { - // Serialization failures propagate — retry is caller-owned. - if (err && typeof err === 'object' && 'code' in err && err.code === 'P2034') continue - throw err - } - } - throw new Error('exceeded retry budget') -} -``` - -Nested `context.db` writes inside the callback join the outer transaction. New `StackContext`, `TransactionOptions`, and `TransactionIsolationLevel` types are exported from `@opensaas/stack-core`. See ADR-0012. diff --git a/.changeset/spotty-llamas-cheer.md b/.changeset/spotty-llamas-cheer.md deleted file mode 100644 index f6475b87..00000000 --- a/.changeset/spotty-llamas-cheer.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@opensaas/stack-core': patch ---- - -Apply a field's defaultValue to omitted inputs before create validation (resolve-then-validate, matching Keystone), so isRequired + defaultValue no longer fails on create. - -Note: because an omitted-but-defaulted field is now filled into `resolvedData` before validation, that field's create-side field-level `beforeOperation`/`afterOperation` hooks (gated on the field key being present in `resolvedData`) now fire for defaulted fields where they previously would not. diff --git a/packages/auth/CHANGELOG.md b/packages/auth/CHANGELOG.md index d2886c0c..5a6b8827 100644 --- a/packages/auth/CHANGELOG.md +++ b/packages/auth/CHANGELOG.md @@ -1,5 +1,7 @@ # @opensaas/stack-auth +## 0.26.0 + ## 0.25.0 ## 0.24.0 diff --git a/packages/auth/package.json b/packages/auth/package.json index 09763d9b..cea475ca 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@opensaas/stack-auth", - "version": "0.25.0", + "version": "0.26.0", "description": "Better-auth integration for OpenSaas Stack", "type": "module", "main": "./dist/index.js", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 8f98efea..0ff07acb 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,12 @@ # @opensaas/stack-cli +## 0.26.0 + +### Patch Changes + +- Updated dependencies [[`322d5b6`](https://github.com/OpenSaasAU/stack/commit/322d5b64d11c3e3401493511e0c0e3a1fa20e210), [`0be254e`](https://github.com/OpenSaasAU/stack/commit/0be254e2b2e6bbc0c2f168438aea49d2e1cc7f0b)]: + - @opensaas/stack-core@0.26.0 + ## 0.25.0 ### Minor Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 1c6422b7..ea288664 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@opensaas/stack-cli", - "version": "0.25.0", + "version": "0.26.0", "description": "CLI tools for OpenSaas Stack", "type": "module", "main": "./dist/index.js", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 2b7dbc29..f97c77c3 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,45 @@ # @opensaas/stack-core +## 0.26.0 + +### Minor Changes + +- [#616](https://github.com/OpenSaasAU/stack/pull/616) [`322d5b6`](https://github.com/OpenSaasAU/stack/commit/322d5b64d11c3e3401493511e0c0e3a1fa20e210) Thanks [@borisno2](https://github.com/borisno2)! - Add `context.transaction()` — an interactive, hook-firing transaction + + You can now run multiple access-checked `context.db.*` operations atomically in one transaction while preserving the access/hook boundary (unlike raw `prisma.$transaction`, which bypasses both). The callback receives a full context whose `db.*` operations enforce access control and run list/field hooks, but persist against a single interactive transaction — so a throw anywhere rolls the whole transaction back. + + Options (notably `isolationLevel`, plus `maxWait`/`timeout`) pass through to Prisma, and serialization failures (Prisma `P2034`) propagate to the caller so you own the retry loop. This makes concurrency-sensitive invariants such as a capacity gate enforceable: + + ```typescript + async function bookSlot(context, slotId) { + for (let attempt = 0; attempt < 5; attempt++) { + try { + return await context.transaction( + async (tx) => { + const count = await tx.db.booking.count({ where: { slotId } }) + if (count >= CAPACITY) return { booked: false } + return { booked: true, item: await tx.db.booking.create({ data: { slotId } }) } + }, + { isolationLevel: 'Serializable' }, + ) + } catch (err) { + // Serialization failures propagate — retry is caller-owned. + if (err && typeof err === 'object' && 'code' in err && err.code === 'P2034') continue + throw err + } + } + throw new Error('exceeded retry budget') + } + ``` + + Nested `context.db` writes inside the callback join the outer transaction. New `StackContext`, `TransactionOptions`, and `TransactionIsolationLevel` types are exported from `@opensaas/stack-core`. See ADR-0012. + +### Patch Changes + +- [#620](https://github.com/OpenSaasAU/stack/pull/620) [`0be254e`](https://github.com/OpenSaasAU/stack/commit/0be254e2b2e6bbc0c2f168438aea49d2e1cc7f0b) Thanks [@borisno2](https://github.com/borisno2)! - Apply a field's defaultValue to omitted inputs before create validation (resolve-then-validate, matching Keystone), so isRequired + defaultValue no longer fails on create. + + Note: because an omitted-but-defaulted field is now filled into `resolvedData` before validation, that field's create-side field-level `beforeOperation`/`afterOperation` hooks (gated on the field key being present in `resolvedData`) now fire for defaulted fields where they previously would not. + ## 0.25.0 ### Minor Changes diff --git a/packages/core/package.json b/packages/core/package.json index 0f86f084..b231e866 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@opensaas/stack-core", - "version": "0.25.0", + "version": "0.26.0", "description": "Core stack for OpenSaas - schema definition, access control, and runtime utilities", "type": "module", "main": "./dist/index.js", diff --git a/packages/rag/CHANGELOG.md b/packages/rag/CHANGELOG.md index dee1e27d..0c95a701 100644 --- a/packages/rag/CHANGELOG.md +++ b/packages/rag/CHANGELOG.md @@ -1,5 +1,7 @@ # @opensaas/stack-rag +## 0.26.0 + ## 0.25.0 ## 0.24.0 diff --git a/packages/rag/package.json b/packages/rag/package.json index 763b4a07..c05c7e90 100644 --- a/packages/rag/package.json +++ b/packages/rag/package.json @@ -1,6 +1,6 @@ { "name": "@opensaas/stack-rag", - "version": "0.25.0", + "version": "0.26.0", "description": "RAG and AI embeddings integration for OpenSaas Stack", "type": "module", "main": "./dist/index.js", diff --git a/packages/storage-s3/CHANGELOG.md b/packages/storage-s3/CHANGELOG.md index aef4090f..8ba20f69 100644 --- a/packages/storage-s3/CHANGELOG.md +++ b/packages/storage-s3/CHANGELOG.md @@ -1,5 +1,7 @@ # @opensaas/stack-storage-s3 +## 0.26.0 + ## 0.25.0 ## 0.24.0 diff --git a/packages/storage-s3/package.json b/packages/storage-s3/package.json index 01ccdbb8..24651a78 100644 --- a/packages/storage-s3/package.json +++ b/packages/storage-s3/package.json @@ -1,6 +1,6 @@ { "name": "@opensaas/stack-storage-s3", - "version": "0.25.0", + "version": "0.26.0", "description": "AWS S3 storage provider for OpenSaas Stack file uploads", "type": "module", "exports": { diff --git a/packages/storage-vercel/CHANGELOG.md b/packages/storage-vercel/CHANGELOG.md index 42020535..a43931f9 100644 --- a/packages/storage-vercel/CHANGELOG.md +++ b/packages/storage-vercel/CHANGELOG.md @@ -1,5 +1,7 @@ # @opensaas/stack-storage-vercel +## 0.26.0 + ## 0.25.0 ## 0.24.0 diff --git a/packages/storage-vercel/package.json b/packages/storage-vercel/package.json index 1ad35d68..b667c16c 100644 --- a/packages/storage-vercel/package.json +++ b/packages/storage-vercel/package.json @@ -1,6 +1,6 @@ { "name": "@opensaas/stack-storage-vercel", - "version": "0.25.0", + "version": "0.26.0", "description": "Vercel Blob storage provider for OpenSaas Stack file uploads", "type": "module", "exports": { diff --git a/packages/storage/CHANGELOG.md b/packages/storage/CHANGELOG.md index 5c694446..c782ac80 100644 --- a/packages/storage/CHANGELOG.md +++ b/packages/storage/CHANGELOG.md @@ -1,5 +1,11 @@ # @opensaas/stack-storage +## 0.26.0 + +### Patch Changes + +- [#619](https://github.com/OpenSaasAU/stack/pull/619) [`29ca3a9`](https://github.com/OpenSaasAU/stack/commit/29ca3a9fdd90af4e34b9ff770ae9a5ae94df2337) Thanks [@borisno2](https://github.com/borisno2)! - Fix file()/image() fields being required on create/update: their Zod schema now uses key-optionality (.nullish()) so an omitted field validates and stores null (Zod 4). + ## 0.25.0 ## 0.24.0 diff --git a/packages/storage/package.json b/packages/storage/package.json index aaf31f38..f1a139aa 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -1,6 +1,6 @@ { "name": "@opensaas/stack-storage", - "version": "0.25.0", + "version": "0.26.0", "description": "File and image upload field types with pluggable storage providers for OpenSaas Stack", "type": "module", "exports": { diff --git a/packages/tiptap/CHANGELOG.md b/packages/tiptap/CHANGELOG.md index b9aabcc9..0f9bcb1b 100644 --- a/packages/tiptap/CHANGELOG.md +++ b/packages/tiptap/CHANGELOG.md @@ -1,5 +1,7 @@ # @opensaas/stack-tiptap +## 0.26.0 + ## 0.25.0 ## 0.24.0 diff --git a/packages/tiptap/package.json b/packages/tiptap/package.json index 0f5b017b..5231a6cc 100644 --- a/packages/tiptap/package.json +++ b/packages/tiptap/package.json @@ -1,6 +1,6 @@ { "name": "@opensaas/stack-tiptap", - "version": "0.25.0", + "version": "0.26.0", "description": "Tiptap rich text editor integration for OpenSaas Stack", "type": "module", "main": "./dist/index.js", diff --git a/packages/ui/CHANGELOG.md b/packages/ui/CHANGELOG.md index 7a648843..dd5835d7 100644 --- a/packages/ui/CHANGELOG.md +++ b/packages/ui/CHANGELOG.md @@ -1,5 +1,7 @@ # @opensaas/stack-ui +## 0.26.0 + ## 0.25.0 ### Patch Changes diff --git a/packages/ui/package.json b/packages/ui/package.json index eef3e8d1..18477eb0 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opensaas/stack-ui", - "version": "0.25.0", + "version": "0.26.0", "description": "Composable React UI components for OpenSaas Stack", "type": "module", "main": "./dist/index.js",