@cipherstash/stack 0.18.0 → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +704 -0
  2. package/README.md +97 -79
  3. package/dist/adapter-kit.cjs +923 -0
  4. package/dist/adapter-kit.cjs.map +1 -0
  5. package/dist/adapter-kit.d.cts +82 -0
  6. package/dist/adapter-kit.d.ts +82 -0
  7. package/dist/adapter-kit.js +47 -0
  8. package/dist/adapter-kit.js.map +1 -0
  9. package/dist/base-operation-AOAIvsSB.d.cts +32 -0
  10. package/dist/base-operation-FXEzUXIq.d.ts +32 -0
  11. package/dist/{chunk-VPOTNP4K.js → chunk-3B5ZX3IS.js} +3 -1
  12. package/dist/chunk-3B5ZX3IS.js.map +1 -0
  13. package/dist/chunk-7333ZC6L.js +48 -0
  14. package/dist/chunk-7333ZC6L.js.map +1 -0
  15. package/dist/{chunk-XWPGAHBZ.js → chunk-BNO32ZMV.js} +1 -1
  16. package/dist/chunk-BNO32ZMV.js.map +1 -0
  17. package/dist/chunk-CLM7E4I6.js +4439 -0
  18. package/dist/chunk-CLM7E4I6.js.map +1 -0
  19. package/dist/{chunk-LLCCNKDL.js → chunk-HQANMV7R.js} +3 -3
  20. package/dist/{chunk-LLCCNKDL.js.map → chunk-HQANMV7R.js.map} +1 -1
  21. package/dist/chunk-JSG2AMDI.js +17 -0
  22. package/dist/chunk-JSG2AMDI.js.map +1 -0
  23. package/dist/chunk-OFQ555AX.js +191 -0
  24. package/dist/chunk-OFQ555AX.js.map +1 -0
  25. package/dist/chunk-PZ5AY32C.js +10 -0
  26. package/dist/chunk-PZ5AY32C.js.map +1 -0
  27. package/dist/chunk-V2Q3NYIH.js +494 -0
  28. package/dist/chunk-V2Q3NYIH.js.map +1 -0
  29. package/dist/chunk-X3JRXEIB.js +98 -0
  30. package/dist/chunk-X3JRXEIB.js.map +1 -0
  31. package/dist/{chunk-ZYOZHZMJ.js → chunk-ZTP5QJ27.js} +193 -169
  32. package/dist/chunk-ZTP5QJ27.js.map +1 -0
  33. package/dist/client.cjs +4124 -49
  34. package/dist/client.cjs.map +1 -1
  35. package/dist/client.d.cts +6 -5
  36. package/dist/client.d.ts +6 -5
  37. package/dist/client.js +3 -1
  38. package/dist/columns-D2_YzrCX.d.cts +622 -0
  39. package/dist/columns-rZc7fQHI.d.ts +622 -0
  40. package/dist/dynamodb/index.cjs +19 -12
  41. package/dist/dynamodb/index.cjs.map +1 -1
  42. package/dist/dynamodb/index.d.cts +3 -2
  43. package/dist/dynamodb/index.d.ts +3 -2
  44. package/dist/dynamodb/index.js +8 -10
  45. package/dist/dynamodb/index.js.map +1 -1
  46. package/dist/encryption/index.cjs +4496 -222
  47. package/dist/encryption/index.cjs.map +1 -1
  48. package/dist/encryption/index.d.cts +807 -6
  49. package/dist/encryption/index.d.ts +807 -6
  50. package/dist/encryption/index.js +15 -7
  51. package/dist/encryption/v3.cjs +7896 -0
  52. package/dist/encryption/v3.cjs.map +1 -0
  53. package/dist/encryption/v3.d.cts +103 -0
  54. package/dist/encryption/v3.d.ts +103 -0
  55. package/dist/encryption/v3.js +189 -0
  56. package/dist/encryption/v3.js.map +1 -0
  57. package/dist/eql/v3/index.cjs +663 -0
  58. package/dist/eql/v3/index.cjs.map +1 -0
  59. package/dist/eql/v3/index.d.cts +173 -0
  60. package/dist/eql/v3/index.d.ts +173 -0
  61. package/dist/eql/v3/index.js +99 -0
  62. package/dist/eql/v3/index.js.map +1 -0
  63. package/dist/errors/index.js +1 -0
  64. package/dist/identity/index.cjs +55 -35
  65. package/dist/identity/index.cjs.map +1 -1
  66. package/dist/identity/index.d.cts +54 -30
  67. package/dist/identity/index.d.ts +54 -30
  68. package/dist/identity/index.js +9 -177
  69. package/dist/identity/index.js.map +1 -1
  70. package/dist/index-BquA71_Y.d.ts +24 -0
  71. package/dist/index-fhWTOV0K.d.cts +24 -0
  72. package/dist/index.cjs +4547 -243
  73. package/dist/index.cjs.map +1 -1
  74. package/dist/index.d.cts +18 -19
  75. package/dist/index.d.ts +18 -19
  76. package/dist/index.js +20 -5
  77. package/dist/index.js.map +1 -1
  78. package/dist/schema/index.cjs +4128 -49
  79. package/dist/schema/index.cjs.map +1 -1
  80. package/dist/schema/index.d.cts +1 -1
  81. package/dist/schema/index.d.ts +1 -1
  82. package/dist/schema/index.js +3 -1
  83. package/dist/{types-public-BTxqjmtv.d.cts → types-public-QMjYNfQO.d.cts} +448 -251
  84. package/dist/{types-public-BTxqjmtv.d.ts → types-public-QMjYNfQO.d.ts} +448 -251
  85. package/dist/types-public.cjs.map +1 -1
  86. package/dist/types-public.d.cts +2 -2
  87. package/dist/types-public.d.ts +2 -2
  88. package/dist/types-public.js +2 -1
  89. package/dist/wasm-inline.d.ts +1643 -0
  90. package/dist/wasm-inline.js +4901 -0
  91. package/dist/wasm-inline.js.map +1 -0
  92. package/package.json +74 -52
  93. package/dist/chunk-VPOTNP4K.js.map +0 -1
  94. package/dist/chunk-XWPGAHBZ.js.map +0 -1
  95. package/dist/chunk-YWQXTZ5M.js +0 -383
  96. package/dist/chunk-YWQXTZ5M.js.map +0 -1
  97. package/dist/chunk-ZYOZHZMJ.js.map +0 -1
  98. package/dist/client-CIsfZ2zg.d.ts +0 -692
  99. package/dist/client-Dt98Rugc.d.cts +0 -692
  100. package/dist/drizzle/index.cjs +0 -1558
  101. package/dist/drizzle/index.cjs.map +0 -1
  102. package/dist/drizzle/index.d.cts +0 -358
  103. package/dist/drizzle/index.d.ts +0 -358
  104. package/dist/drizzle/index.js +0 -1215
  105. package/dist/drizzle/index.js.map +0 -1
  106. package/dist/supabase/index.cjs +0 -1526
  107. package/dist/supabase/index.cjs.map +0 -1
  108. package/dist/supabase/index.d.cts +0 -144
  109. package/dist/supabase/index.d.ts +0 -144
  110. package/dist/supabase/index.js +0 -899
  111. package/dist/supabase/index.js.map +0 -1
@@ -1,191 +1,5 @@
1
+ import { JsPlaintext, EncryptedPayload, newClient, EncryptedQuery as EncryptedQuery$1, EncryptedV3Query, AuthStrategy, Encrypted as Encrypted$1 } from '@cipherstash/protect-ffi';
1
2
  import { z } from 'zod';
