@cipherstash/stack 0.16.0 → 0.19.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 (102) hide show
  1. package/CHANGELOG.md +225 -0
  2. package/README.md +2 -2
  3. package/dist/{chunk-CY5B4LIF.js → chunk-36AA7IBJ.js} +303 -204
  4. package/dist/chunk-36AA7IBJ.js.map +1 -0
  5. package/dist/{chunk-MD6742R6.js → chunk-4AVL4VZD.js} +1 -1
  6. package/dist/chunk-4AVL4VZD.js.map +1 -0
  7. package/dist/{chunk-4RNBI3UH.js → chunk-BNO32ZMV.js} +1 -1
  8. package/dist/chunk-BNO32ZMV.js.map +1 -0
  9. package/dist/{chunk-6FD7OBGM.js → chunk-HQANMV7R.js} +3 -3
  10. package/dist/chunk-HQANMV7R.js.map +1 -0
  11. package/dist/chunk-IADZCZEA.js +23 -0
  12. package/dist/chunk-IADZCZEA.js.map +1 -0
  13. package/dist/chunk-IBSK6P33.js +209 -0
  14. package/dist/chunk-IBSK6P33.js.map +1 -0
  15. package/dist/chunk-JSG2AMDI.js +17 -0
  16. package/dist/chunk-JSG2AMDI.js.map +1 -0
  17. package/dist/chunk-MP3SSDNN.js +4439 -0
  18. package/dist/chunk-MP3SSDNN.js.map +1 -0
  19. package/dist/chunk-OFQ555AX.js +191 -0
  20. package/dist/chunk-OFQ555AX.js.map +1 -0
  21. package/dist/chunk-PZ5AY32C.js +10 -0
  22. package/dist/chunk-PZ5AY32C.js.map +1 -0
  23. package/dist/chunk-U66S7VIF.js +435 -0
  24. package/dist/chunk-U66S7VIF.js.map +1 -0
  25. package/dist/{client-C_7TF8EL.d.cts → client-DSGHBN-g.d.cts} +209 -72
  26. package/dist/{client-BLbA6aFD.d.ts → client-DfCrlHXh.d.ts} +209 -72
  27. package/dist/client.cjs +4103 -43
  28. package/dist/client.cjs.map +1 -1
  29. package/dist/client.d.cts +5 -5
  30. package/dist/client.d.ts +5 -5
  31. package/dist/client.js +3 -1
  32. package/dist/drizzle/index.cjs +4139 -77
  33. package/dist/drizzle/index.cjs.map +1 -1
  34. package/dist/drizzle/index.d.cts +33 -33
  35. package/dist/drizzle/index.d.ts +33 -33
  36. package/dist/drizzle/index.js +39 -33
  37. package/dist/drizzle/index.js.map +1 -1
  38. package/dist/dynamodb/index.cjs +31 -14
  39. package/dist/dynamodb/index.cjs.map +1 -1
  40. package/dist/dynamodb/index.d.cts +12 -12
  41. package/dist/dynamodb/index.d.ts +12 -12
  42. package/dist/dynamodb/index.js +16 -12
  43. package/dist/dynamodb/index.js.map +1 -1
  44. package/dist/encryption/index.cjs +4611 -257
  45. package/dist/encryption/index.cjs.map +1 -1
  46. package/dist/encryption/index.d.cts +3 -3
  47. package/dist/encryption/index.d.ts +3 -3
  48. package/dist/encryption/index.js +35 -7
  49. package/dist/encryption/v3.cjs +7791 -0
  50. package/dist/encryption/v3.cjs.map +1 -0
  51. package/dist/encryption/v3.d.cts +100 -0
  52. package/dist/encryption/v3.d.ts +100 -0
  53. package/dist/encryption/v3.js +161 -0
  54. package/dist/encryption/v3.js.map +1 -0
  55. package/dist/eql/v3/index.cjs +612 -0
  56. package/dist/eql/v3/index.cjs.map +1 -0
  57. package/dist/eql/v3/index.d.cts +71 -0
  58. package/dist/eql/v3/index.d.ts +71 -0
  59. package/dist/eql/v3/index.js +89 -0
  60. package/dist/eql/v3/index.js.map +1 -0
  61. package/dist/errors/index.js +1 -0
  62. package/dist/identity/index.cjs +55 -35
  63. package/dist/identity/index.cjs.map +1 -1
  64. package/dist/identity/index.d.cts +54 -30
  65. package/dist/identity/index.d.ts +54 -30
  66. package/dist/identity/index.js +9 -177
  67. package/dist/identity/index.js.map +1 -1
  68. package/dist/index.cjs +4625 -273
  69. package/dist/index.cjs.map +1 -1
  70. package/dist/index.d.cts +18 -7
  71. package/dist/index.d.ts +18 -7
  72. package/dist/index.js +20 -5
  73. package/dist/index.js.map +1 -1
  74. package/dist/schema/index.cjs +4108 -44
  75. package/dist/schema/index.cjs.map +1 -1
  76. package/dist/schema/index.d.cts +1 -1
  77. package/dist/schema/index.d.ts +1 -1
  78. package/dist/schema/index.js +3 -1
  79. package/dist/supabase/index.cjs +4500 -75
  80. package/dist/supabase/index.cjs.map +1 -1
  81. package/dist/supabase/index.d.cts +113 -34
  82. package/dist/supabase/index.d.ts +113 -34
  83. package/dist/supabase/index.js +350 -32
  84. package/dist/supabase/index.js.map +1 -1
  85. package/dist/table-CIH7jZ2h.d.ts +603 -0
  86. package/dist/table-DihEAlxG.d.cts +603 -0
  87. package/dist/{types-public-Dv-r6Ik0.d.ts → types-public-CpS5KjwX.d.cts} +209 -36
  88. package/dist/{types-public-Dv-r6Ik0.d.cts → types-public-CpS5KjwX.d.ts} +209 -36
  89. package/dist/types-public.cjs.map +1 -1
  90. package/dist/types-public.d.cts +2 -2
  91. package/dist/types-public.d.ts +2 -2
  92. package/dist/types-public.js +2 -1
  93. package/dist/wasm-inline.d.ts +1269 -0
  94. package/dist/wasm-inline.js +4594 -0
  95. package/dist/wasm-inline.js.map +1 -0
  96. package/package.json +63 -13
  97. package/dist/chunk-4RNBI3UH.js.map +0 -1
  98. package/dist/chunk-6FD7OBGM.js.map +0 -1
  99. package/dist/chunk-CY5B4LIF.js.map +0 -1
  100. package/dist/chunk-JDZ2QUUF.js +0 -381
  101. package/dist/chunk-JDZ2QUUF.js.map +0 -1
  102. package/dist/chunk-MD6742R6.js.map +0 -1
