@cipherstash/stack 0.19.0 → 1.0.0-rc.1

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 (101) hide show
  1. package/CHANGELOG.md +596 -0
  2. package/README.md +376 -276
  3. package/dist/adapter-kit.cjs +1002 -0
  4. package/dist/adapter-kit.cjs.map +1 -0
  5. package/dist/adapter-kit.d.cts +120 -0
  6. package/dist/adapter-kit.d.ts +120 -0
  7. package/dist/adapter-kit.js +122 -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-4AVL4VZD.js → chunk-3B5ZX3IS.js} +3 -1
  12. package/dist/chunk-3B5ZX3IS.js.map +1 -0
  13. package/dist/{chunk-U66S7VIF.js → chunk-6SGN52W6.js} +166 -107
  14. package/dist/chunk-6SGN52W6.js.map +1 -0
  15. package/dist/chunk-7333ZC6L.js +48 -0
  16. package/dist/chunk-7333ZC6L.js.map +1 -0
  17. package/dist/{chunk-MP3SSDNN.js → chunk-CLM7E4I6.js} +15 -15
  18. package/dist/{chunk-MP3SSDNN.js.map → chunk-CLM7E4I6.js.map} +1 -1
  19. package/dist/{chunk-OFQ555AX.js → chunk-IDKP6ABU.js} +2 -2
  20. package/dist/{chunk-36AA7IBJ.js → chunk-L7ISHSG7.js} +53 -20
  21. package/dist/chunk-L7ISHSG7.js.map +1 -0
  22. package/dist/{chunk-LBMC4D6D.js → chunk-NVKK7UDN.js} +1 -1
  23. package/dist/chunk-NVKK7UDN.js.map +1 -0
  24. package/dist/chunk-X3JRXEIB.js +98 -0
  25. package/dist/chunk-X3JRXEIB.js.map +1 -0
  26. package/dist/client.cjs +29 -12
  27. package/dist/client.cjs.map +1 -1
  28. package/dist/client.d.cts +3 -2
  29. package/dist/client.d.ts +3 -2
  30. package/dist/client.js +2 -2
  31. package/dist/{table-CIH7jZ2h.d.ts → columns-0lbT9stl.d.ts} +157 -138
  32. package/dist/{table-DihEAlxG.d.cts → columns-Bxv7Oo9o.d.cts} +157 -138
  33. package/dist/dynamodb/index.d.cts +3 -2
  34. package/dist/dynamodb/index.d.ts +3 -2
  35. package/dist/encryption/index.cjs +54 -16
  36. package/dist/encryption/index.cjs.map +1 -1
  37. package/dist/encryption/index.d.cts +807 -6
  38. package/dist/encryption/index.d.ts +807 -6
  39. package/dist/encryption/index.js +6 -6
  40. package/dist/encryption/v3.cjs +1078 -973
  41. package/dist/encryption/v3.cjs.map +1 -1
  42. package/dist/encryption/v3.d.cts +15 -12
  43. package/dist/encryption/v3.d.ts +15 -12
  44. package/dist/encryption/v3.js +50 -22
  45. package/dist/encryption/v3.js.map +1 -1
  46. package/dist/eql/v3/index.cjs +130 -79
  47. package/dist/eql/v3/index.cjs.map +1 -1
  48. package/dist/eql/v3/index.d.cts +115 -13
  49. package/dist/eql/v3/index.d.ts +115 -13
  50. package/dist/eql/v3/index.js +16 -6
  51. package/dist/errors/index.cjs.map +1 -1
  52. package/dist/errors/index.d.cts +5 -5
  53. package/dist/errors/index.d.ts +5 -5
  54. package/dist/errors/index.js +1 -1
  55. package/dist/identity/index.cjs.map +1 -1
  56. package/dist/identity/index.js +2 -2
  57. package/dist/index-BquA71_Y.d.ts +24 -0
  58. package/dist/index-fhWTOV0K.d.cts +24 -0
  59. package/dist/index.cjs +79 -27
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.d.cts +5 -17
  62. package/dist/index.d.ts +5 -17
  63. package/dist/index.js +6 -6
  64. package/dist/schema/index.cjs +29 -12
  65. package/dist/schema/index.cjs.map +1 -1
  66. package/dist/schema/index.d.cts +1 -1
  67. package/dist/schema/index.d.ts +1 -1
  68. package/dist/schema/index.js +2 -2
  69. package/dist/{types-public-CpS5KjwX.d.ts → types-public-QMjYNfQO.d.cts} +765 -726
  70. package/dist/{types-public-CpS5KjwX.d.cts → types-public-QMjYNfQO.d.ts} +765 -726
  71. package/dist/types-public.cjs.map +1 -1
  72. package/dist/types-public.d.cts +1 -1
  73. package/dist/types-public.d.ts +1 -1
  74. package/dist/types-public.js +1 -1
  75. package/dist/wasm-inline.d.ts +779 -405
  76. package/dist/wasm-inline.js +606 -299
  77. package/dist/wasm-inline.js.map +1 -1
  78. package/package.json +25 -53
  79. package/dist/chunk-36AA7IBJ.js.map +0 -1
  80. package/dist/chunk-4AVL4VZD.js.map +0 -1
  81. package/dist/chunk-IADZCZEA.js +0 -23
  82. package/dist/chunk-IADZCZEA.js.map +0 -1
  83. package/dist/chunk-IBSK6P33.js +0 -209
  84. package/dist/chunk-IBSK6P33.js.map +0 -1
  85. package/dist/chunk-LBMC4D6D.js.map +0 -1
  86. package/dist/chunk-U66S7VIF.js.map +0 -1
  87. package/dist/client-DSGHBN-g.d.cts +0 -834
  88. package/dist/client-DfCrlHXh.d.ts +0 -834
  89. package/dist/drizzle/index.cjs +0 -5617
  90. package/dist/drizzle/index.cjs.map +0 -1
  91. package/dist/drizzle/index.d.cts +0 -358
  92. package/dist/drizzle/index.d.ts +0 -358
  93. package/dist/drizzle/index.js +0 -1220
  94. package/dist/drizzle/index.js.map +0 -1
  95. package/dist/supabase/index.cjs +0 -5951
  96. package/dist/supabase/index.cjs.map +0 -1
  97. package/dist/supabase/index.d.cts +0 -223
  98. package/dist/supabase/index.d.ts +0 -223
  99. package/dist/supabase/index.js +0 -1217
  100. package/dist/supabase/index.js.map +0 -1
  101. /package/dist/{chunk-OFQ555AX.js.map → chunk-IDKP6ABU.js.map} +0 -0