2
- import { Encrypted as Encrypted$1, newClient, EncryptedQuery as EncryptedQuery$1, JsPlaintext } from '@cipherstash/protect-ffi';
3
-
4
- /** Brand symbol for nominal typing */
5
- declare const __brand: unique symbol;
6
- /** Creates a branded type that is structurally incompatible with the base type */
7
- type Brand<T, B extends string> = T & {
8
- readonly [__brand]: B;
9
- };
10
- type Client = Awaited<ReturnType<typeof newClient>> | undefined;
11
- /** A branded type representing encrypted data. Cannot be accidentally used as plaintext. */
12
- type EncryptedValue = Brand<Encrypted$1, 'encrypted'>;
13
- /** Structural type representing encrypted data stored in the database. Always
14
- * carries a ciphertext. See also `EncryptedValue` for branded nominal typing,
15
- * and {@link EncryptedQuery} for the search-term shape returned by
16
- * `encryptQuery`. */
17
- type Encrypted = Encrypted$1;
18
- /** Structural type representing an encrypted query term (search needle)
19
- * returned by `encryptQuery` / `encryptQueryBulk` for scalar
20
- * (`unique` / `match` / `ore`) lookups and `ste_vec_selector` JSON path
21
- * queries. Carries no ciphertext — matched against stored values, never
22
- * decrypted. JSON containment queries (`ste_vec_term`) return a
23
- * storage-shaped {@link Encrypted} payload instead. */
24
- type EncryptedQuery = EncryptedQuery$1;
25
- type KeysetIdentifier = {
26
- name: string;
27
- } | {
28
- id: string;
29
- };
30
- type ClientConfig = {
31
- /**
32
- * The CipherStash workspace CRN (Cloud Resource Name).
33
- * Format: `crn:<region>.aws:<workspace-id>`.
34
- * Can also be set via the `CS_WORKSPACE_CRN` environment variable.
35
- */
36
- workspaceCrn?: string;
37
- /**
38
- * The API access key used for authenticating with the CipherStash API.
39
- * Can also be set via the `CS_CLIENT_ACCESS_KEY` environment variable.
40
- * Obtain this from the CipherStash dashboard after creating a workspace.
41
- */
42
- accessKey?: string;
43
- /**
44
- * The client identifier used to authenticate with CipherStash services.
45
- * Can also be set via the `CS_CLIENT_ID` environment variable.
46
- * Generated during workspace onboarding in the CipherStash dashboard.
47
- */
48
- clientId?: string;
49
- /**
50
- * The client key material used in combination with ZeroKMS for encryption operations.
51
- * Can also be set via the `CS_CLIENT_KEY` environment variable.
52
- * Generated during workspace onboarding in the CipherStash dashboard.
53
- */
54
- clientKey?: string;
55
- /**
56
- * An optional keyset identifier for multi-tenant encryption.
57
- * Each keyset provides cryptographic isolation, giving each tenant its own keyspace.
58
- * Specify by name (`{ name: "tenant-a" }`) or UUID (`{ id: "..." }`).
59
- * Keysets are created and managed in the CipherStash dashboard.
60
- */
61
- keyset?: KeysetIdentifier;
62
- };
63
- type AtLeastOneCsTable<T> = [T, ...T[]];
64
- type EncryptionClientConfig = {
65
- schemas: AtLeastOneCsTable<EncryptedTable<EncryptedTableColumn>>;
66
- config?: ClientConfig;
67
- };
68
- /**
69
- * Options for single-value encrypt operations.
70
- * Use a column from your table schema (from {@link encryptedColumn}) or a nested
71
- * field (from {@link encryptedField}) as the target for encryption.
72
- */
73
- type EncryptOptions = {
74
- /** The column or nested field to encrypt into. From {@link EncryptedColumn} or {@link EncryptedField}. */
75
- column: EncryptedColumn | EncryptedField;
76
- table: EncryptedTable<EncryptedTableColumn>;
77
- };
78
- /** Format for encrypted query/search term return values */
79
- type EncryptedReturnType = 'eql' | 'composite-literal' | 'escaped-composite-literal';
80
- type SearchTerm = {
81
- value: JsPlaintext;
82
- column: EncryptedColumn;
83
- table: EncryptedTable<EncryptedTableColumn>;
84
- returnType?: EncryptedReturnType;
85
- };
86
- /** Encrypted search term result. `eql` return type yields either a storage
87
- * payload (`Encrypted`, for `ste_vec_term`) or a query-only term
88
- * (`EncryptedQuery`, for scalar lookups and `ste_vec_selector`); the
89
- * `composite-literal` return types yield a string. */
90
- type EncryptedSearchTerm = Encrypted | EncryptedQuery | string;
91
- /** Result of encryptQuery (single or batch). `eql` return type yields either a
92
- * storage payload (`Encrypted`) or a query-only term (`EncryptedQuery`); the
93
- * `composite-literal` return types yield a string. */
94
- type EncryptedQueryResult = Encrypted | EncryptedQuery | string | null;
95
- type EncryptedFields<T> = {
96
- [K in keyof T as NonNullable<T[K]> extends Encrypted ? K : never]: T[K];
97
- };
98
- type OtherFields<T> = {
99
- [K in keyof T as NonNullable<T[K]> extends Encrypted ? never : K]: T[K];
100
- };
101
- type DecryptedFields<T> = {
102
- [K in keyof T as NonNullable<T[K]> extends Encrypted ? K : never]: null extends T[K] ? string | null : string;
103
- };
104
- /** Model with encrypted fields replaced by plaintext (decrypted) values */
105
- type Decrypted<T> = OtherFields<T> & DecryptedFields<T>;
106
- /**
107
- * Maps a plaintext model type to its encrypted form using the table schema.
108
- *
109
- * Fields whose keys match columns defined in `S` become `Encrypted`;
110
- * all other fields retain their original types from `T`.
111
- *
112
- * When `S` is the widened `EncryptedTableColumn` (e.g. when a user passes an
113
- * explicit `<User>` type argument without specifying `S`), the type degrades
114
- * gracefully to `T` — preserving backward compatibility.
115
- *
116
- * @typeParam T - The plaintext model type (e.g. `{ id: string; email: string }`)
117
- * @typeParam S - The table schema column definition, inferred from the `table` argument
118
- *
119
- * @example
120
- * ```typescript
121
- * type User = { id: string; email: string }
122
- * // With a schema that defines `email`:
123
- * type Encrypted = EncryptedFromSchema<User, { email: EncryptedColumn }>
124
- * // => { id: string; email: Encrypted }
125
- * ```
126
- */
127
- type EncryptedFromSchema<T, S extends EncryptedTableColumn> = {
128
- [K in keyof T]: [K] extends [keyof S] ? [S[K & keyof S]] extends [EncryptedColumn | EncryptedField] ? null extends T[K] ? Encrypted | null : Encrypted : T[K] : T[K];
129
- };
130
- type BulkEncryptPayload = Array<{
131
- id?: string;
132
- plaintext: JsPlaintext | null;
133
- }>;
134
- type BulkEncryptedData = Array<{
135
- id?: string;
136
- data: Encrypted | null;
137
- }>;
138
- type BulkDecryptPayload = Array<{
139
- id?: string;
140
- data: Encrypted | null;
141
- }>;
142
- type BulkDecryptedData = Array<DecryptionResult<JsPlaintext | null>>;
143
- type DecryptionSuccess<T> = {
144
- error?: never;
145
- data: T;
146
- id?: string;
147
- };
148
- type DecryptionError<T> = {
149
- error: T;
150
- id?: string;
151
- data?: never;
152
- };
153
- /**
154
- * Result type for individual items in bulk decrypt operations.
155
- * Uses `error`/`data` fields (not `failure`/`data`) since bulk operations
156
- * can have per-item failures.
157
- */
158
- type DecryptionResult<T> = DecryptionSuccess<T> | DecryptionError<T>;
159
- /**
160
- * User-facing query type names for encrypting query values.
161
- *
162
- * - `'equality'`: Exact match. [Exact Queries](https://cipherstash.com/docs/stack/cipherstash/encryption/searchable-encryption)
163
- * - `'freeTextSearch'`: Text search. [Match Queries](https://cipherstash.com/docs/stack/cipherstash/encryption/searchable-encryption)
164
- * - `'orderAndRange'`: Comparison and range. [Range Queries](https://cipherstash.com/docs/stack/cipherstash/encryption/searchable-encryption)
165
- * - `'steVecSelector'`: JSONPath selector (e.g. `'$.user.email'`)
166
- * - `'steVecTerm'`: Containment (e.g. `{ role: 'admin' }`)
167
- * - `'searchableJson'`: Auto-infers selector or term from plaintext type (recommended)
168
- */
169
- type QueryTypeName = 'orderAndRange' | 'freeTextSearch' | 'equality' | 'steVecSelector' | 'steVecTerm' | 'searchableJson';
170
- declare const queryTypes: {
171
- readonly orderAndRange: "orderAndRange";
172
- readonly freeTextSearch: "freeTextSearch";
173
- readonly equality: "equality";
174
- readonly steVecSelector: "steVecSelector";
175
- readonly steVecTerm: "steVecTerm";
176
- readonly searchableJson: "searchableJson";
177
- };
178
- /** @internal */
179
- type QueryTermBase = {
180
- column: EncryptedColumn;
181
- table: EncryptedTable<EncryptedTableColumn>;
182
- queryType?: QueryTypeName;
183
- returnType?: EncryptedReturnType;
184
- };
185
- type EncryptQueryOptions = QueryTermBase;
186
- type ScalarQueryTerm = QueryTermBase & {
187
- value: JsPlaintext;
188
- };
189
3
 
