diff --git a/.changeset/export-operation-result-types.md b/.changeset/export-operation-result-types.md deleted file mode 100644 index cee74560..00000000 --- a/.changeset/export-operation-result-types.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@cipherstash/stack": minor ---- - -Export the operation classes returned by the encryption and DynamoDB clients as public API. - -The classes returned from public methods are now exported and documented in the API reference, so their types can be named and their TSDoc links resolve. - -- From `@cipherstash/stack/encryption`: `EncryptOperation`, `EncryptQueryOperation`, `BatchEncryptQueryOperation`, `DecryptOperation`, `EncryptModelOperation`, `DecryptModelOperation`, `BulkEncryptOperation`, `BulkDecryptOperation`, `BulkEncryptModelsOperation`, `BulkDecryptModelsOperation`. `EncryptQueryOperation` and `BatchEncryptQueryOperation` were previously marked `@internal`; since they are returned from `EncryptionClient.encryptQuery`, they are now public for consistency with the other operations. -- From `@cipherstash/stack/dynamodb`: `EncryptModelOperation`, `DecryptModelOperation`, `BulkEncryptModelsOperation`, `BulkDecryptModelsOperation`. -- From `@cipherstash/stack/types`: `EncryptedQuery` and `EncryptedFromSchema`. - -The `*WithLockContext` variants returned by `.withLockContext()` remain internal — they share the same awaitable shape and are not intended to be named directly. - -No runtime behaviour changes; this only widens the exported surface and corrects TSDoc cross-references that previously failed to resolve. diff --git a/.changeset/restore-null-guards-in-encryption-ops.md b/.changeset/restore-null-guards-in-encryption-ops.md deleted file mode 100644 index 5c1798c9..00000000 --- a/.changeset/restore-null-guards-in-encryption-ops.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@cipherstash/stack": minor ---- - -Fix: restore runtime null short-circuits in the encryption operation classes. - -A prior refactor (`feat(stack): remove null from Encrypted type`) tightened the type signatures to disallow `null` and, alongside that, deleted the `if (value === null) return null` guards from every operation in `packages/stack/src/encryption/operations/`. The type guard does not survive runtime: callers reaching the operation through a cast (e.g. `null as any`), dynamic model walking, or JS interop would then have their null silently encrypted by protect-ffi into a real SteVec ciphertext (`{ k: 'sv', v: 2, ... }`) — which is observable, surprising, and breaks symmetry with the model-helpers layer that does still treat null as "absent" at the field level. - -Restored, mirroring the pattern in `@cipherstash/protect`: - -- `encrypt` / `encryptWithLockContext`: `if (plaintext === null) return null`. -- `bulkEncrypt` / `bulkEncryptWithLockContext`: per-element null filter; nulls are preserved in position in the output. -- `decrypt` / `decryptWithLockContext`: `if (encryptedData === null) return null`. -- `bulkDecrypt` / `bulkDecryptWithLockContext`: per-element null filter, position-preserving merge. -- `encryptQuery` / `encryptQueryWithLockContext`: `if (plaintext === null || plaintext === undefined) return { data: null }`. -- `batchEncryptQuery` / `batchEncryptQueryWithLockContext`: per-element null/undefined filter; null slots in the input array stay null in the result array. - -Type adjustments to support the runtime behavior honestly: - -- `BulkEncryptPayload['plaintext']`, `BulkEncryptedData['data']`, `BulkDecryptPayload['data']`, and the `T` of `BulkDecryptedData` all widen to `... | null`. Bulk APIs now accept and return mixed nullable arrays without filtering ahead of time. -- `EncryptedQueryResult` widens to include `null` so the batch query path can return position-stable arrays with null slots. -- `Encryption.encrypt()` and `Encryption.decrypt()` public signatures are unchanged — still narrow (`JsPlaintext` / `Encrypted` input, `Encrypted` / `JsPlaintext` non-nullable output). The runtime null short-circuit in `EncryptOperation` / `DecryptOperation` is defense in depth for callers reaching the operation classes through casts, dynamic field walking, or JS interop. The narrow-return contract holds for any caller that respects the input contract. diff --git a/examples/basic/CHANGELOG.md b/examples/basic/CHANGELOG.md index e7896dc3..90729ab3 100644 --- a/examples/basic/CHANGELOG.md +++ b/examples/basic/CHANGELOG.md @@ -1,5 +1,13 @@ # @cipherstash/basic-example +## 1.2.12 + +### Patch Changes + +- Updated dependencies [6e7ae4e] +- Updated dependencies [712d7fa] + - @cipherstash/stack@0.18.0 + ## 1.2.11 ### Patch Changes diff --git a/examples/basic/package.json b/examples/basic/package.json index 988bcde9..cb7d329d 100644 --- a/examples/basic/package.json +++ b/examples/basic/package.json @@ -1,7 +1,7 @@ { "name": "@cipherstash/basic-example", "private": true, - "version": "1.2.11", + "version": "1.2.12", "type": "module", "scripts": { "start": "tsx index.ts" diff --git a/examples/prisma/CHANGELOG.md b/examples/prisma/CHANGELOG.md index 3a7467c7..c1ce61e9 100644 --- a/examples/prisma/CHANGELOG.md +++ b/examples/prisma/CHANGELOG.md @@ -1,5 +1,14 @@ # @cipherstash/prisma-next-example +## 0.0.4 + +### Patch Changes + +- Updated dependencies [6e7ae4e] +- Updated dependencies [712d7fa] + - @cipherstash/stack@0.18.0 + - @cipherstash/prisma-next@0.3.1 + ## 0.0.3 ### Patch Changes diff --git a/examples/prisma/package.json b/examples/prisma/package.json index e326d626..dc8d3e84 100644 --- a/examples/prisma/package.json +++ b/examples/prisma/package.json @@ -1,7 +1,7 @@ { "name": "@cipherstash/prisma-next-example", "private": true, - "version": "0.0.3", + "version": "0.0.4", "description": "End-to-end example of @cipherstash/prisma-next: searchable application-layer encryption for Postgres with Prisma Next, using @cipherstash/stack as the SDK.", "type": "module", "scripts": { diff --git a/packages/bench/CHANGELOG.md b/packages/bench/CHANGELOG.md index 7d55d026..ec91d36b 100644 --- a/packages/bench/CHANGELOG.md +++ b/packages/bench/CHANGELOG.md @@ -1,5 +1,13 @@ # @cipherstash/bench +## 0.0.3 + +### Patch Changes + +- Updated dependencies [6e7ae4e] +- Updated dependencies [712d7fa] + - @cipherstash/stack@0.18.0 + ## 0.0.2 ### Patch Changes diff --git a/packages/bench/package.json b/packages/bench/package.json index fec5bc90..16636149 100644 --- a/packages/bench/package.json +++ b/packages/bench/package.json @@ -1,6 +1,6 @@ { "name": "@cipherstash/bench", - "version": "0.0.2", + "version": "0.0.3", "private": true, "description": "Performance / index-engagement benchmarks for stack integrations (Drizzle, encryptedSupabase, Prisma).", "type": "module", diff --git a/packages/prisma-next/CHANGELOG.md b/packages/prisma-next/CHANGELOG.md index 0729ca14..0625ee41 100644 --- a/packages/prisma-next/CHANGELOG.md +++ b/packages/prisma-next/CHANGELOG.md @@ -1,5 +1,13 @@ # @cipherstash/prisma-next +## 0.3.1 + +### Patch Changes + +- Updated dependencies [6e7ae4e] +- Updated dependencies [712d7fa] + - @cipherstash/stack@0.18.0 + ## 0.3.0 ### Minor Changes diff --git a/packages/prisma-next/package.json b/packages/prisma-next/package.json index 35b441ec..c0db088f 100644 --- a/packages/prisma-next/package.json +++ b/packages/prisma-next/package.json @@ -1,6 +1,6 @@ { "name": "@cipherstash/prisma-next", - "version": "0.3.0", + "version": "0.3.1", "license": "MIT", "author": "CipherStash ", "description": "CipherStash extension for Prisma Next: searchable application-layer field-level encryption for Postgres, with six encrypted column types, 17 query operators, bulk encrypt/decrypt middleware, and a baseline migration that installs the vendored EQL bundle SQL byte-for-byte.", diff --git a/packages/stack/CHANGELOG.md b/packages/stack/CHANGELOG.md index fe03dd26..ff6208f9 100644 --- a/packages/stack/CHANGELOG.md +++ b/packages/stack/CHANGELOG.md @@ -1,5 +1,40 @@ # @cipherstash/stack +## 0.18.0 + +### Minor Changes + +- 6e7ae4e: Export the operation classes returned by the encryption and DynamoDB clients as public API. + + The classes returned from public methods are now exported and documented in the API reference, so their types can be named and their TSDoc links resolve. + + - From `@cipherstash/stack/encryption`: `EncryptOperation`, `EncryptQueryOperation`, `BatchEncryptQueryOperation`, `DecryptOperation`, `EncryptModelOperation`, `DecryptModelOperation`, `BulkEncryptOperation`, `BulkDecryptOperation`, `BulkEncryptModelsOperation`, `BulkDecryptModelsOperation`. `EncryptQueryOperation` and `BatchEncryptQueryOperation` were previously marked `@internal`; since they are returned from `EncryptionClient.encryptQuery`, they are now public for consistency with the other operations. + - From `@cipherstash/stack/dynamodb`: `EncryptModelOperation`, `DecryptModelOperation`, `BulkEncryptModelsOperation`, `BulkDecryptModelsOperation`. + - From `@cipherstash/stack/types`: `EncryptedQuery` and `EncryptedFromSchema`. + + The `*WithLockContext` variants returned by `.withLockContext()` remain internal — they share the same awaitable shape and are not intended to be named directly. + + No runtime behaviour changes; this only widens the exported surface and corrects TSDoc cross-references that previously failed to resolve. + +- 712d7fa: Fix: restore runtime null short-circuits in the encryption operation classes. + + A prior refactor (`feat(stack): remove null from Encrypted type`) tightened the type signatures to disallow `null` and, alongside that, deleted the `if (value === null) return null` guards from every operation in `packages/stack/src/encryption/operations/`. The type guard does not survive runtime: callers reaching the operation through a cast (e.g. `null as any`), dynamic model walking, or JS interop would then have their null silently encrypted by protect-ffi into a real SteVec ciphertext (`{ k: 'sv', v: 2, ... }`) — which is observable, surprising, and breaks symmetry with the model-helpers layer that does still treat null as "absent" at the field level. + + Restored, mirroring the pattern in `@cipherstash/protect`: + + - `encrypt` / `encryptWithLockContext`: `if (plaintext === null) return null`. + - `bulkEncrypt` / `bulkEncryptWithLockContext`: per-element null filter; nulls are preserved in position in the output. + - `decrypt` / `decryptWithLockContext`: `if (encryptedData === null) return null`. + - `bulkDecrypt` / `bulkDecryptWithLockContext`: per-element null filter, position-preserving merge. + - `encryptQuery` / `encryptQueryWithLockContext`: `if (plaintext === null || plaintext === undefined) return { data: null }`. + - `batchEncryptQuery` / `batchEncryptQueryWithLockContext`: per-element null/undefined filter; null slots in the input array stay null in the result array. + + Type adjustments to support the runtime behavior honestly: + + - `BulkEncryptPayload['plaintext']`, `BulkEncryptedData['data']`, `BulkDecryptPayload['data']`, and the `T` of `BulkDecryptedData` all widen to `... | null`. Bulk APIs now accept and return mixed nullable arrays without filtering ahead of time. + - `EncryptedQueryResult` widens to include `null` so the batch query path can return position-stable arrays with null slots. + - `Encryption.encrypt()` and `Encryption.decrypt()` public signatures are unchanged — still narrow (`JsPlaintext` / `Encrypted` input, `Encrypted` / `JsPlaintext` non-nullable output). The runtime null short-circuit in `EncryptOperation` / `DecryptOperation` is defense in depth for callers reaching the operation classes through casts, dynamic field walking, or JS interop. The narrow-return contract holds for any caller that respects the input contract. + ## 0.17.0 ### Minor Changes diff --git a/packages/stack/package.json b/packages/stack/package.json index fe5d15e4..cd36137e 100644 --- a/packages/stack/package.json +++ b/packages/stack/package.json @@ -1,6 +1,6 @@ { "name": "@cipherstash/stack", - "version": "0.17.0", + "version": "0.18.0", "description": "CipherStash Stack for TypeScript and JavaScript", "keywords": [ "encrypted",