@@ -1,834 +0,0 @@
1
- import { Result } from '@byteslice/result';
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
-
7
- type AuditConfig = {
8
- metadata?: Record<string, unknown>;
9
- };
10
- type AuditData = {
11
- metadata?: Record<string, unknown>;
12
- };
13
- declare abstract class EncryptionOperation<T> {
14
- protected auditMetadata?: Record<string, unknown>;
15
- /**
16
- * Attach audit metadata to this operation. Can be chained.
17
- * @param config Configuration for ZeroKMS audit logging
18
- * @param config.metadata Arbitrary JSON object for appending metadata to the audit log
19
- */
20
- audit(config: AuditConfig): this;
21
- /**
22
- * Get the audit data for this operation.
23
- */
24
- getAuditData(): AuditData;
25
- /**
26
- * Execute the operation and return a Result
27
- */
28
- abstract execute(): Promise<Result<T, EncryptionError>>;
29
- /**
30
- * Make the operation thenable
31
- */
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
- }
34
-
35
- declare class BatchEncryptQueryOperation extends EncryptionOperation<EncryptedQueryResult[]> {
36
- private client;
37
- private terms;
38
- constructor(client: Client, terms: readonly ScalarQueryTerm[]);
39
- withLockContext(lockContext: LockContextInput): BatchEncryptQueryOperationWithLockContext;
40
- execute(): Promise<Result<EncryptedQueryResult[], EncryptionError>>;
41
- }
42
- declare class BatchEncryptQueryOperationWithLockContext extends EncryptionOperation<EncryptedQueryResult[]> {
43
- private client;
44
- private terms;
45
- private lockContext;
46
- constructor(client: Client, terms: readonly ScalarQueryTerm[], lockContext: LockContextInput, auditMetadata?: Record<string, unknown>);
47
- execute(): Promise<Result<EncryptedQueryResult[], EncryptionError>>;
48
- }
49
-
50
- declare class BulkDecryptOperation extends EncryptionOperation<BulkDecryptedData> {
51
- private client;
52
- private encryptedPayloads;
53
- constructor(client: Client, encryptedPayloads: BulkDecryptPayload);
54
- withLockContext(lockContext: LockContextInput): BulkDecryptOperationWithLockContext;
55
- execute(): Promise<Result<BulkDecryptedData, EncryptionError>>;
56
- getOperation(): {
57
- client: Client;
58
- encryptedPayloads: BulkDecryptPayload;
59
- };
60
- }
61
- declare class BulkDecryptOperationWithLockContext extends EncryptionOperation<BulkDecryptedData> {
62
- private operation;
63
- private lockContext;
64
- constructor(operation: BulkDecryptOperation, lockContext: LockContextInput);
65
- execute(): Promise<Result<BulkDecryptedData, EncryptionError>>;
66
- }
67
-
68
- declare class BulkDecryptModelsOperation<T extends Record<string, unknown>> extends EncryptionOperation<Decrypted<T>[]> {
69
- private client;
70
- private models;
71
- constructor(client: Client, models: T[]);
72
- withLockContext(lockContext: LockContextInput): BulkDecryptModelsOperationWithLockContext<T>;
73
- execute(): Promise<Result<Decrypted<T>[], EncryptionError>>;
74
- getOperation(): {
75
- client: Client;
76
- models: T[];
77
- };
78
- }
79
- declare class BulkDecryptModelsOperationWithLockContext<T extends Record<string, unknown>> extends EncryptionOperation<Decrypted<T>[]> {
80
- private operation;
81
- private lockContext;
82
- constructor(operation: BulkDecryptModelsOperation<T>, lockContext: LockContextInput);
83
- execute(): Promise<Result<Decrypted<T>[], EncryptionError>>;
84
- }
85
-
86
- declare class BulkEncryptOperation extends EncryptionOperation<BulkEncryptedData> {
87
- private client;
88
- private plaintexts;
89
- private column;
90
- private table;
91
- constructor(client: Client, plaintexts: BulkEncryptPayload, opts: EncryptOptions);
92
- withLockContext(lockContext: LockContextInput): BulkEncryptOperationWithLockContext;
93
- execute(): Promise<Result<BulkEncryptedData, EncryptionError>>;
94
- getOperation(): {
95
- client: Client;
96
- plaintexts: BulkEncryptPayload;
97
- column: BuildableColumn;
98
- table: BuildableTable;
99
- };
100
- }
101
- declare class BulkEncryptOperationWithLockContext extends EncryptionOperation<BulkEncryptedData> {
102
- private operation;
103
- private lockContext;
104
- constructor(operation: BulkEncryptOperation, lockContext: LockContextInput);
105
- execute(): Promise<Result<BulkEncryptedData, EncryptionError>>;
106
- }
107
-
108
- declare class BulkEncryptModelsOperation<T extends Record<string, unknown>> extends EncryptionOperation<T[]> {
109
- private client;
110
- private models;
111
- private table;
112
- constructor(client: Client, models: Record<string, unknown>[], table: BuildableTable);
113
- withLockContext(lockContext: LockContextInput): BulkEncryptModelsOperationWithLockContext<T>;
114
- execute(): Promise<Result<T[], EncryptionError>>;
115
- getOperation(): {
116
- client: Client;
117
- models: Record<string, unknown>[];
118
- table: BuildableTable;
119
- };
120
- }
121
- declare class BulkEncryptModelsOperationWithLockContext<T extends Record<string, unknown>> extends EncryptionOperation<T[]> {
122
- private operation;
123
- private lockContext;
124
- constructor(operation: BulkEncryptModelsOperation<T>, lockContext: LockContextInput);
125
- execute(): Promise<Result<T[], EncryptionError>>;
126
- }
127
-
128
- /**
129
- * Decrypts an encrypted payload using the provided client.
130
- * This is the type returned by the {@link EncryptionClient.decrypt | decrypt} method of the {@link EncryptionClient}.
131
- */
132
- declare class DecryptOperation extends EncryptionOperation<JsPlaintext> {
133
- private client;
134
- private encryptedData;
135
- constructor(client: Client, encryptedData: Encrypted | null);
136
- withLockContext(lockContext: LockContextInput): DecryptOperationWithLockContext;
137
- execute(): Promise<Result<JsPlaintext, EncryptionError>>;
138
- getOperation(): {
139
- client: Client;
140
- encryptedData: Encrypted | null;
141
- auditData?: Record<string, unknown>;
142
- };
143
- }
144
- declare class DecryptOperationWithLockContext extends EncryptionOperation<JsPlaintext> {
145
- private operation;
146
- private lockContext;
147
- constructor(operation: DecryptOperation, lockContext: LockContextInput);
148
- execute(): Promise<Result<JsPlaintext, EncryptionError>>;
149
- }
150
-
151
- declare class DecryptModelOperation<T extends Record<string, unknown>> extends EncryptionOperation<Decrypted<T>> {
152
- private client;
153
- private model;
154
- constructor(client: Client, model: T);
155
- withLockContext(lockContext: LockContextInput): DecryptModelOperationWithLockContext<T>;
156
- execute(): Promise<Result<Decrypted<T>, EncryptionError>>;
157
- getOperation(): {
158
- client: Client;
159
- model: T;
160
- };
161
- }
162
- declare class DecryptModelOperationWithLockContext<T extends Record<string, unknown>> extends EncryptionOperation<Decrypted<T>> {
163
- private operation;
164
- private lockContext;
165
- constructor(operation: DecryptModelOperation<T>, lockContext: LockContextInput);
166
- execute(): Promise<Result<Decrypted<T>, EncryptionError>>;
167
- }
168
-
169
- declare class EncryptOperation extends EncryptionOperation<Encrypted> {
170
- private client;
171
- private plaintext;
172
- private column;
173
- private table;
174
- constructor(client: Client, plaintext: Plaintext | null, opts: EncryptOptions);
175
- withLockContext(lockContext: LockContextInput): EncryptOperationWithLockContext;
176
- execute(): Promise<Result<Encrypted, EncryptionError>>;
177
- getOperation(): {
178
- client: Client;
179
- plaintext: Plaintext | null;
180
- column: BuildableColumn;
181
- table: BuildableTable;
182
- };
183
- }
184
- declare class EncryptOperationWithLockContext extends EncryptionOperation<Encrypted> {
185
- private operation;
186
- private lockContext;
187
- constructor(operation: EncryptOperation, lockContext: LockContextInput);
188
- execute(): Promise<Result<Encrypted, EncryptionError>>;
189
- }
190
-
191
- declare class EncryptModelOperation<T extends Record<string, unknown>> extends EncryptionOperation<T> {
192
- private client;
193
- private model;
194
- private table;
195
- constructor(client: Client, model: Record<string, unknown>, table: BuildableTable);
196
- withLockContext(lockContext: LockContextInput): EncryptModelOperationWithLockContext<T>;
197
- execute(): Promise<Result<T, EncryptionError>>;
198
- getOperation(): {
199
- client: Client;
200
- model: Record<string, unknown>;
201
- table: BuildableTable;
202
- };
203
- }
204
- declare class EncryptModelOperationWithLockContext<T extends Record<string, unknown>> extends EncryptionOperation<T> {
205
- private operation;
206
- private lockContext;
207
- constructor(operation: EncryptModelOperation<T>, lockContext: LockContextInput);
208
- execute(): Promise<Result<T, EncryptionError>>;
209
- }
210
-
211
- declare class EncryptQueryOperation extends EncryptionOperation<EncryptedQueryResult> {
212
- private client;
213
- private plaintext;
214
- private opts;
215
- constructor(client: Client, plaintext: Plaintext | null | undefined, opts: EncryptQueryOptions);
216
- withLockContext(lockContext: LockContextInput): EncryptQueryOperationWithLockContext;
217
- execute(): Promise<Result<EncryptedQueryResult, EncryptionError>>;
218
- getOperation(): {
219
- column: BuildableQueryColumn;
220
- table: BuildableTable;
221
- queryType?: QueryTypeName;
222
- returnType?: EncryptedReturnType;
223
- client: Client;
224
- plaintext: Plaintext | null | undefined;
225
- };
226
- }
227
- declare class EncryptQueryOperationWithLockContext extends EncryptionOperation<EncryptedQueryResult> {
228
- private client;
229
- private plaintext;
230
- private opts;
231
- private lockContext;
232
- constructor(client: Client, plaintext: Plaintext | null | undefined, opts: EncryptQueryOptions, lockContext: LockContextInput, auditMetadata?: Record<string, unknown>);
233
- execute(): Promise<Result<EncryptedQueryResult, EncryptionError>>;
234
- }
235
-
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;
258
- /** The EncryptionClient is the main entry point for interacting with the CipherStash Encryption library.
259
- * It provides methods for encrypting and decrypting individual values, as well as models (objects) and bulk operations.
260
- *
261
- * The client must be initialized using the {@link Encryption} function before it can be used.
262
- */
263
- declare class EncryptionClient {
264
- private client;
265
- private encryptConfig;
266
- /**
267
- * Initializes the EncryptionClient with the provided configuration.
268
- * @internal
269
- * @param config - The configuration object for initializing the client.
270
- * @returns A promise that resolves to a {@link Result} containing the initialized EncryptionClient or an {@link EncryptionError}.
271
- **/
272
- init(config: {
273
- encryptConfig: EncryptConfig;
274
- workspaceCrn?: string;
275
- accessKey?: string;
276
- clientId?: string;
277
- clientKey?: string;
278
- keyset?: KeysetIdentifier;
279
- authStrategy?: AuthStrategy;
280
- eqlVersion?: 2 | 3;
281
- }): Promise<Result<EncryptionClient, EncryptionError>>;
282
- /**
283
- * Encrypt a value - returns a promise which resolves to an encrypted value.
284
- *
285
- * @param plaintext - The plaintext value to be encrypted.
286
- * @param opts - Options specifying the column (or nested field) and table for encryption. See {@link EncryptOptions}.
287
- * @returns An EncryptOperation that can be awaited or chained with additional methods.
288
- *
289
- * @example
290
- * The following example demonstrates how to encrypt a value using the Encryption client.
291
- * It includes defining an encryption schema with {@link encryptedTable} and {@link encryptedColumn},
292
- * initializing the client with {@link Encryption}, and performing the encryption.
293
- *
294
- * `encrypt` returns an {@link EncryptOperation} which can be awaited to get a {@link Result}
295
- * which can either be the encrypted value or an {@link EncryptionError}.
296
- *
297
- * ```typescript
298
- * // Define encryption schema
299
- * import { Encryption } from "@cipherstash/stack"
300
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
301
- * const userSchema = encryptedTable("users", {
302
- * email: encryptedColumn("email"),
303
- * });
304
- *
305
- * // Initialize Encryption client
306
- * const client = await Encryption({ schemas: [userSchema] })
307
- *
308
- * // Encrypt a value
309
- * const encryptedResult = await client.encrypt(
310
- * "person@example.com",
311
- * { column: userSchema.email, table: userSchema }
312
- * )
313
- *
314
- * // Handle encryption result
315
- * if (encryptedResult.failure) {
316
- * throw new Error(`Encryption failed: ${encryptedResult.failure.message}`);
317
- * }
318
- *
319
- * console.log("Encrypted data:", encryptedResult.data);
320
- * ```
321
- *
322
- * @example
323
- * When encrypting data, a {@link LockContext} can be provided to tie the encryption to a specific user or session.
324
- * This ensures that the same lock context is required for decryption.
325
- *
326
- * The following example demonstrates how to create a lock context using a user's JWT token
327
- * and use it during encryption.
328
- *
329
- * ```typescript
330
- * // Define encryption schema and initialize client as above
331
- *
332
- * // Create a lock for the user's `sub` claim from their JWT
333
- * const lc = new LockContext();
334
- * const lockContext = await lc.identify(userJwt);
335
- *
336
- * if (lockContext.failure) {
337
- * // Handle the failure
338
- * }
339
- *
340
- * // Encrypt a value with the lock context
341
- * // Decryption will then require the same lock context
342
- * const encryptedResult = await client.encrypt(
343
- * "person@example.com",
344
- * { column: userSchema.email, table: userSchema }
345
- * )
346
- * .withLockContext(lockContext)
347
- * ```
348
- *
349
- * @see {@link EncryptOptions}
350
- * @see {@link Result}
351
- * @see {@link encryptedTable}
352
- * @see {@link encryptedColumn}
353
- * @see {@link encryptedField}
354
- * @see {@link LockContext}
355
- * @see {@link EncryptOperation}
356
- */
357
- encrypt(plaintext: Plaintext, opts: EncryptOptions): EncryptOperation;
358
- /**
359
- * Encrypt a query value - returns a promise which resolves to an encrypted query value.
360
- *
361
- * @param plaintext - The plaintext value to be encrypted for querying.
362
- * @param opts - Options specifying the column, table, and optional queryType for encryption.
363
- * @returns An EncryptQueryOperation that can be awaited or chained with additional methods.
364
- *
365
- * @example
366
- * The following example demonstrates how to encrypt a query value using the Encryption client.
367
- *
368
- * ```typescript
369
- * // Define encryption schema
370
- * import { Encryption } from "@cipherstash/stack"
371
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
372
- * const userSchema = encryptedTable("users", {
373
- * email: encryptedColumn("email").equality(),
374
- * });
375
- *
376
- * // Initialize Encryption client
377
- * const client = await Encryption({ schemas: [userSchema] })
378
- *
379
- * // Encrypt a query value
380
- * const encryptedResult = await client.encryptQuery(
381
- * "person@example.com",
382
- * { column: userSchema.email, table: userSchema, queryType: 'equality' }
383
- * )
384
- *
385
- * // Handle encryption result
386
- * if (encryptedResult.failure) {
387
- * throw new Error(`Encryption failed: ${encryptedResult.failure.message}`);
388
- * }
389
- *
390
- * console.log("Encrypted query:", encryptedResult.data);
391
- * ```
392
- *
393
- * @example
394
- * The queryType can be auto-inferred from the column's configured indexes:
395
- *
396
- * ```typescript
397
- * // When queryType is omitted, it will be inferred from the column's indexes
398
- * const encryptedResult = await client.encryptQuery(
399
- * "person@example.com",
400
- * { column: userSchema.email, table: userSchema }
401
- * )
402
- * ```
403
- *
404
- * @see {@link EncryptQueryOperation}
405
- *
406
- * **JSONB columns (searchableJson):**
407
- * When `queryType` is omitted on a `searchableJson()` column, the query operation is inferred:
408
- * - String plaintext → `steVecSelector` (JSONPath queries like `'$.user.email'`)
409
- * - Object/Array plaintext → `steVecTerm` (containment queries like `{ role: 'admin' }`)
410
- */
411
- encryptQuery(plaintext: Plaintext, opts: EncryptQueryOptions): EncryptQueryOperation;
412
- /**
413
- * Encrypt multiple values for use in queries (batch operation).
414
- * @param terms - Array of query terms to encrypt
415
- */
416
- encryptQuery(terms: readonly ScalarQueryTerm[]): BatchEncryptQueryOperation;
417
- /**
418
- * Decryption - returns a promise which resolves to a decrypted value.
419
- *
420
- * @param encryptedData - The encrypted data to be decrypted.
421
- * @returns A DecryptOperation that can be awaited or chained with additional methods.
422
- *
423
- * @example
424
- * The following example demonstrates how to decrypt a value that was previously encrypted using the {@link encrypt} method.
425
- * It includes encrypting a value first, then decrypting it, and handling the result.
426
- *
427
- * ```typescript
428
- * const encryptedData = await client.encrypt(
429
- * "person@example.com",
430
- * { column: "email", table: "users" }
431
- * )
432
- * const decryptResult = await client.decrypt(encryptedData)
433
- * if (decryptResult.failure) {
434
- * throw new Error(`Decryption failed: ${decryptResult.failure.message}`);
435
- * }
436
- * console.log("Decrypted data:", decryptResult.data);
437
- * ```
438
- *
439
- * @example
440
- * Provide a lock context when decrypting:
441
- * ```typescript
442
- * await client.decrypt(encryptedData)
443
- * .withLockContext(lockContext)
444
- * ```
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
- *
453
- * @see {@link LockContext}
454
- * @see {@link DecryptOperation}
455
- */
456
- decrypt(encryptedData: Encrypted): DecryptOperation;
457
- /**
458
- * Encrypt a model (object) based on the table schema.
459
- *
460
- * Only fields whose keys match columns defined in the table schema are encrypted.
461
- * All other fields are passed through unchanged. Returns a thenable operation
462
- * that supports `.withLockContext()` for identity-aware encryption.
463
- *
464
- * The return type is **schema-aware**: fields matching the table schema are
465
- * typed as `Encrypted`, while other fields retain their original types. For
466
- * best results, let TypeScript infer the type parameters from the arguments
467
- * rather than providing an explicit type argument.
468
- *
469
- * @param input - The model object with plaintext values to encrypt.
470
- * @param table - The table schema defining which fields to encrypt.
471
- * @returns An `EncryptModelOperation` that can be awaited to get a `Result`
472
- * containing the model with schema-defined fields typed as `Encrypted`,
473
- * or an `EncryptionError`.
474
- *
475
- * @example
476
- * ```typescript
477
- * import { Encryption } from "@cipherstash/stack"
478
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
479
- *
480
- * type User = { id: string; email: string; createdAt: Date }
481
- *
482
- * const usersSchema = encryptedTable("users", {
483
- * email: encryptedColumn("email").equality(),
484
- * })
485
- *
486
- * const client = await Encryption({ schemas: [usersSchema] })
487
- *
488
- * // Let TypeScript infer the return type from the schema.
489
- * // result.data.email is typed as `Encrypted`, result.data.id stays `string`.
490
- * const result = await client.encryptModel(
491
- * { id: "user_123", email: "alice@example.com", createdAt: new Date() },
492
- * usersSchema,
493
- * )
494
- *
495
- * if (result.failure) {
496
- * console.error(result.failure.message)
497
- * } else {
498
- * console.log(result.data.id) // string
499
- * console.log(result.data.email) // Encrypted
500
- * }
501
- * ```
502
- */
503
- encryptModel<T extends Record<string, unknown>, Table extends BuildableTable>(input: T, table: Table): EncryptModelOperation<EncryptedFromBuildableTable<T, Table>>;
504
- /**
505
- * Decrypt a model (object) whose fields contain encrypted values.
506
- *
507
- * Identifies encrypted fields automatically and decrypts them, returning the
508
- * model with plaintext values. Returns a thenable operation that supports
509
- * `.withLockContext()` for identity-aware decryption.
510
- *
511
- * @param input - The model object with encrypted field values.
512
- * @returns A `DecryptModelOperation<T>` that can be awaited to get a `Result`
513
- * containing the model with decrypted plaintext fields, or an `EncryptionError`.
514
- *
515
- * @example
516
- * ```typescript
517
- * // Decrypt a previously encrypted model
518
- * const decrypted = await client.decryptModel<User>(encryptedUser)
519
- *
520
- * if (decrypted.failure) {
521
- * console.error(decrypted.failure.message)
522
- * } else {
523
- * console.log(decrypted.data.email) // "alice@example.com"
524
- * }
525
- *
526
- * // With a lock context
527
- * const decrypted = await client
528
- * .decryptModel<User>(encryptedUser)
529
- * .withLockContext(lockContext)
530
- * ```
531
- */
532
- decryptModel<T extends Record<string, unknown>>(input: T): DecryptModelOperation<T>;
533
- /**
534
- * Encrypt multiple models (objects) in a single bulk operation.
535
- *
536
- * Performs a single call to ZeroKMS regardless of the number of models,
537
- * while still using a unique key for each encrypted value. Only fields
538
- * matching the table schema are encrypted; other fields pass through unchanged.
539
- *
540
- * The return type is **schema-aware**: fields matching the table schema are
541
- * typed as `Encrypted`, while other fields retain their original types. For
542
- * best results, let TypeScript infer the type parameters from the arguments.
543
- *
544
- * @param input - An array of model objects with plaintext values to encrypt.
545
- * @param table - The table schema defining which fields to encrypt.
546
- * @returns A `BulkEncryptModelsOperation` that can be awaited to get a `Result`
547
- * containing an array of models with schema-defined fields typed as `Encrypted`,
548
- * or an `EncryptionError`.
549
- *
550
- * @example
551
- * ```typescript
552
- * import { Encryption } from "@cipherstash/stack"
553
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
554
- *
555
- * type User = { id: string; email: string }
556
- *
557
- * const usersSchema = encryptedTable("users", {
558
- * email: encryptedColumn("email"),
559
- * })
560
- *
561
- * const client = await Encryption({ schemas: [usersSchema] })
562
- *
563
- * // Let TypeScript infer the return type from the schema.
564
- * // Each item's email is typed as `Encrypted`, id stays `string`.
565
- * const result = await client.bulkEncryptModels(
566
- * [
567
- * { id: "1", email: "alice@example.com" },
568
- * { id: "2", email: "bob@example.com" },
569
- * ],
570
- * usersSchema,
571
- * )
572
- *
573
- * if (!result.failure) {
574
- * console.log(result.data) // array of models with encrypted email fields
575
- * }
576
- * ```
577
- */
578
- bulkEncryptModels<T extends Record<string, unknown>, Table extends BuildableTable>(input: Array<T>, table: Table): BulkEncryptModelsOperation<EncryptedFromBuildableTable<T, Table>>;
579
- /**
580
- * Decrypt multiple models (objects) in a single bulk operation.
581
- *
582
- * Performs a single call to ZeroKMS regardless of the number of models,
583
- * restoring all encrypted fields to their original plaintext values.
584
- *
585
- * @param input - An array of model objects with encrypted field values.
586
- * @returns A `BulkDecryptModelsOperation<T>` that can be awaited to get a `Result`
587
- * containing an array of models with decrypted plaintext fields, or an `EncryptionError`.
588
- *
589
- * @example
590
- * ```typescript
591
- * const encryptedUsers = encryptedResult.data // from bulkEncryptModels
592
- *
593
- * const result = await client.bulkDecryptModels<User>(encryptedUsers)
594
- *
595
- * if (!result.failure) {
596
- * for (const user of result.data) {
597
- * console.log(user.email) // plaintext email
598
- * }
599
- * }
600
- *
601
- * // With a lock context
602
- * const result = await client
603
- * .bulkDecryptModels<User>(encryptedUsers)
604
- * .withLockContext(lockContext)
605
- * ```
606
- */
607
- bulkDecryptModels<T extends Record<string, unknown>>(input: Array<T>): BulkDecryptModelsOperation<T>;
608
- /**
609
- * Encrypt multiple plaintext values in a single bulk operation.
610
- *
611
- * Each value is encrypted with its own unique key via a single call to ZeroKMS.
612
- * Values can include optional `id` fields for correlating results back to
613
- * your application data.
614
- *
615
- * @param plaintexts - An array of objects with `plaintext` (and optional `id`) fields.
616
- * @param opts - Options specifying the target column (or nested {@link encryptedField}) and table. See {@link EncryptOptions}.
617
- * @returns A `BulkEncryptOperation` that can be awaited to get a `Result`
618
- * containing an array of `{ id?, data: Encrypted }` objects, or an `EncryptionError`.
619
- *
620
- * @example
621
- * ```typescript
622
- * import { Encryption } from "@cipherstash/stack"
623
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
624
- *
625
- * const users = encryptedTable("users", {
626
- * email: encryptedColumn("email"),
627
- * })
628
- * const client = await Encryption({ schemas: [users] })
629
- *
630
- * const result = await client.bulkEncrypt(
631
- * [
632
- * { id: "u1", plaintext: "alice@example.com" },
633
- * { id: "u2", plaintext: "bob@example.com" },
634
- * ],
635
- * { column: users.email, table: users },
636
- * )
637
- *
638
- * if (!result.failure) {
639
- * // result.data = [{ id: "u1", data: Encrypted }, { id: "u2", data: Encrypted }, ...]
640
- * console.log(result.data)
641
- * }
642
- * ```
643
- */
644
- bulkEncrypt(plaintexts: BulkEncryptPayload, opts: EncryptOptions): BulkEncryptOperation;
645
- /**
646
- * Decrypt multiple encrypted values in a single bulk operation.
647
- *
648
- * Performs a single call to ZeroKMS to decrypt all values. The result uses
649
- * a multi-status pattern: each item in the returned array has either a `data`
650
- * field (success) or an `error` field (failure), allowing graceful handling
651
- * of partial failures.
652
- *
653
- * @param encryptedPayloads - An array of objects with `data` (encrypted payload) and optional `id` fields.
654
- * @returns A `BulkDecryptOperation` that can be awaited to get a `Result`
655
- * containing an array of `{ id?, data: plaintext }` or `{ id?, error: string }` objects,
656
- * or an `EncryptionError` if the entire operation fails.
657
- *
658
- * @example
659
- * ```typescript
660
- * const encrypted = await client.bulkEncrypt(plaintexts, { column: users.email, table: users })
661
- *
662
- * const result = await client.bulkDecrypt(encrypted.data)
663
- *
664
- * if (!result.failure) {
665
- * for (const item of result.data) {
666
- * if ("data" in item) {
667
- * console.log(`${item.id}: ${item.data}`)
668
- * } else {
669
- * console.error(`${item.id} failed: ${item.error}`)
670
- * }
671
- * }
672
- * }
673
- * ```
674
- */
675
- bulkDecrypt(encryptedPayloads: BulkDecryptPayload): BulkDecryptOperation;
676
- /**
677
- * Get the encrypt config object.
678
- *
679
- * @returns The encrypt config object.
680
- */
681
- getEncryptConfig(): EncryptConfig | undefined;
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;
691
- /**
692
- * Creates and initializes an Encryption client for encrypting and decrypting data with CipherStash.
693
- *
694
- * Provide at least one schema (from {@link encryptedTable}) so the client knows which tables and
695
- * columns to use:
696
- *
697
- * ```typescript
698
- * import { Encryption, encryptedTable, encryptedColumn } from "@cipherstash/stack"
699
- *
700
- * const users = encryptedTable("users", { email: encryptedColumn("email") })
701
- * const client = await Encryption({ schemas: [users] })
702
- * const result = await client.encrypt("alice@example.com", { column: users.email, table: users })
703
- * ```
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
- *
828
- * @see {@link EncryptionClientConfig} for full config options.
829
- * @see {@link ClientConfig.authStrategy} for the auth strategy field.
830
- * @see {@link EncryptionClient} for available methods after initialization.
831
- */
832
- declare const Encryption: (config: EncryptionClientConfig) => Promise<EncryptionClient>;
833
-
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 };