190
4
  /**
191
5
  * Allowed cast types for CipherStash schema fields.
@@ -194,6 +8,7 @@ type ScalarQueryTerm = QueryTermBase & {
194
8
  * - `"bigint"`
195
9
  * - `"boolean"`
196
10
  * - `"date"`
11
+ * - `"timestamp"`
197
12
  * - `"number"`
198
13
  * - `"string"`
199
14
  * - `"json"`
@@ -209,11 +24,15 @@ type ScalarQueryTerm = QueryTermBase & {
209
24
  * EQL cast types — the PostgreSQL-aligned types that EQL actually accepts.
210
25
  * These are stored in the `cast_as` field of the EncryptConfig.
211
26
  */
212
- declare const eqlCastAsEnum: z.ZodDefault<z.ZodEnum<["text", "int", "small_int", "big_int", "real", "double", "boolean", "date", "jsonb"]>>;
27
+ declare const eqlCastAsEnum: z.ZodDefault<z.ZodEnum<["text", "int", "small_int", "big_int", "real", "double", "boolean", "date", "timestamp", "jsonb"]>>;
213
28
  /**
214
29
  * SDK-facing data types — developer-friendly aliases accepted by `dataType()`.
30
+ *
31
+ * `timestamp` is distinct from `date`: `date` is calendar-date only (time-of-day
32
+ * truncated to midnight), while `timestamp` preserves the full date+time. v3
33
+ * `timestamp` domains set `cast_as: 'timestamp'` so the FFI keeps the instant.
215
34
  */