@@ -1,8 +1,8 @@
1
- import { h as EncryptedQueryResult, i as Client, S as ScalarQueryTerm, B as BulkDecryptedData, j as BulkDecryptPayload, D as Decrypted, k as BulkEncryptedData, l as BulkEncryptPayload, m as EncryptOptions, f as EncryptedColumn, n as EncryptedField, c as EncryptedTable, d as EncryptedTableColumn, E as Encrypted, o as EncryptQueryOptions, Q as QueryTypeName, p as EncryptedReturnType, q as EncryptConfig, K as KeysetIdentifier, r as EncryptedFromSchema, s as EncryptionClientConfig } from './types-public-Dv-r6Ik0.js';
2
- import { EncryptionError } from './errors/index.js';
3
1
  import { Result } from '@byteslice/result';
4
- import { JsPlaintext } from '@cipherstash/protect-ffi';
5
- import { LockContext } from './identity/index.js';
2
+ import { EncryptionError } from './errors/index.js';
3
+ import { n as EncryptedQueryResult, o as Client, S as ScalarQueryTerm, p as BulkDecryptedData, c as BulkDecryptPayload, D as Decrypted, q as BulkEncryptedData, B as BulkEncryptPayload, b as EncryptOptions, r as BuildableColumn, s as BuildableTable, a as Encrypted, P as Plaintext, t as EncryptQueryOptions, u as BuildableQueryColumn, Q as QueryTypeName, E as EncryptedReturnType, j as EncryptConfig, K as KeysetIdentifier, v as EncryptedFromBuildableTable, w as EncryptionClientConfig } from './types-public-CpS5KjwX.js';
4
+ import { LockContextInput } from './identity/index.js';
5
+ import { JsPlaintext, AuthStrategy } from '@cipherstash/protect-ffi';
6
6
 
