Skip to content

Commit dd561bf

Browse files
committed
docs(prisma-next): document EQL v3 String support
1 parent e9aca23 commit dd561bf

2 files changed

Lines changed: 37 additions & 4 deletions

File tree

packages/prisma-next/DEVELOPING.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,18 @@ packages/3-extensions/cipherstash/
4141
│ └── descriptor-meta.ts cipherstashPackMeta + authoring + storage + codec instances
4242
├── middleware/
4343
│ └── bulk-encrypt.ts bulkEncryptMiddleware(sdk) + stampRoutingKeysFromAst
44+
├── v3/ EQL v3 (domain-based; text/String scalar)
45+
│ ├── domain-map.ts (scalar, index) → eql_v3 domain SSOT
46+
│ └── wire-codec.ts plain-jsonb wire (encode/decodeEqlV3Wire)
4447
├── migration/
4548
│ ├── codec-hooks-factory.ts makeCipherstashCodecHooks({...}) factory (per codec)
49+
│ ├── codec-hooks-v3.ts v3 hooks: expandNativeType → per-index domain
4650
│ ├── cipherstash-codec.ts cipherstashStringCodecHooks string-only hook bundle
4751
│ ├── call-classes.ts CipherstashAddSearchConfigCall / RemoveSearchConfigCall
48-
│ ├── eql-bundle.ts EQL install SQL (vendored byte-for-byte)
49-
│ └── eql-install.generated.ts generated EQL install op definitions
52+
│ ├── eql-bundle.ts EQL v2 install SQL (vendored byte-for-byte)
53+
│ ├── eql-install.generated.ts generated EQL v2 install op definitions
54+
│ ├── eql-v3-bundle.ts EQL v3 install SQL (vendored byte-for-byte)
55+
│ └── eql-v3-install.generated.ts GENERATED — see scripts/REFRESH_EQL_V3.md
5056
├── types/
5157
│ ├── codec-types.ts CipherstashCodecTypes interface (decode return types)
5258
│ └── operation-types.ts QueryOperationTypes augmentation (column-method surface)

packages/prisma-next/README.md

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,39 @@ See the [full documentation](https://cipherstash.com/docs/stack/cipherstash/encr
9494
| `./stack` | One-call setup against `@cipherstash/stack`: `cipherstashFromStack`, `deriveStackSchemas`, `createCipherstashSdk` |
9595
| `./control` | `SqlControlExtensionDescriptor` (contract space + pack meta + codec lifecycle hooks) |
9696
| `./runtime` | Six envelope classes + `CipherstashSdk` + codec runtime + `decryptAll` + four free-standing helpers |
97-
| `./middleware` | `bulkEncryptMiddleware(sdk)` |
97+
| `./middleware` | `bulkEncryptMiddleware(sdk)` (v2) + `bulkEncryptV3Middleware(sdk)` (v3) |
9898
| `./pack` | `cipherstashPackMeta` for TS contract authoring |
99-
| `./column-types` | Six TS factories: `encryptedString` / `encryptedDouble` / `encryptedBigInt` / `encryptedDate` / `encryptedBoolean` / `encryptedJson` |
99+
| `./column-types` | TS factories: `encryptedString` / `encryptedDouble` / `encryptedBigInt` / `encryptedDate` / `encryptedBoolean` / `encryptedJson` (v2) + `encryptedStringV3` (v3) |
100100

101101
`./control`, `./runtime`, and `./middleware` are tree-shakable. `./stack` sits on top of `./runtime` + `./middleware` and additionally pulls in `@cipherstash/stack`; consumers who implement `CipherstashSdk` against a different KMS skip `./stack` and pay no `@cipherstash/stack` bundle cost.
102102

103+
## EQL v3 (experimental)
104+
105+
EQL v3 is a **domain-based** encryption model that coexists with v2: v2 columns keep their `eql_v2_encrypted` storage and SQL, and v3 columns are added independently. Milestone 1 supports the **`String`/`text`** scalar only.
106+
107+
A v3 column declares **exactly one index capability** (one Postgres domain) via `EncryptedStringV3`:
108+
109+
```prisma
110+
model Doc {
111+
id String @id
112+
email cipherstash.EncryptedStringV3({ index: "equality" }) // → eql_v3.text_eq
113+
bio cipherstash.EncryptedStringV3({ index: "freeTextSearch" }) // → eql_v3.text_match
114+
name cipherstash.EncryptedStringV3({ index: "orderAndRange" }) // → eql_v3.text_ord
115+
}
116+
```
117+
118+
…or in TypeScript: `encryptedStringV3({ index: 'equality' })`.
119+
120+
**Operators per index** (the v3 column carries the cipherstash traits, so the same `cipherstash*` operator surface attaches; the column's single index decides which are valid):
121+
122+
| Index | Domain | Valid operators |
123+
| ----------------- | ------------------ | --------------------------------------------------------------------------------- |
124+
| `equality` | `eql_v3.text_eq` | `cipherstashEq` / `cipherstashNe` / `cipherstashInArray` / `cipherstashNotInArray` |
125+
| `orderAndRange` | `eql_v3.text_ord` | `cipherstashGt` / `cipherstashGte` / `cipherstashLt` / `cipherstashLte` / `cipherstashBetween` / `cipherstashNotBetween` |
126+
| `freeTextSearch` | `eql_v3.text_match`| `cipherstashIlike` / `cipherstashNotIlike` (containment) |
127+
128+
Applying an operator that needs a different index than the column declares (e.g. `cipherstashGt` on an `equality` column) is rejected with a clear `TypeError` at **query-build time** — a runtime guard, not compile-time gating (milestone-1 trade-off; per-index codec ids could restore compile-time gating later). The v3 baseline migration installs the `eql_v3` bundle alongside the v2 bundle; both `bulkEncryptMiddleware` and `bulkEncryptV3Middleware` register over the same SDK and ignore each other's columns.
129+
103130
## Authentication
104131

105132
There are 2 main ways to authenticate to CipherStash:

0 commit comments

Comments
 (0)