216
- declare const castAsEnum: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json", "text"]>>;
35
+ declare const castAsEnum: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "timestamp", "number", "string", "json", "text"]>>;
217
36
  /**
218
37
  * Map SDK-facing data types to EQL `cast_as` values.
219
38
  *
@@ -229,6 +48,7 @@ declare const tokenFilterSchema: z.ZodObject<{
229
48
  kind: "downcase";
230
49
  }>;
231
50
  declare const oreIndexOptsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
51
+ declare const opeIndexOptsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
232
52
  declare const uniqueIndexOptsSchema: z.ZodObject<{
233
53
  token_filters: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
234
54
  kind: z.ZodLiteral<"downcase">;
@@ -274,28 +94,28 @@ declare const matchIndexOptsSchema: z.ZodObject<{
274
94
  m: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
275
95
  include_original: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
276
96
  }, "strip", z.ZodTypeAny, {
277
- token_filters?: {
278
- kind: "downcase";
279
- }[] | undefined;
280
97
  tokenizer?: {
281
98
  kind: "standard";
282
99
  } | {
283
100
  kind: "ngram";
284
101
  token_length: number;
285
102
  } | undefined;
103
+ token_filters?: {
104
+ kind: "downcase";
105
+ }[] | undefined;
286
106
  k?: number | undefined;
287
107
  m?: number | undefined;
288
108
  include_original?: boolean | undefined;
289
109
  }, {
290
- token_filters?: {
291
- kind: "downcase";
292
- }[] | undefined;
293
110
  tokenizer?: {
294
111
  kind: "standard";
295
112
  } | {
296
113
  kind: "ngram";
297
114
  token_length: number;
298
115
  } | undefined;
116
+ token_filters?: {
117
+ kind: "downcase";
118
+ }[] | undefined;
299
119
  k?: number | undefined;
300
120
  m?: number | undefined;
301
121
  include_original?: boolean | undefined;
@@ -315,6 +135,7 @@ declare const steVecIndexOptsSchema: z.ZodObject<{
315
135
  wildcard?: boolean | undefined;
316
136
  position?: boolean | undefined;
317
137
  }>]>>;
138
+ mode: z.ZodOptional<z.ZodEnum<["compat", "standard"]>>;
318
139
  }, "strip", z.ZodTypeAny, {
319
140
  prefix: string;
320
141
  array_index_mode?: "all" | "none" | {
@@ -322,6 +143,7 @@ declare const steVecIndexOptsSchema: z.ZodObject<{
322
143
  wildcard?: boolean | undefined;
323
144
  position?: boolean | undefined;
324
145
  } | undefined;
146
+ mode?: "standard" | "compat" | undefined;
325
147
  }, {
326
148
  prefix: string;
327
149
  array_index_mode?: "all" | "none" | {
@@ -329,11 +151,13 @@ declare const steVecIndexOptsSchema: z.ZodObject<{
329
151
  wildcard?: boolean | undefined;
330
152
  position?: boolean | undefined;
331
153
  } | undefined;
154
+ mode?: "standard" | "compat" | undefined;
332
155
  }>;
333
156
  declare const columnSchema: z.ZodDefault<z.ZodObject<{
334
- cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json", "text"]>>;
157
+ cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "timestamp", "number", "string", "json", "text"]>>;
335
158
  indexes: z.ZodDefault<z.ZodObject<{
336
159
  ore: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
160
+ ope: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
337
161
  unique: z.ZodOptional<z.ZodObject<{
338
162
  token_filters: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
339
163
  kind: z.ZodLiteral<"downcase">;
@@ -379,28 +203,28 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
379
203
  m: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
380
204
  include_original: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
381
205
  }, "strip", z.ZodTypeAny, {
382
- token_filters?: {
383
- kind: "downcase";
384
- }[] | undefined;
385
206
  tokenizer?: {
386
207
  kind: "standard";
387
208
  } | {
388
209
  kind: "ngram";
389
210
  token_length: number;
390
211
  } | undefined;
212
+ token_filters?: {
213
+ kind: "downcase";
214
+ }[] | undefined;
391
215
  k?: number | undefined;
392
216
  m?: number | undefined;
393
217
  include_original?: boolean | undefined;
394
218
  }, {
395
- token_filters?: {
396
- kind: "downcase";
397
- }[] | undefined;
398
219
  tokenizer?: {
399
220
  kind: "standard";
400
221
  } | {
401
222
  kind: "ngram";
402
223
  token_length: number;
403
224
  } | undefined;
225
+ token_filters?: {
226
+ kind: "downcase";
227
+ }[] | undefined;
404
228
  k?: number | undefined;
405
229
  m?: number | undefined;
406
230
  include_original?: boolean | undefined;
@@ -420,6 +244,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
420
244
  wildcard?: boolean | undefined;
421
245
  position?: boolean | undefined;
422
246
  }>]>>;
247
+ mode: z.ZodOptional<z.ZodEnum<["compat", "standard"]>>;
423
248
  }, "strip", z.ZodTypeAny, {
424
249
  prefix: string;
425
250
  array_index_mode?: "all" | "none" | {
@@ -427,6 +252,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
427
252
  wildcard?: boolean | undefined;
428
253
  position?: boolean | undefined;
429
254
  } | undefined;
255
+ mode?: "standard" | "compat" | undefined;
430
256
  }, {
431
257
  prefix: string;
432
258
  array_index_mode?: "all" | "none" | {
@@ -434,24 +260,26 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
434
260
  wildcard?: boolean | undefined;
435
261
  position?: boolean | undefined;
436
262
  } | undefined;
263
+ mode?: "standard" | "compat" | undefined;
437
264
  }>>;
438
265
  }, "strip", z.ZodTypeAny, {
439
266
  ore?: {} | undefined;
267
+ ope?: {} | undefined;
440
268
  unique?: {
441
269
  token_filters?: {
442
270
  kind: "downcase";
443
271
  }[] | undefined;
444
272
  } | undefined;
445
273
  match?: {
446
- token_filters?: {
447
- kind: "downcase";
448
- }[] | undefined;
449
274
  tokenizer?: {
450
275
  kind: "standard";
451
276
  } | {
452
277
  kind: "ngram";
453
278
  token_length: number;
454
279
  } | undefined;
280
+ token_filters?: {
281
+ kind: "downcase";
282
+ }[] | undefined;
455
283
  k?: number | undefined;
456
284
  m?: number | undefined;
457
285
  include_original?: boolean | undefined;
@@ -463,24 +291,26 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
463
291
  wildcard?: boolean | undefined;
464
292
  position?: boolean | undefined;
465
293
  } | undefined;
294
+ mode?: "standard" | "compat" | undefined;
466
295
  } | undefined;
467
296
  }, {
468
297
  ore?: {} | undefined;
298
+ ope?: {} | undefined;
469
299
  unique?: {
470
300
  token_filters?: {
471
301
  kind: "downcase";
472
302
  }[] | undefined;
473
303
  } | undefined;
474
304
  match?: {
475
- token_filters?: {
476
- kind: "downcase";
477
- }[] | undefined;
478
305
  tokenizer?: {
479
306
  kind: "standard";
480
307
  } | {
481
308
  kind: "ngram";
482
309
  token_length: number;
483
310
  } | undefined;
311
+ token_filters?: {
312
+ kind: "downcase";
313
+ }[] | undefined;
484
314
  k?: number | undefined;
485
315
  m?: number | undefined;
486
316
  include_original?: boolean | undefined;
@@ -492,27 +322,29 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
492
322
  wildcard?: boolean | undefined;
493
323
  position?: boolean | undefined;
494
324
  } | undefined;
325
+ mode?: "standard" | "compat" | undefined;
495
326
  } | undefined;
496
327
  }>>;
497
328
  }, "strip", z.ZodTypeAny, {
498
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
329
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "text" | "timestamp" | "json";
499
330
  indexes: {
500
331
  ore?: {} | undefined;
332
+ ope?: {} | undefined;
501
333
  unique?: {
502
334
  token_filters?: {
503
335
  kind: "downcase";
504
336
  }[] | undefined;
505
337
  } | undefined;
506
338
  match?: {
507
- token_filters?: {
508
- kind: "downcase";
509
- }[] | undefined;
510
339
  tokenizer?: {
511
340
  kind: "standard";
512
341
  } | {
513
342
  kind: "ngram";
514
343
  token_length: number;
515
344
  } | undefined;
345
+ token_filters?: {
346
+ kind: "downcase";
347
+ }[] | undefined;
516
348
  k?: number | undefined;
517
349
  m?: number | undefined;
518
350
  include_original?: boolean | undefined;
@@ -524,27 +356,29 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
524
356
  wildcard?: boolean | undefined;
525
357
  position?: boolean | undefined;
526
358
  } | undefined;
359
+ mode?: "standard" | "compat" | undefined;
527
360
  } | undefined;
528
361
  };
529
362
  }, {
530
- cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text" | undefined;
363
+ cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "text" | "timestamp" | "json" | undefined;
531
364
  indexes?: {
532
365
  ore?: {} | undefined;
366
+ ope?: {} | undefined;
533
367
  unique?: {
534
368
  token_filters?: {
535
369
  kind: "downcase";
536
370
  }[] | undefined;
537
371
  } | undefined;
538
372
  match?: {
539
- token_filters?: {
540
- kind: "downcase";
541
- }[] | undefined;
542
373
  tokenizer?: {
543
374
  kind: "standard";
544
375
  } | {
545
376
  kind: "ngram";
546
377
  token_length: number;
547
378
  } | undefined;
379
+ token_filters?: {
380
+ kind: "downcase";
381
+ }[] | undefined;
548
382
  k?: number | undefined;
549
383
  m?: number | undefined;
550
384
  include_original?: boolean | undefined;
@@ -556,6 +390,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
556
390
  wildcard?: boolean | undefined;
557
391
  position?: boolean | undefined;
558
392
  } | undefined;
393
+ mode?: "standard" | "compat" | undefined;
559
394
  } | undefined;
560
395
  } | undefined;
561
396
  }>>;
@@ -563,9 +398,10 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
563
398
  declare const encryptConfigSchema: z.ZodObject<{
564
399
  v: z.ZodNumber;
565
400
  tables: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodDefault<z.ZodObject<{
566
- cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json", "text"]>>;
401
+ cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "timestamp", "number", "string", "json", "text"]>>;
567
402
  indexes: z.ZodDefault<z.ZodObject<{
568
403
  ore: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
404
+ ope: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
569
405
  unique: z.ZodOptional<z.ZodObject<{
570
406
  token_filters: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
571
407
  kind: z.ZodLiteral<"downcase">;
@@ -611,28 +447,28 @@ declare const encryptConfigSchema: z.ZodObject<{
611
447
  m: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
612
448
  include_original: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
613
449
  }, "strip", z.ZodTypeAny, {
614
- token_filters?: {
615
- kind: "downcase";
616
- }[] | undefined;
617
450
  tokenizer?: {
618
451
  kind: "standard";
619
452
  } | {
620
453
  kind: "ngram";
621
454
  token_length: number;
622
455
  } | undefined;
456
+ token_filters?: {
457
+ kind: "downcase";
458
+ }[] | undefined;
623
459
  k?: number | undefined;
624
460
  m?: number | undefined;
625
461
  include_original?: boolean | undefined;
626
462
  }, {
627
- token_filters?: {
628
- kind: "downcase";
629
- }[] | undefined;
630
463
  tokenizer?: {
631
464
  kind: "standard";
632
465
  } | {
633
466
  kind: "ngram";
634
467
  token_length: number;
635
468
  } | undefined;
469
+ token_filters?: {
470
+ kind: "downcase";
471
+ }[] | undefined;
636
472
  k?: number | undefined;
637
473
  m?: number | undefined;
638
474
  include_original?: boolean | undefined;
@@ -652,6 +488,7 @@ declare const encryptConfigSchema: z.ZodObject<{
652
488
  wildcard?: boolean | undefined;
653
489
  position?: boolean | undefined;
654
490
  }>]>>;
491
+ mode: z.ZodOptional<z.ZodEnum<["compat", "standard"]>>;
655
492
  }, "strip", z.ZodTypeAny, {
656
493
  prefix: string;
657
494
  array_index_mode?: "all" | "none" | {
@@ -659,6 +496,7 @@ declare const encryptConfigSchema: z.ZodObject<{
659
496
  wildcard?: boolean | undefined;
660
497
  position?: boolean | undefined;
661
498
  } | undefined;
499
+ mode?: "standard" | "compat" | undefined;
662
500
  }, {
663
501
  prefix: string;
664
502
  array_index_mode?: "all" | "none" | {
@@ -666,24 +504,26 @@ declare const encryptConfigSchema: z.ZodObject<{
666
504
  wildcard?: boolean | undefined;
667
505
  position?: boolean | undefined;
668
506
  } | undefined;
507
+ mode?: "standard" | "compat" | undefined;
669
508
  }>>;
670
509
  }, "strip", z.ZodTypeAny, {
671
510
  ore?: {} | undefined;
511
+ ope?: {} | undefined;
672
512
  unique?: {
673
513
  token_filters?: {
674
514
  kind: "downcase";
675
515
  }[] | undefined;
676
516
  } | undefined;
677
517
  match?: {
678
- token_filters?: {
679
- kind: "downcase";
680
- }[] | undefined;
681
518
  tokenizer?: {
682
519
  kind: "standard";
683
520
  } | {
684
521
  kind: "ngram";
685
522
  token_length: number;
686
523
  } | undefined;
524
+ token_filters?: {
525
+ kind: "downcase";
526
+ }[] | undefined;
687
527
  k?: number | undefined;
688
528
  m?: number | undefined;
689
529
  include_original?: boolean | undefined;
@@ -695,24 +535,26 @@ declare const encryptConfigSchema: z.ZodObject<{
695
535
  wildcard?: boolean | undefined;
696
536
  position?: boolean | undefined;
697
537
  } | undefined;
538
+ mode?: "standard" | "compat" | undefined;
698
539
  } | undefined;
699
540
  }, {
700
541
  ore?: {} | undefined;
542
+ ope?: {} | undefined;
701
543
  unique?: {
702
544
  token_filters?: {
703
545
  kind: "downcase";
704
546
  }[] | undefined;
705
547
  } | undefined;
706
548
  match?: {
707
- token_filters?: {
708
- kind: "downcase";
709
- }[] | undefined;
710
549
  tokenizer?: {
711
550
  kind: "standard";
712
551
  } | {
713
552
  kind: "ngram";
714
553
  token_length: number;
715
554
  } | undefined;
555
+ token_filters?: {
556
+ kind: "downcase";
557
+ }[] | undefined;
716
558
  k?: number | undefined;
717
559
  m?: number | undefined;
718
560
  include_original?: boolean | undefined;
@@ -724,27 +566,29 @@ declare const encryptConfigSchema: z.ZodObject<{
724
566
  wildcard?: boolean | undefined;
725
567
  position?: boolean | undefined;
726
568
  } | undefined;
569
+ mode?: "standard" | "compat" | undefined;
727
570
  } | undefined;
728
571
  }>>;
729
572
  }, "strip", z.ZodTypeAny, {
730
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
573
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "text" | "timestamp" | "json";
731
574
  indexes: {
732
575
  ore?: {} | undefined;
576
+ ope?: {} | undefined;
733
577
  unique?: {
734
578
  token_filters?: {
735
579
  kind: "downcase";
736
580
  }[] | undefined;
737
581
  } | undefined;
738
582
  match?: {
739
- token_filters?: {
740
- kind: "downcase";
741
- }[] | undefined;
742
583
  tokenizer?: {
743
584
  kind: "standard";
744
585
  } | {
745
586
  kind: "ngram";
746
587
  token_length: number;
747
588
  } | undefined;
589
+ token_filters?: {
590
+ kind: "downcase";
591
+ }[] | undefined;
748
592
  k?: number | undefined;
749
593
  m?: number | undefined;
750
594
  include_original?: boolean | undefined;
@@ -756,27 +600,29 @@ declare const encryptConfigSchema: z.ZodObject<{
756
600
  wildcard?: boolean | undefined;
757
601
  position?: boolean | undefined;
758
602
  } | undefined;
603
+ mode?: "standard" | "compat" | undefined;
759
604
  } | undefined;
760
605
  };
761
606
  }, {
762
- cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text" | undefined;
607
+ cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "text" | "timestamp" | "json" | undefined;
763
608
  indexes?: {
764
609
  ore?: {} | undefined;
610
+ ope?: {} | undefined;
765
611
  unique?: {
766
612
  token_filters?: {
767
613
  kind: "downcase";
768
614
  }[] | undefined;
769
615
  } | undefined;
770
616
  match?: {
771
- token_filters?: {
772
- kind: "downcase";
773
- }[] | undefined;
774
617
  tokenizer?: {
775
618
  kind: "standard";
776
619
  } | {
777
620
  kind: "ngram";
778
621
  token_length: number;
779
622
  } | undefined;
623
+ token_filters?: {
624
+ kind: "downcase";
625
+ }[] | undefined;
780
626
  k?: number | undefined;
781
627
  m?: number | undefined;
782
628
  include_original?: boolean | undefined;
@@ -788,30 +634,32 @@ declare const encryptConfigSchema: z.ZodObject<{
788
634
  wildcard?: boolean | undefined;
789
635
  position?: boolean | undefined;
790
636
  } | undefined;
637
+ mode?: "standard" | "compat" | undefined;
791
638
  } | undefined;
792
639
  } | undefined;
793
640
  }>>>>>>;
794
641
  }, "strip", z.ZodTypeAny, {
795
642
  v: number;
796
643
  tables: Record<string, Record<string, {
797
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
644
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "text" | "timestamp" | "json";
798
645
  indexes: {
799
646
  ore?: {} | undefined;
647
+ ope?: {} | undefined;
800
648
  unique?: {
801
649
  token_filters?: {
802
650
  kind: "downcase";
803
651
  }[] | undefined;
804
652
  } | undefined;
805
653
  match?: {
806
- token_filters?: {
807
- kind: "downcase";
808
- }[] | undefined;
809
654
  tokenizer?: {
810
655
  kind: "standard";
811
656
  } | {
812
657
  kind: "ngram";
813
658
  token_length: number;
814
659
  } | undefined;
660
+ token_filters?: {
661
+ kind: "downcase";
662
+ }[] | undefined;
815
663
  k?: number | undefined;
816
664
  m?: number | undefined;
817
665
  include_original?: boolean | undefined;
@@ -823,30 +671,32 @@ declare const encryptConfigSchema: z.ZodObject<{
823
671
  wildcard?: boolean | undefined;
824
672
  position?: boolean | undefined;
825
673
  } | undefined;
674
+ mode?: "standard" | "compat" | undefined;
826
675
  } | undefined;
827
676
  };
828
677
  }>>;
829
678
  }, {
830
679
  v: number;
831
680
  tables?: Record<string, Record<string, {
832
- cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text" | undefined;
681
+ cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "text" | "timestamp" | "json" | undefined;
833
682
  indexes?: {
834
683
  ore?: {} | undefined;
684
+ ope?: {} | undefined;
835
685
  unique?: {
836
686
  token_filters?: {
837
687
  kind: "downcase";
838
688
  }[] | undefined;
839
689
  } | undefined;
840
690
  match?: {
841
- token_filters?: {
842
- kind: "downcase";
843
- }[] | undefined;
844
691
  tokenizer?: {
845
692
  kind: "standard";
846
693
  } | {
847
694
  kind: "ngram";
848
695
  token_length: number;
849
696
  } | undefined;
697
+ token_filters?: {
698
+ kind: "downcase";
699
+ }[] | undefined;
850
700
  k?: number | undefined;
851
701
  m?: number | undefined;
852
702
  include_original?: boolean | undefined;
@@ -858,6 +708,7 @@ declare const encryptConfigSchema: z.ZodObject<{
858
708
  wildcard?: boolean | undefined;
859
709
  position?: boolean | undefined;
860
710
  } | undefined;
711
+ mode?: "standard" | "compat" | undefined;
861
712
  } | undefined;
862
713
  } | undefined;
863
714
  } | undefined> | undefined> | undefined;
@@ -875,6 +726,7 @@ type MatchIndexOpts = z.infer<typeof matchIndexOptsSchema>;
875
726
  type SteVecIndexOpts = z.infer<typeof steVecIndexOptsSchema>;
876
727
  type UniqueIndexOpts = z.infer<typeof uniqueIndexOptsSchema>;
877
728
  type OreIndexOpts = z.infer<typeof oreIndexOptsSchema>;
729
+ type OpeIndexOpts = z.infer<typeof opeIndexOptsSchema>;
878
730
  type ColumnSchema = z.infer<typeof columnSchema>;
879
731
  /**
880
732
  * Shape of table columns: either top-level {@link EncryptedColumn} or nested
@@ -906,7 +758,7 @@ declare class EncryptedField {
906
758
  * a different type so the encryption layer knows how to encode the plaintext
907
759
  * before encrypting.
908
760
  *
909
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'text'`, `'bigint'`, or `'json'`.
761
+ * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'timestamp'`, `'text'`, `'bigint'`, or `'json'`. Use `'timestamp'` (not `'date'`) to preserve time-of-day — `'date'` truncates to midnight.
910
762
  * @returns This `EncryptedField` instance for method chaining.
911
763
  *
912
764
  * @example
@@ -918,7 +770,7 @@ declare class EncryptedField {
918
770
  */