7
7
  type AuditConfig = {
8
8
  metadata?: Record<string, unknown>;
@@ -32,24 +32,18 @@ declare abstract class EncryptionOperation<T> {
32
32
  then<TResult1 = Result<T, EncryptionError>, TResult2 = never>(onfulfilled?: ((value: Result<T, EncryptionError>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
33
33
  }
34
34
 
35
- /**
36
- * @internal Use {@link EncryptionClient.encryptQuery} with array input instead.
37
- */
38
35
  declare class BatchEncryptQueryOperation extends EncryptionOperation<EncryptedQueryResult[]> {
39
36
  private client;
40
37
  private terms;
41
38
  constructor(client: Client, terms: readonly ScalarQueryTerm[]);
42
- withLockContext(lockContext: LockContext): BatchEncryptQueryOperationWithLockContext;
39
+ withLockContext(lockContext: LockContextInput): BatchEncryptQueryOperationWithLockContext;
43
40
  execute(): Promise<Result<EncryptedQueryResult[], EncryptionError>>;
44
41
  }
45
- /**
46
- * @internal Use {@link EncryptionClient.encryptQuery} with array input and `.withLockContext()` instead.
47
- */
48
42
  declare class BatchEncryptQueryOperationWithLockContext extends EncryptionOperation<EncryptedQueryResult[]> {
49
43
  private client;
50
44
  private terms;
51
45
  private lockContext;
52
- constructor(client: Client, terms: readonly ScalarQueryTerm[], lockContext: LockContext, auditMetadata?: Record<string, unknown>);
46
+ constructor(client: Client, terms: readonly ScalarQueryTerm[], lockContext: LockContextInput, auditMetadata?: Record<string, unknown>);
53
47
  execute(): Promise<Result<EncryptedQueryResult[], EncryptionError>>;
54
48
  }
55
49
 
@@ -57,7 +51,7 @@ declare class BulkDecryptOperation extends EncryptionOperation<BulkDecryptedData
57
51
  private client;
58
52
  private encryptedPayloads;
59
53
  constructor(client: Client, encryptedPayloads: BulkDecryptPayload);
60
- withLockContext(lockContext: LockContext): BulkDecryptOperationWithLockContext;
54
+ withLockContext(lockContext: LockContextInput): BulkDecryptOperationWithLockContext;
61
55
  execute(): Promise<Result<BulkDecryptedData, EncryptionError>>;
62
56
  getOperation(): {
63
57
  client: Client;
@@ -67,7 +61,7 @@ declare class BulkDecryptOperation extends EncryptionOperation<BulkDecryptedData
67
61
  declare class BulkDecryptOperationWithLockContext extends EncryptionOperation<BulkDecryptedData> {
68
62
  private operation;
69
63
  private lockContext;
70
- constructor(operation: BulkDecryptOperation, lockContext: LockContext);
64
+ constructor(operation: BulkDecryptOperation, lockContext: LockContextInput);
71
65
  execute(): Promise<Result<BulkDecryptedData, EncryptionError>>;
72
66
  }
73
67
 
@@ -75,7 +69,7 @@ declare class BulkDecryptModelsOperation<T extends Record<string, unknown>> exte
75
69
  private client;
76
70
  private models;
77
71
  constructor(client: Client, models: T[]);
78
- withLockContext(lockContext: LockContext): BulkDecryptModelsOperationWithLockContext<T>;
72
+ withLockContext(lockContext: LockContextInput): BulkDecryptModelsOperationWithLockContext<T>;
79
73
  execute(): Promise<Result<Decrypted<T>[], EncryptionError>>;
80
74
  getOperation(): {
81
75
  client: Client;
@@ -85,7 +79,7 @@ declare class BulkDecryptModelsOperation<T extends Record<string, unknown>> exte
85
79
  declare class BulkDecryptModelsOperationWithLockContext<T extends Record<string, unknown>> extends EncryptionOperation<Decrypted<T>[]> {
86
80
  private operation;
87
81
  private lockContext;
88
- constructor(operation: BulkDecryptModelsOperation<T>, lockContext: LockContext);
82
+ constructor(operation: BulkDecryptModelsOperation<T>, lockContext: LockContextInput);
89
83
  execute(): Promise<Result<Decrypted<T>[], EncryptionError>>;
90
84
  }
91
85
 
@@ -95,19 +89,19 @@ declare class BulkEncryptOperation extends EncryptionOperation<BulkEncryptedData
95
89
  private column;
96
90
  private table;
97
91
  constructor(client: Client, plaintexts: BulkEncryptPayload, opts: EncryptOptions);
98
- withLockContext(lockContext: LockContext): BulkEncryptOperationWithLockContext;
92
+ withLockContext(lockContext: LockContextInput): BulkEncryptOperationWithLockContext;
99
93
  execute(): Promise<Result<BulkEncryptedData, EncryptionError>>;
100
94
  getOperation(): {
101
95
  client: Client;
102
96
  plaintexts: BulkEncryptPayload;
103
- column: EncryptedColumn | EncryptedField;
104
- table: EncryptedTable<EncryptedTableColumn>;
97
+ column: BuildableColumn;
98
+ table: BuildableTable;
105
99
  };
106
100
  }
107
101
  declare class BulkEncryptOperationWithLockContext extends EncryptionOperation<BulkEncryptedData> {
108
102
  private operation;
109
103
  private lockContext;
110
- constructor(operation: BulkEncryptOperation, lockContext: LockContext);
104
+ constructor(operation: BulkEncryptOperation, lockContext: LockContextInput);
111
105
  execute(): Promise<Result<BulkEncryptedData, EncryptionError>>;
112
106
  }
113
107
 
@@ -115,19 +109,19 @@ declare class BulkEncryptModelsOperation<T extends Record<string, unknown>> exte
115
109
  private client;
116
110
  private models;
117
111
  private table;
118
- constructor(client: Client, models: Record<string, unknown>[], table: EncryptedTable<EncryptedTableColumn>);
119
- withLockContext(lockContext: LockContext): BulkEncryptModelsOperationWithLockContext<T>;
112
+ constructor(client: Client, models: Record<string, unknown>[], table: BuildableTable);
113
+ withLockContext(lockContext: LockContextInput): BulkEncryptModelsOperationWithLockContext<T>;
120
114
  execute(): Promise<Result<T[], EncryptionError>>;
121
115
  getOperation(): {
122
116
  client: Client;
123
117
  models: Record<string, unknown>[];
124
- table: EncryptedTable<EncryptedTableColumn>;
118
+ table: BuildableTable;
125
119
  };
126
120
  }
127
121
  declare class BulkEncryptModelsOperationWithLockContext<T extends Record<string, unknown>> extends EncryptionOperation<T[]> {
128
122
  private operation;
129
123
  private lockContext;
130
- constructor(operation: BulkEncryptModelsOperation<T>, lockContext: LockContext);
124
+ constructor(operation: BulkEncryptModelsOperation<T>, lockContext: LockContextInput);
131
125
  execute(): Promise<Result<T[], EncryptionError>>;
132
126
  }
133
127
 
@@ -138,19 +132,19 @@ declare class BulkEncryptModelsOperationWithLockContext<T extends Record<string,
138
132
  declare class DecryptOperation extends EncryptionOperation<JsPlaintext> {
139
133
  private client;
140
134
  private encryptedData;
141
- constructor(client: Client, encryptedData: Encrypted);
142
- withLockContext(lockContext: LockContext): DecryptOperationWithLockContext;
135
+ constructor(client: Client, encryptedData: Encrypted | null);
136
+ withLockContext(lockContext: LockContextInput): DecryptOperationWithLockContext;
143
137
  execute(): Promise<Result<JsPlaintext, EncryptionError>>;
144
138
  getOperation(): {
145
139
  client: Client;
146
- encryptedData: Encrypted;
140
+ encryptedData: Encrypted | null;
147
141
  auditData?: Record<string, unknown>;
148
142
  };
149
143
  }
150
144
  declare class DecryptOperationWithLockContext extends EncryptionOperation<JsPlaintext> {
151
145
  private operation;
152
146
  private lockContext;
153
- constructor(operation: DecryptOperation, lockContext: LockContext);
147
+ constructor(operation: DecryptOperation, lockContext: LockContextInput);
154
148
  execute(): Promise<Result<JsPlaintext, EncryptionError>>;
155
149
  }
156
150
 
@@ -158,7 +152,7 @@ declare class DecryptModelOperation<T extends Record<string, unknown>> extends E
158
152
  private client;
159
153
  private model;
160
154
  constructor(client: Client, model: T);
161
- withLockContext(lockContext: LockContext): DecryptModelOperationWithLockContext<T>;
155
+ withLockContext(lockContext: LockContextInput): DecryptModelOperationWithLockContext<T>;
162
156
  execute(): Promise<Result<Decrypted<T>, EncryptionError>>;
163
157
  getOperation(): {
164
158
  client: Client;
@@ -168,7 +162,7 @@ declare class DecryptModelOperation<T extends Record<string, unknown>> extends E
168
162
  declare class DecryptModelOperationWithLockContext<T extends Record<string, unknown>> extends EncryptionOperation<Decrypted<T>> {
169
163
  private operation;
170
164
  private lockContext;
171
- constructor(operation: DecryptModelOperation<T>, lockContext: LockContext);
165
+ constructor(operation: DecryptModelOperation<T>, lockContext: LockContextInput);
172
166
  execute(): Promise<Result<Decrypted<T>, EncryptionError>>;
173
167
  }
174
168
 
@@ -177,20 +171,20 @@ declare class EncryptOperation extends EncryptionOperation<Encrypted> {
177
171
  private plaintext;
178
172
  private column;
179
173
  private table;
180
- constructor(client: Client, plaintext: JsPlaintext, opts: EncryptOptions);
181
- withLockContext(lockContext: LockContext): EncryptOperationWithLockContext;
174
+ constructor(client: Client, plaintext: Plaintext | null, opts: EncryptOptions);
175
+ withLockContext(lockContext: LockContextInput): EncryptOperationWithLockContext;
182
176
  execute(): Promise<Result<Encrypted, EncryptionError>>;
183
177
  getOperation(): {
184
178
  client: Client;
185
- plaintext: JsPlaintext;
186
- column: EncryptedColumn | EncryptedField;
187
- table: EncryptedTable<EncryptedTableColumn>;
179
+ plaintext: Plaintext | null;
180
+ column: BuildableColumn;
181
+ table: BuildableTable;
188
182
  };
189
183
  }
190
184
  declare class EncryptOperationWithLockContext extends EncryptionOperation<Encrypted> {
191
185
  private operation;
192
186
  private lockContext;
193
- constructor(operation: EncryptOperation, lockContext: LockContext);
187
+ constructor(operation: EncryptOperation, lockContext: LockContextInput);
194
188
  execute(): Promise<Result<Encrypted, EncryptionError>>;
195
189
  }
196
190
 
@@ -198,54 +192,69 @@ declare class EncryptModelOperation<T extends Record<string, unknown>> extends E
198
192
  private client;
199
193
  private model;
200
194
  private table;
201
- constructor(client: Client, model: Record<string, unknown>, table: EncryptedTable<EncryptedTableColumn>);
202
- withLockContext(lockContext: LockContext): EncryptModelOperationWithLockContext<T>;
195
+ constructor(client: Client, model: Record<string, unknown>, table: BuildableTable);
196
+ withLockContext(lockContext: LockContextInput): EncryptModelOperationWithLockContext<T>;
203
197
  execute(): Promise<Result<T, EncryptionError>>;
204
198
  getOperation(): {
205
199
  client: Client;
206
200
  model: Record<string, unknown>;
207
- table: EncryptedTable<EncryptedTableColumn>;
201
+ table: BuildableTable;
208
202
  };
209
203
  }
210
204
  declare class EncryptModelOperationWithLockContext<T extends Record<string, unknown>> extends EncryptionOperation<T> {
211
205
  private operation;
212
206
  private lockContext;
213
- constructor(operation: EncryptModelOperation<T>, lockContext: LockContext);
207
+ constructor(operation: EncryptModelOperation<T>, lockContext: LockContextInput);
214
208
  execute(): Promise<Result<T, EncryptionError>>;
215
209
  }
216
210
 
217
- /**
218
- * @internal Use {@link EncryptionClient.encryptQuery} instead.
219
- */
220
211
  declare class EncryptQueryOperation extends EncryptionOperation<EncryptedQueryResult> {
221
212
  private client;
222
213
  private plaintext;
223
214
  private opts;
224
- constructor(client: Client, plaintext: JsPlaintext, opts: EncryptQueryOptions);
225
- withLockContext(lockContext: LockContext): EncryptQueryOperationWithLockContext;
215
+ constructor(client: Client, plaintext: Plaintext | null | undefined, opts: EncryptQueryOptions);
216
+ withLockContext(lockContext: LockContextInput): EncryptQueryOperationWithLockContext;
226
217
  execute(): Promise<Result<EncryptedQueryResult, EncryptionError>>;
227
218
  getOperation(): {
228
- column: EncryptedColumn;
229
- table: EncryptedTable<EncryptedTableColumn>;
219
+ column: BuildableQueryColumn;
220
+ table: BuildableTable;
230
221
  queryType?: QueryTypeName;
231
222
  returnType?: EncryptedReturnType;
232
223
  client: Client;
233
- plaintext: JsPlaintext;
224
+ plaintext: Plaintext | null | undefined;
234
225
  };
235
226
  }
236
- /**
237
- * @internal Use {@link EncryptionClient.encryptQuery} with `.withLockContext()` instead.
238
- */
239
227
  declare class EncryptQueryOperationWithLockContext extends EncryptionOperation<EncryptedQueryResult> {
240
228
  private client;
241
229
  private plaintext;
242
230
  private opts;
243
231
  private lockContext;
244
- constructor(client: Client, plaintext: JsPlaintext, opts: EncryptQueryOptions, lockContext: LockContext, auditMetadata?: Record<string, unknown>);
232
+ constructor(client: Client, plaintext: Plaintext | null | undefined, opts: EncryptQueryOptions, lockContext: LockContextInput, auditMetadata?: Record<string, unknown>);
245
233
  execute(): Promise<Result<EncryptedQueryResult, EncryptionError>>;
246
234
  }
247
235
 
248
236
  declare const noClientError: () => Error;
237
+ /**
238
+ * Resolve the EQL wire version for a client from its schema set.
239
+ *
240
+ * One FFI client emits exactly one wire format, so the whole schema set must
241
+ * agree. EQL v3 tables (from `@cipherstash/stack/v3`) are detected by their
242
+ * `buildColumnKeyMap()` marker — v2 tables don't have one:
243
+ *
244
+ * - every schema is v3 → `3`;
245
+ * - no schema is v3 → `undefined`, leaving the FFI's v2 default (and its
246
+ * byte-identical v2 output) untouched;
247
+ * - a mix of the two → throws: the v2 tables target `eql_v2_encrypted`
248
+ * columns and the v3 tables target `eql_v3` domains, so no single wire
249
+ * format serves both. Split them across two clients.
250
+ *
251
+ * An explicit `config.eqlVersion` bypasses detection (the wire format is
252
+ * then unambiguous — e.g. writing v2-wire from a v3 schema set during a
253
+ * migration), but a mixed schema set still throws.
254
+ *
255
+ * @internal exported for unit-test coverage of the detection matrix.
256
+ */
257
+ declare function resolveEqlVersion(schemas: readonly BuildableTable[], explicit?: 2 | 3): 2 | 3 | undefined;
249
258
  /** The EncryptionClient is the main entry point for interacting with the CipherStash Encryption library.
250
259
  * It provides methods for encrypting and decrypting individual values, as well as models (objects) and bulk operations.
251
260
  *
@@ -267,6 +276,8 @@ declare class EncryptionClient {
267
276
  clientId?: string;
268
277
  clientKey?: string;
269
278
  keyset?: KeysetIdentifier;
279
+ authStrategy?: AuthStrategy;
280
+ eqlVersion?: 2 | 3;
270
281
  }): Promise<Result<EncryptionClient, EncryptionError>>;
271
282
  /**
272
283
  * Encrypt a value - returns a promise which resolves to an encrypted value.
@@ -343,7 +354,7 @@ declare class EncryptionClient {
343
354
  * @see {@link LockContext}
344
355
  * @see {@link EncryptOperation}
345
356
  */
346
- encrypt(plaintext: JsPlaintext, opts: EncryptOptions): EncryptOperation;
357
+ encrypt(plaintext: Plaintext, opts: EncryptOptions): EncryptOperation;
347
358
  /**
348
359
  * Encrypt a query value - returns a promise which resolves to an encrypted query value.
349
360
  *
@@ -397,7 +408,7 @@ declare class EncryptionClient {
397
408
  * - String plaintext → `steVecSelector` (JSONPath queries like `'$.user.email'`)
398
409
  * - Object/Array plaintext → `steVecTerm` (containment queries like `{ role: 'admin' }`)
399
410
  */
400
- encryptQuery(plaintext: JsPlaintext, opts: EncryptQueryOptions): EncryptQueryOperation;
411
+ encryptQuery(plaintext: Plaintext, opts: EncryptQueryOptions): EncryptQueryOperation;
401
412
  /**
402
413
  * Encrypt multiple values for use in queries (batch operation).
403
414
  * @param terms - Array of query terms to encrypt
@@ -432,6 +443,13 @@ declare class EncryptionClient {
432
443
  * .withLockContext(lockContext)
433
444
  * ```
434
445
  *
446
+ * @remarks
447
+ * The public input type rejects null, but at runtime `decrypt` will
448
+ * short-circuit and return null when given a null ciphertext
449
+ * (defense in depth for legacy / manually-NULLed DB rows reached via
450
+ * casts or dynamic field walking). The narrow return type holds for
451
+ * any caller that respects the input contract.
452
+ *
435
453
  * @see {@link LockContext}
436
454
  * @see {@link DecryptOperation}
437
455
  */
@@ -482,7 +500,7 @@ declare class EncryptionClient {
482
500
  * }
483
501
  * ```
484
502
  */
485
- encryptModel<T extends Record<string, unknown>, S extends EncryptedTableColumn = EncryptedTableColumn>(input: T, table: EncryptedTable<S>): EncryptModelOperation<EncryptedFromSchema<T, S>>;
503
+ encryptModel<T extends Record<string, unknown>, Table extends BuildableTable>(input: T, table: Table): EncryptModelOperation<EncryptedFromBuildableTable<T, Table>>;
486
504
  /**
487
505
  * Decrypt a model (object) whose fields contain encrypted values.
488
506
  *
@@ -557,7 +575,7 @@ declare class EncryptionClient {
557
575
  * }
558
576
  * ```
559
577
  */
560
- bulkEncryptModels<T extends Record<string, unknown>, S extends EncryptedTableColumn = EncryptedTableColumn>(input: Array<T>, table: EncryptedTable<S>): BulkEncryptModelsOperation<EncryptedFromSchema<T, S>>;
578
+ bulkEncryptModels<T extends Record<string, unknown>, Table extends BuildableTable>(input: Array<T>, table: Table): BulkEncryptModelsOperation<EncryptedFromBuildableTable<T, Table>>;
561
579
  /**
562
580
  * Decrypt multiple models (objects) in a single bulk operation.
563
581
  *
@@ -662,36 +680,155 @@ declare class EncryptionClient {
662
680
  */
663
681
  getEncryptConfig(): EncryptConfig | undefined;
664
682
  }
683
+ /**
684
+ * Reset the once-per-process deprecation-warning latch. Test-only hook so
685
+ * suites can assert the warning fires deterministically, independent of test
686
+ * ordering. Not re-exported from the package entry, so it stays off the public
687
+ * API surface.
688
+ * @internal
689
+ */
690
+ declare function __resetStrategyDeprecationWarningForTests(): void;
665
691
  /**
666
692
  * Creates and initializes an Encryption client for encrypting and decrypting data with CipherStash.
667
693
  *
668
694
  * Provide at least one schema (from {@link encryptedTable}) so the client knows which tables and
669
- * columns to use. Credentials are read from the optional `config` or from the environment
670
- * (`CS_WORKSPACE_CRN`, `CS_CLIENT_ID`, `CS_CLIENT_KEY`, `CS_CLIENT_ACCESS_KEY`).
671
- *
672
- * @param config - Initialization options. Must include `schemas`; optionally include `config` for
673
- * workspace/keys. Logging is configured via the `STASH_STACK_LOG` environment variable
674
- * (`debug | info | error`, default: `error`).
675
- * @returns A Promise that resolves to an initialized {@link EncryptionClient} ready for
676
- * {@link EncryptionClient.encrypt}, {@link EncryptionClient.decrypt}, and related operations.
695
+ * columns to use:
677
696
  *
678
- * @throws Throws if `schemas` is empty, or if a keyset `id` is supplied but is not a valid UUID.
679
- * Also throws if {@link EncryptionClient.init} fails (e.g. invalid credentials or config).
680
- *
681
- * @example
682
697
  * ```typescript
683
698
  * import { Encryption, encryptedTable, encryptedColumn } from "@cipherstash/stack"
684
699
  *
685
- * const users = encryptedTable("users", {
686
- * email: encryptedColumn("email"),
687
- * })
700
+ * const users = encryptedTable("users", { email: encryptedColumn("email") })
688
701
  * const client = await Encryption({ schemas: [users] })
689
702
  * const result = await client.encrypt("alice@example.com", { column: users.email, table: users })
690
703
  * ```
691
704
  *
705
+ * ## Authentication
706
+ *
707
+ * The snippets in this section reuse the `users` schema from the example above, and
708
+ * `workspaceCrn` / `accessKey` stand in for your own workspace credentials (from the
709
+ * [dashboard](https://dashboard.cipherstash.com) or the `CS_*` variables below).
710
+ *
711
+ * By default the client uses the `auto` auth strategy. `auto` first looks for the `CS_*`
712
+ * environment variables (see below) and, if they are not set, falls back to the local **dev
713
+ * profile** on your machine. The dev profile also supplies the client key, so during local
714
+ * development you generally don't need to set any environment variables at all.
715
+ *
716
+ * ### Local development — create a dev profile
717
+ *
718
+ * Log in once to create the dev profile that `auto` picks up automatically:
719
+ *
720
+ * ```bash
721
+ * npx stash auth login
722
+ * ```
723
+ *
724
+ * ### Production / CI — environment variables
725
+ *
726
+ * In production and CI you typically authenticate with the four `CS_*` environment variables
727
+ * instead of a dev profile. Developers can obtain these values from the
728
+ * [CipherStash dashboard](https://dashboard.cipherstash.com):
729
+ *
730
+ * | Environment variable | Description |
731
+ * | ---------------------- | ------------------------------------------------------------------------------ |
732
+ * | `CS_WORKSPACE_CRN` | The workspace Cloud Resource Name (CRN) that identifies your workspace. |
733
+ * | `CS_CLIENT_ID` | The client identifier issued when you create an access key. |
734
+ * | `CS_CLIENT_KEY` | The client key material combined with ZeroKMS to perform encryption. |
735
+ * | `CS_CLIENT_ACCESS_KEY` | The API access key used to authenticate requests to CipherStash. |
736
+ *
737
+ * When these are set, `auto` uses them in preference to the local dev profile.
738
+ *
739
+ * ### Custom auth strategies — `config.authStrategy`
740
+ *
741
+ * For finer control, pass an explicit strategy via `config.authStrategy` (from `@cipherstash/auth`,
742
+ * re-exported by `@cipherstash/stack`). See the `@cipherstash/auth` package for the full list. Two
743
+ * common choices:
744
+ *
745
+ * `AccessKeyStrategy` — like `auto`, but only ever uses an access key; it never falls back to the
746
+ * local dev profile. Ideal for services and CI:
747
+ *
748
+ * ```typescript
749
+ * import { Encryption, AccessKeyStrategy } from "@cipherstash/stack"
750
+ *
751
+ * const client = await Encryption({
752
+ * schemas: [users],
753
+ * config: {
754
+ * authStrategy: AccessKeyStrategy.create(workspaceCrn, accessKey),
755
+ * },
756
+ * })
757
+ * ```
758
+ *
759
+ * `OidcFederationStrategy` — authenticate end users through your own identity provider (Supabase,
760
+ * Clerk, Auth0 or Okta) by federating their OIDC JWT into a CipherStash token. Add the provider to
761
+ * your workspace first at
762
+ * [dashboard.cipherstash.com/workspaces/_/oidc-providers](https://dashboard.cipherstash.com/workspaces/_/oidc-providers)
763
+ * (the `_` in the URL resolves to whichever workspace you select):
764
+ *
765
+ * ```typescript
766
+ * import { Encryption, OidcFederationStrategy } from "@cipherstash/stack"
767
+ *
768
+ * // Authenticate every ZeroKMS request as the signed-in user.
769
+ * const client = await Encryption({
770
+ * schemas: [users],
771
+ * config: {
772
+ * authStrategy: OidcFederationStrategy.create(workspaceCrn, () => getUserJwt()),
773
+ * },
774
+ * })
775
+ * ```
776
+ *
777
+ * ### Lock context (identity-bound encryption)
778
+ *
779
+ * Lock context is an **additional** capability layered on top of `OidcFederationStrategy`: it
780
+ * requires that strategy, but `OidcFederationStrategy` does not require lock context. It binds a
781
+ * value to a claim from the user's JWT (typically `sub`) so that only the user who encrypted a
782
+ * value can decrypt it:
783
+ *
784
+ * ```typescript
785
+ * // Bind the data key to the user's `sub` claim.
786
+ * const result = await client
787
+ * .encrypt("alice@example.com", { column: users.email, table: users })
788
+ * .withLockContext({ identityClaim: ["sub"] })
789
+ * ```
790
+ *
791
+ * Because the lock is tied to a specific end user's identity, `AccessKeyStrategy` (which
792
+ * authenticates a service, not a user) is not valid for lock context — there is no user `sub`
793
+ * claim to bind to.
794
+ *
795
+ * ## Keysets (multi-tenant isolation)
796
+ *
797
+ * Pass `config.keyset` to encrypt under a specific **keyset** — a named or UUID-identified keyspace
798
+ * that gives each tenant its own cryptographic isolation, so data encrypted under one keyset cannot
799
+ * be decrypted under another. Create and manage keysets in the
800
+ * [dashboard](https://dashboard.cipherstash.com/workspaces/_/keysets) (the `_` in the URL resolves
801
+ * to whichever workspace you select); omit `config.keyset` to use the workspace's default keyset.
802
+ *
803
+ * ```typescript
804
+ * // `users` is the schema from the first example above.
805
+ * const client = await Encryption({
806
+ * schemas: [users],
807
+ * config: {
808
+ * keyset: { name: "tenant-a" }, // or { id: "<uuid>" }
809
+ * },
810
+ * })
811
+ * ```
812
+ *
813
+ * A client is bound to a single keyset for its lifetime, so multi-tenant applications use **one
814
+ * `Encryption()` client per tenant**. Keysets are orthogonal to `authStrategy` and lock context —
815
+ * they isolate a whole tenant's *keyspace* (coarse, fixed per client), whereas lock context binds
816
+ * an individual value to a user's identity claim (fine-grained, per operation) — and can be
817
+ * combined with both.
818
+ *
819
+ * @param config - Initialization options. Must include `schemas`; optionally include `config` for
820
+ * credentials and authentication. Logging is configured via the `STASH_STACK_LOG` environment
821
+ * variable (`debug | info | error`, default: `error`).
822
+ * @returns A Promise that resolves to an initialized {@link EncryptionClient} ready for
823
+ * {@link EncryptionClient.encrypt}, {@link EncryptionClient.decrypt}, and related operations.
824
+ *
825
+ * @throws Throws if `schemas` is empty, or if a keyset `id` is supplied but is not a valid UUID.
826
+ * Also throws if the client fails to initialize (e.g. invalid credentials or config).
827
+ *
692
828
  * @see {@link EncryptionClientConfig} for full config options.
829
+ * @see {@link ClientConfig.authStrategy} for the auth strategy field.
693
830
  * @see {@link EncryptionClient} for available methods after initialization.
694
831
  */
695
832
  declare const Encryption: (config: EncryptionClientConfig) => Promise<EncryptionClient>;
696
833
 
697
- export { type AuditConfig as A, Encryption as E, EncryptionClient as a, noClientError as n };
834
+ export { type AuditConfig as A, BulkEncryptModelsOperation as B, DecryptOperation as D, EncryptOperation as E, __resetStrategyDeprecationWarningForTests as _, EncryptQueryOperation as a, EncryptModelOperation as b, BulkEncryptOperation as c, BulkDecryptOperation as d, EncryptionClient as e, Encryption as f, BatchEncryptQueryOperation as g, BulkDecryptModelsOperation as h, DecryptModelOperation as i, noClientError as n, resolveEqlVersion as r };