919
771
  dataType(castAs: CastAs): this;
920
772
  build(): {
921
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
773
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "text" | "timestamp" | "json";
922
774
  indexes: {};
923
775
  };
924
776
  getName(): string;
@@ -935,7 +787,7 @@ declare class EncryptedColumn {
935
787
  * a different type so the encryption layer knows how to encode the plaintext
936
788
  * before encrypting.
937
789
  *
938
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
790
+ * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'timestamp'`, `'text'`, `'bigint'`, or `'json'`. Use `'timestamp'` (not `'date'`) to preserve time-of-day — `'date'` truncates to midnight.
939
791
  * @returns This `EncryptedColumn` instance for method chaining.
940
792
  *
941
793
  * @example
@@ -1037,9 +889,10 @@ declare class EncryptedColumn {
1037
889
  */
1038
890
  searchableJson(): this;
1039
891
  build(): {
1040
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
892
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "text" | "timestamp" | "json";
1041
893
  indexes: {
1042
894
  ore?: OreIndexOpts;
895
+ ope?: OpeIndexOpts;
1043
896
  unique?: UniqueIndexOpts;
1044
897
  match?: Required<MatchIndexOpts>;
1045
898
  ste_vec?: SteVecIndexOpts;
@@ -1212,6 +1065,350 @@ declare function encryptedField(valueName: string): EncryptedField;
1212
1065
  * console.log(config)
1213
1066
  * ```
1214
1067
  */
1215
- declare function buildEncryptConfig(...protectTables: Array<EncryptedTable<EncryptedTableColumn>>): EncryptConfig;
1068
+ declare function buildEncryptConfig(...protectTables: Array<BuildableTable>): EncryptConfig;
1069
+
1070
+ /** Brand symbol for nominal typing */
1071
+ declare const __brand: unique symbol;
1072
+ /** Creates a branded type that is structurally incompatible with the base type */
1073
+ type Brand<T, B extends string> = T & {
1074
+ readonly [__brand]: B;
1075
+ };
1076
+ type Client = Awaited<ReturnType<typeof newClient>> | undefined;
1077
+ /** A branded type representing encrypted data. Cannot be accidentally used as plaintext. */
1078
+ type EncryptedValue = Brand<Encrypted$1, 'encrypted'>;
1079
+ /** Structural type representing encrypted data stored in the database. Always
1080
+ * carries a ciphertext. Covers BOTH wire formats: the EQL v2.3 payloads
1081
+ * (`k: "ct"` / `k: "sv"`) and the EQL v3 payloads (flat `{v: 3, i, c, …}`
1082
+ * scalars and `{v: 3, k: "sv", i, sv}` SteVec documents). Which format
1083
+ * `encrypt` produces is selected by the client's
1084
+ * {@link ClientConfig.eqlVersion}; `decrypt` accepts both regardless.
1085
+ * v3 scalars carry no `k` discriminator, so narrow with `'k' in payload`
1086
+ * before reading it. See also `EncryptedValue` for branded nominal typing,
1087
+ * and {@link EncryptedQuery} for the search-term shape returned by
1088
+ * `encryptQuery`. */
1089
+ type Encrypted = EncryptedPayload;
1090
+ /** Structural type representing an encrypted query term (search needle)
1091
+ * returned by `encryptQuery` / `encryptQueryBulk` for scalar
1092
+ * (`unique` / `match` / `ore`) lookups and `ste_vec_selector` JSON path
1093
+ * queries, plus — under `eqlVersion: 3` — the `eql_v3.jsonb_query`
1094
+ * containment needle. Carries no ciphertext — matched against stored
1095
+ * values, never decrypted. v2 JSON containment queries (`ste_vec_term`)
1096
+ * return a storage-shaped {@link Encrypted} payload instead. */
1097
+ type EncryptedQuery = EncryptedQuery$1 | EncryptedV3Query;
1098
+ /**
1099
+ * Plaintext values the SDK accepts for encryption.
1100
+ *
1101
+ * Widens the FFI's `JsPlaintext` (`string | number | boolean |
1102
+ * Record<string, unknown> | JsPlaintext[]`) with `Date` and `bigint`. `Date`
1103
+ * is a supported cast target that is omitted from the FFI's `JsPlaintext` INPUT
1104
+ * union, but it serializes at the boundary via `toJSON` (ISO string), so it is
1105
+ * accepted on the way in.
1106
+ *
1107
+ * `bigint` is the plaintext for the v3 int8/bigint domains (see `eql/v3`),
1108
+ * which always decrypt to a JS `bigint`. protect-ffi 0.28 marshals a native
1109
+ * `bigint` across the Neon boundary losslessly. i64 bounds
1110
+ * (`-2^63 … 2^63 - 1`) are enforced at the protect-ffi boundary, not here —
1111
+ * out-of-range values surface as encryption errors from the FFI.
1112
+ *
1113
+ * When the upstream FFI `JsPlaintext` includes `Date` and `bigint`, both extra
1114
+ * arms can collapse back into `JsPlaintext`.
1115
+ */
1116
+ type Plaintext = JsPlaintext | Date | bigint;
1117
+ type KeysetIdentifier = {
1118
+ name: string;
1119
+ } | {
1120
+ id: string;
1121
+ };
1122
+ type ClientConfig = {
1123
+ /**
1124
+ * The CipherStash workspace CRN (Cloud Resource Name).
1125
+ * Format: `crn:<region>.aws:<workspace-id>`.
1126
+ * Can also be set via the `CS_WORKSPACE_CRN` environment variable.
1127
+ */
1128
+ workspaceCrn?: string;
1129
+ /**
1130
+ * The API access key used for authenticating with the CipherStash API.
1131
+ * Can also be set via the `CS_CLIENT_ACCESS_KEY` environment variable.
1132
+ * Obtain this from the CipherStash dashboard after creating a workspace.
1133
+ */
1134
+ accessKey?: string;
1135
+ /**
1136
+ * The client identifier used to authenticate with CipherStash services.
1137
+ * Can also be set via the `CS_CLIENT_ID` environment variable.
1138
+ * Generated during workspace onboarding in the CipherStash dashboard.
1139
+ */
1140
+ clientId?: string;
1141
+ /**
1142
+ * The client key material used in combination with ZeroKMS for encryption operations.
1143
+ * Can also be set via the `CS_CLIENT_KEY` environment variable.
1144
+ * Generated during workspace onboarding in the CipherStash dashboard.
1145
+ */
1146
+ clientKey?: string;
1147
+ /**
1148
+ * An optional keyset identifier for multi-tenant encryption.
1149
+ * Each keyset provides cryptographic isolation, giving each tenant its own keyspace.
1150
+ * Specify by name (`{ name: "tenant-a" }`) or UUID (`{ id: "..." }`).
1151
+ * Keysets are created and managed in the
1152
+ * [dashboard](https://dashboard.cipherstash.com/workspaces/_/keysets); omit to
1153
+ * use the workspace's default keyset. A client is bound to one keyset for its
1154
+ * lifetime, so use one client per tenant.
1155
+ *
1156
+ * @see {@link Encryption} for the full keysets walkthrough.
1157
+ */
1158
+ keyset?: KeysetIdentifier;
1159
+ /**
1160
+ * An optional authentication strategy for ZeroKMS requests, from
1161
+ * `@cipherstash/auth` (re-exported by `@cipherstash/stack`). When provided,
1162
+ * its `getToken()` is invoked on every ZeroKMS request and takes precedence
1163
+ * over the default `auto` strategy (the `clientKey` is still required for
1164
+ * encryption). Use:
1165
+ *
1166
+ * - `OidcFederationStrategy` for per-user, identity-bound encryption —
1167
+ * federates an end user's OIDC JWT into a CTS service token, so requests
1168
+ * authenticate as that user. Pair with `.withLockContext({ identityClaim })`
1169
+ * to bind the data key to a claim. This replaces the older
1170
+ * `LockContext.identify()` ceremony.
1171
+ * - `AccessKeyStrategy` for service-to-service / CI, or any custom
1172
+ * `{ getToken() }` object for bespoke token acquisition / caching.
1173
+ *
1174
+ * Leave unset to use the default `auto` strategy, which reads credentials
1175
+ * from the `CS_*` environment variables and falls back to the local dev
1176
+ * profile created by `npx stash auth login`.
1177
+ *
1178
+ * @see {@link AuthStrategy}
1179
+ * @see {@link Encryption} for a full walkthrough of the authentication options.
1180
+ */
1181
+ authStrategy?: AuthStrategy;
1182
+ /**
1183
+ * @deprecated Renamed to {@link ClientConfig.authStrategy}. Still honoured for
1184
+ * backwards compatibility — passing it logs a deprecation warning at runtime —
1185
+ * but it will be removed in a future release. Set `authStrategy` instead.
1186
+ */
1187
+ strategy?: AuthStrategy;
1188
+ /**
1189
+ * The EQL wire version the client emits — one FFI client always emits
1190
+ * exactly one wire format.
1191
+ *
1192
+ * - `2` (the protect-ffi default): payloads target the
1193
+ * `eql_v2_encrypted` column type.
1194
+ * - `3`: payloads target the per-capability `eql_v3` domains
1195
+ * (`eql_v3.text_eq`, `eql_v3.integer_ord_ore`, `eql_v3.json`, …),
1196
+ * derived from each column's `cast_as` and indexes.
1197
+ *
1198
+ * When omitted, {@link Encryption} auto-detects from the schema set:
1199
+ * EQL v3 tables (from `@cipherstash/stack/v3`, marked by
1200
+ * `buildColumnKeyMap()`) select `3`; v2 tables leave the FFI default
1201
+ * (`2`) untouched. Mixing v2 and v3 tables in one client is an error —
1202
+ * split them across two clients instead.
1203
+ *
1204
+ * `decrypt` accepts BOTH formats regardless of this setting, so v2 and
1205
+ * v3 data can coexist during a migration.
1206
+ *
1207
+ * Under `3`, `encryptQuery` returns EQL v3 query operands (protect-ffi
1208
+ * 0.29+): term-only scalar operands for the `eql_v3.query_<name>` twins,
1209
+ * the `eql_v3.query_jsonb` containment needle, and bare selector-hash
1210
+ * strings for JSON path queries.
1211
+ */
1212
+ eqlVersion?: 2 | 3;
1213
+ };
1214
+ type AtLeastOneCsTable<T> = [T, ...T[]];
1215
+ /** Structural contract for a column builder the client can consume for STORAGE
1216
+ * (`encrypt`). Satisfied by v2 `EncryptedColumn` / `EncryptedField` AND v3
1217
+ * `EncryptedTextSearchColumn` — fields ARE encryptable, so this stays wide. */
1218
+ interface BuildableColumn {
1219
+ getName(): string;
1220
+ build(): ColumnSchema;
1221
+ }
1222
+ /** Structural contract for a column the client can consume for QUERIES
1223
+ * (`encryptQuery` / search terms). Narrower than `BuildableColumn`: it must
1224
+ * EXCLUDE non-queryable `EncryptedField` (a field has no indexes). A v2
1225
+ * `EncryptedColumn` qualifies via the nominal arm; a v3 queryable concrete
1226
+ * type qualifies via the `getEqlType()` structural arm; `EncryptedField` (no
1227
+ * `getEqlType`, not an `EncryptedColumn`) is rejected. */
1228
+ interface BuildableV3QueryableColumn extends BuildableColumn {
1229
+ getEqlType(): string;
1230
+ getQueryCapabilities(): {
1231
+ equality: boolean;
1232
+ orderAndRange: boolean;
1233
+ freeTextSearch: boolean;
1234
+ };
1235
+ isQueryable(): true;
1236
+ }
1237
+ type BuildableQueryColumn = EncryptedColumn | BuildableV3QueryableColumn;
1238
+ /** Structural contract for a table builder the client can consume. Satisfied by
1239
+ * v2 and v3 `EncryptedTable` alike. */
1240
+ interface BuildableTable {
1241
+ tableName: string;
1242
+ build(): {
1243
+ tableName: string;
1244
+ columns: Record<string, ColumnSchema>;
1245
+ };
1246
+ /**
1247
+ * Optional map from a model field's JS property name to its encrypt-config
1248
+ * column name (the DB name). Present when the two can differ — v3 tables key
1249
+ * their config by DB name (`column.getName()`) while models are written with
1250
+ * JS property keys, so the model path must match by property but address the
1251
+ * FFI/config by DB name.
1252
+ *
1253
+ * Absent on v2 tables, whose `build()` already keys columns by the JS property
1254
+ * name; the model path then matches and addresses by that same key.
1255
+ */
1256
+ buildColumnKeyMap?(): Record<string, string>;
1257
+ }
1258
+ type EncryptionClientConfig = {
1259
+ schemas: AtLeastOneCsTable<BuildableTable>;
1260
+ config?: ClientConfig;
1261
+ };
1262
+ /**
1263
+ * The literal column map of a buildable table, read from its type-level
1264
+ * `_columnType` brand. Both v2 and v3 `EncryptedTable` carry this brand, so this
1265
+ * recovers the literal column keys structurally.
1266
+ *
1267
+ * This deliberately uses the `_columnType` brand rather than `build().columns`:
1268
+ * `BuildableTable.build()` is typed to return `Record<string, ColumnSchema>`,
1269
+ * which erases the literal keys and would mark EVERY model field as encrypted.
1270
+ *
1271
+ * The fallbacks resolve to `Record<never, never>` (a no-key type), NOT `never`:
1272
+ * a value typed as the bare structural `BuildableTable` carries no `_columnType`
1273
+ * brand, and `keyof never` is `string | number | symbol` — which would wrongly
1274
+ * mark EVERY model field as encrypted. `keyof Record<never, never>` is `never`,
1275
+ * so `EncryptedFromBuildableTable` degrades gracefully to the model unchanged.
1276
+ */
1277
+ type BuildableTableColumns<T extends BuildableTable> = T extends {
1278
+ readonly _columnType: infer C;
1279
+ } ? C extends Record<string, unknown> ? C : Record<never, never> : Record<never, never>;
1280
+ /**
1281
+ * Maps a plaintext model type to its encrypted form using a buildable table.
1282
+ *
1283
+ * Fields whose keys match a column defined in `Table` (via its `_columnType`
1284
+ * brand) become `Encrypted` (`Encrypted | null` when the source field is
1285
+ * nullable); all other fields retain their original types from `T`. Works for
1286
+ * both v2 and v3 tables. See {@link EncryptedFromSchema} for the v2-specific
1287
+ * variant retained for backward compatibility.
1288
+ */
1289
+ type EncryptedFromBuildableTable<T, Table extends BuildableTable> = {
1290
+ [K in keyof T]: [K] extends [keyof BuildableTableColumns<Table>] ? null extends T[K] ? Encrypted | null : Encrypted : T[K];
1291
+ };
1292
+ /**
1293
+ * Options for single-value encrypt operations.
1294
+ * Use a column from your table schema (from {@link encryptedColumn}) or a nested
1295
+ * field (from {@link encryptedField}) as the target for encryption.
1296
+ */
1297
+ type EncryptOptions = {
1298
+ /** The column or nested field to encrypt into. From {@link EncryptedColumn} or {@link EncryptedField}. */
1299
+ column: BuildableColumn;
1300
+ table: BuildableTable;
1301
+ };
1302
+ /** Format for encrypted query/search term return values */
1303
+ type EncryptedReturnType = 'eql' | 'composite-literal' | 'escaped-composite-literal';
1304
+ type SearchTerm = {
1305
+ value: Plaintext;
1306
+ column: BuildableQueryColumn;
1307
+ table: BuildableTable;
1308
+ returnType?: EncryptedReturnType;
1309
+ };
1310
+ /** Encrypted search term result. `eql` return type yields either a storage
1311
+ * payload (`Encrypted`, for `ste_vec_term`) or a query-only term
1312
+ * (`EncryptedQuery`, for scalar lookups and `ste_vec_selector`); the
1313
+ * `composite-literal` return types yield a string. */
1314
+ type EncryptedSearchTerm = Encrypted | EncryptedQuery | string;
1315
+ /** Result of encryptQuery (single or batch). `eql` return type yields either a
1316
+ * storage payload (`Encrypted`) or a query-only term (`EncryptedQuery`); the
1317
+ * `composite-literal` return types yield a string. */
1318
+ type EncryptedQueryResult = Encrypted | EncryptedQuery | string | null;
1319
+ type EncryptedFields<T> = {
1320
+ [K in keyof T as NonNullable<T[K]> extends Encrypted ? K : never]: T[K];
1321
+ };
1322
+ type OtherFields<T> = {
1323
+ [K in keyof T as NonNullable<T[K]> extends Encrypted ? never : K]: T[K];
1324
+ };
1325
+ type DecryptedFields<T> = {
1326
+ [K in keyof T as NonNullable<T[K]> extends Encrypted ? K : never]: null extends T[K] ? string | null : string;
1327
+ };
1328
+ /** Model with encrypted fields replaced by plaintext (decrypted) values */
1329
+ type Decrypted<T> = OtherFields<T> & DecryptedFields<T>;
1330
+ /**
1331
+ * Maps a plaintext model type to its encrypted form using the table schema.
1332
+ *
1333
+ * Fields whose keys match columns defined in `S` become `Encrypted`;
1334
+ * all other fields retain their original types from `T`.
1335
+ *
1336
+ * When `S` is the widened `EncryptedTableColumn` (e.g. when a user passes an
1337
+ * explicit `<User>` type argument without specifying `S`), the type degrades
1338
+ * gracefully to `T` — preserving backward compatibility.
1339
+ *
1340
+ * @typeParam T - The plaintext model type (e.g. `{ id: string; email: string }`)
1341
+ * @typeParam S - The table schema column definition, inferred from the `table` argument
1342
+ *
1343
+ * @example
1344
+ * ```typescript
1345
+ * type User = { id: string; email: string }
1346
+ * // With a schema that defines `email`:
1347
+ * type Encrypted = EncryptedFromSchema<User, { email: EncryptedColumn }>
1348
+ * // => { id: string; email: Encrypted }
1349
+ * ```
1350
+ */
1351
+ type EncryptedFromSchema<T, S extends EncryptedTableColumn> = {
1352
+ [K in keyof T]: [K] extends [keyof S] ? [S[K & keyof S]] extends [EncryptedColumn | EncryptedField] ? null extends T[K] ? Encrypted | null : Encrypted : T[K] : T[K];
1353
+ };
1354
+ type BulkEncryptPayload = Array<{
1355
+ id?: string;
1356
+ plaintext: Plaintext | null;
1357
+ }>;
1358
+ type BulkEncryptedData = Array<{
1359
+ id?: string;
1360
+ data: Encrypted | null;
1361
+ }>;
1362
+ type BulkDecryptPayload = Array<{
1363
+ id?: string;
1364
+ data: Encrypted | null;
1365
+ }>;
1366
+ type BulkDecryptedData = Array<DecryptionResult<JsPlaintext | null>>;
1367
+ type DecryptionSuccess<T> = {
1368
+ error?: never;
1369
+ data: T;
1370
+ id?: string;
1371
+ };
1372
+ type DecryptionError<T> = {
1373
+ error: T;
1374
+ id?: string;
1375
+ data?: never;
1376
+ };
1377
+ /**
1378
+ * Result type for individual items in bulk decrypt operations.
1379
+ * Uses `error`/`data` fields (not `failure`/`data`) since bulk operations
1380
+ * can have per-item failures.
1381
+ */
1382
+ type DecryptionResult<T> = DecryptionSuccess<T> | DecryptionError<T>;
1383
+ /**
1384
+ * User-facing query type names for encrypting query values.
1385
+ *
1386
+ * - `'equality'`: Exact match. [Exact Queries](https://cipherstash.com/docs/stack/cipherstash/encryption/searchable-encryption)
1387
+ * - `'freeTextSearch'`: Text search. [Match Queries](https://cipherstash.com/docs/stack/cipherstash/encryption/searchable-encryption)
1388
+ * - `'orderAndRange'`: Comparison and range. [Range Queries](https://cipherstash.com/docs/stack/cipherstash/encryption/searchable-encryption)
1389
+ * - `'steVecSelector'`: JSONPath selector (e.g. `'$.user.email'`)
1390
+ * - `'steVecTerm'`: Containment (e.g. `{ role: 'admin' }`)
1391
+ * - `'searchableJson'`: Auto-infers selector or term from plaintext type (recommended)
1392
+ */
1393
+ type QueryTypeName = 'orderAndRange' | 'freeTextSearch' | 'equality' | 'steVecSelector' | 'steVecTerm' | 'searchableJson';
1394
+ declare const queryTypes: {
1395
+ readonly orderAndRange: "orderAndRange";
1396
+ readonly freeTextSearch: "freeTextSearch";
1397
+ readonly equality: "equality";
1398
+ readonly steVecSelector: "steVecSelector";
1399
+ readonly steVecTerm: "steVecTerm";
1400
+ readonly searchableJson: "searchableJson";
1401
+ };
1402
+ /** @internal */
1403
+ type QueryTermBase = {
1404
+ column: BuildableQueryColumn;
1405
+ table: BuildableTable;
1406
+ queryType?: QueryTypeName;
1407
+ returnType?: EncryptedReturnType;
1408
+ };
1409
+ type EncryptQueryOptions = QueryTermBase;
1410
+ type ScalarQueryTerm = QueryTermBase & {
1411
+ value: Plaintext;
1412
+ };
1216
1413
 
1217
- export { eqlCastAsEnum as A, type BulkDecryptedData as B, type CastAs as C, type Decrypted as D, type Encrypted as E, toEqlCastAs as F, type ClientConfig as G, type DecryptedFields as H, type InferEncrypted as I, type DecryptionResult as J, type KeysetIdentifier as K, type EncryptedFields as L, type MatchIndexOpts as M, type EncryptedQuery as N, type OreIndexOpts as O, type EncryptedSearchTerm as P, type QueryTypeName as Q, type OtherFields as R, type ScalarQueryTerm as S, type TokenFilter as T, type UniqueIndexOpts as U, type SearchTerm as V, queryTypes as W, encryptedField as a, encryptedTable as b, EncryptedTable as c, type EncryptedTableColumn as d, encryptedColumn as e, EncryptedColumn as f, type EncryptedValue as g, type EncryptedQueryResult as h, type Client as i, type BulkDecryptPayload as j, type BulkEncryptedData as k, type BulkEncryptPayload as l, type EncryptOptions as m, EncryptedField as n, type EncryptQueryOptions as o, type EncryptedReturnType as p, type EncryptConfig as q, type EncryptedFromSchema as r, type EncryptionClientConfig as s, type InferPlaintext as t, type ColumnSchema as u, type EqlCastAs as v, type SteVecIndexOpts as w, buildEncryptConfig as x, castAsEnum as y, encryptConfigSchema as z };
1414
+ export { encryptedTable as $, type EncryptedTableColumn as A, type BuildableColumn as B, type CastAs as C, type Decrypted as D, type EncryptConfig as E, type EncryptedValue as F, type EncryptionClientConfig as G, type EqlCastAs as H, type InferEncrypted as I, type InferPlaintext as J, type KeysetIdentifier as K, type OreIndexOpts as L, type MatchIndexOpts as M, type OtherFields as N, type OpeIndexOpts as O, type Plaintext as P, type QueryTypeName as Q, type SearchTerm as R, type ScalarQueryTerm as S, type SteVecIndexOpts as T, type TokenFilter as U, type UniqueIndexOpts as V, buildEncryptConfig as W, castAsEnum as X, encryptConfigSchema as Y, encryptedColumn as Z, encryptedField as _, type BuildableQueryColumn as a, eqlCastAsEnum as a0, queryTypes as a1, toEqlCastAs as a2, type BuildableTable as b, type BuildableTableColumns as c, type BuildableV3QueryableColumn as d, type BulkDecryptPayload as e, type BulkDecryptedData as f, type BulkEncryptPayload as g, type BulkEncryptedData as h, type Client as i, type ClientConfig as j, type ColumnSchema as k, type DecryptedFields as l, type DecryptionResult as m, type EncryptOptions as n, type EncryptQueryOptions as o, type Encrypted as p, EncryptedColumn as q, EncryptedField as r, type EncryptedFields as s, type EncryptedFromBuildableTable as t, type EncryptedFromSchema as u, type EncryptedQuery as v, type EncryptedQueryResult as w, type EncryptedReturnType as x, type EncryptedSearchTerm as y, EncryptedTable as z };