@cipherstash/stack 0.15.3 → 0.18.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 (65) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/dist/{chunk-6FD7OBGM.js → chunk-LLCCNKDL.js} +3 -3
  3. package/dist/chunk-LLCCNKDL.js.map +1 -0
  4. package/dist/{chunk-MD6742R6.js → chunk-VPOTNP4K.js} +1 -1
  5. package/dist/chunk-VPOTNP4K.js.map +1 -0
  6. package/dist/{chunk-4RNBI3UH.js → chunk-XWPGAHBZ.js} +1 -1
  7. package/dist/chunk-XWPGAHBZ.js.map +1 -0
  8. package/dist/{chunk-GNLU3I27.js → chunk-YWQXTZ5M.js} +4 -2
  9. package/dist/chunk-YWQXTZ5M.js.map +1 -0
  10. package/dist/{chunk-46S3YFRK.js → chunk-ZYOZHZMJ.js} +170 -54
  11. package/dist/chunk-ZYOZHZMJ.js.map +1 -0
  12. package/dist/{client-Dv60lAyy.d.ts → client-CIsfZ2zg.d.ts} +17 -22
  13. package/dist/{client-DQyqn0oT.d.cts → client-Dt98Rugc.d.cts} +17 -22
  14. package/dist/client.cjs +2 -0
  15. package/dist/client.cjs.map +1 -1
  16. package/dist/client.d.cts +2 -2
  17. package/dist/client.d.ts +2 -2
  18. package/dist/client.js +1 -1
  19. package/dist/drizzle/index.cjs +6 -3
  20. package/dist/drizzle/index.cjs.map +1 -1
  21. package/dist/drizzle/index.d.cts +2 -2
  22. package/dist/drizzle/index.d.ts +2 -2
  23. package/dist/drizzle/index.js +6 -5
  24. package/dist/drizzle/index.js.map +1 -1
  25. package/dist/dynamodb/index.cjs +14 -4
  26. package/dist/dynamodb/index.cjs.map +1 -1
  27. package/dist/dynamodb/index.d.cts +12 -12
  28. package/dist/dynamodb/index.d.ts +12 -12
  29. package/dist/dynamodb/index.js +9 -3
  30. package/dist/dynamodb/index.js.map +1 -1
  31. package/dist/encryption/index.cjs +178 -52
  32. package/dist/encryption/index.cjs.map +1 -1
  33. package/dist/encryption/index.d.cts +2 -2
  34. package/dist/encryption/index.d.ts +2 -2
  35. package/dist/encryption/index.js +25 -5
  36. package/dist/identity/index.cjs +2 -2
  37. package/dist/identity/index.cjs.map +1 -1
  38. package/dist/identity/index.js +3 -3
  39. package/dist/index.cjs +160 -52
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +3 -3
  42. package/dist/index.d.ts +3 -3
  43. package/dist/index.js +5 -5
  44. package/dist/schema/index.cjs +3 -1
  45. package/dist/schema/index.cjs.map +1 -1
  46. package/dist/schema/index.d.cts +1 -1
  47. package/dist/schema/index.d.ts +1 -1
  48. package/dist/schema/index.js +1 -1
  49. package/dist/supabase/index.cjs +2 -2
  50. package/dist/supabase/index.cjs.map +1 -1
  51. package/dist/supabase/index.d.cts +2 -2
  52. package/dist/supabase/index.d.ts +2 -2
  53. package/dist/supabase/index.js +3 -3
  54. package/dist/{types-public-DX3mGqoi.d.ts → types-public-BTxqjmtv.d.cts} +96 -81
  55. package/dist/{types-public-DX3mGqoi.d.cts → types-public-BTxqjmtv.d.ts} +96 -81
  56. package/dist/types-public.cjs.map +1 -1
  57. package/dist/types-public.d.cts +1 -1
  58. package/dist/types-public.d.ts +1 -1
  59. package/dist/types-public.js +1 -1
  60. package/package.json +16 -16
  61. package/dist/chunk-46S3YFRK.js.map +0 -1
  62. package/dist/chunk-4RNBI3UH.js.map +0 -1
  63. package/dist/chunk-6FD7OBGM.js.map +0 -1
  64. package/dist/chunk-GNLU3I27.js.map +0 -1
  65. package/dist/chunk-MD6742R6.js.map +0 -1
@@ -2,19 +2,19 @@ import {
2
2
  formatEncryptedResult,
3
3
  isEncryptedPayload,
4
4
  toFfiKeysetIdentifier
5
- } from "./chunk-4RNBI3UH.js";
5
+ } from "./chunk-XWPGAHBZ.js";
6
6
  import {
7
7
  buildEncryptConfig,
8
8
  encryptConfigSchema
9
- } from "./chunk-GNLU3I27.js";
9
+ } from "./chunk-YWQXTZ5M.js";
10
10
  import {
11
11
  queryTypeToFfi,
12
12
  queryTypeToQueryOp
13
- } from "./chunk-MD6742R6.js";
13
+ } from "./chunk-VPOTNP4K.js";
14
14
  import {
15
15
  createRequestLogger,
16
16
  logger
17
- } from "./chunk-6FD7OBGM.js";
17
+ } from "./chunk-LLCCNKDL.js";
18
18
  import {
19
19
  EncryptionErrorTypes
20
20
  } from "./chunk-LBMC4D6D.js";
@@ -22,7 +22,15 @@ import {
22
22
  // src/encryption/index.ts
23
23
  import { withResult as withResult11 } from "@byteslice/result";
24
24
  import { newClient } from "@cipherstash/protect-ffi";
25
- import { validate as uuidValidate } from "uuid";
25
+
26
+ // ../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/regex.js
27
+ var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
28
+
29
+ // ../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/validate.js
30
+ function validate(uuid) {
31
+ return typeof uuid === "string" && regex_default.test(uuid);
32
+ }
33
+ var validate_default = validate;
26
34
 
27
35
  // src/encryption/helpers/type-guards.ts
28
36
  function isScalarQueryTermArray(value) {
@@ -168,6 +176,15 @@ var EncryptionOperation = class {
168
176
  };
169
177
 
170
178
  // src/encryption/operations/batch-encrypt-query.ts
179
+ function filterNullTerms(terms) {
180
+ const nonNullTerms = [];
181
+ terms.forEach((term, index) => {
182
+ if (term.value !== null && term.value !== void 0) {
183
+ nonNullTerms.push({ term, originalIndex: index });
184
+ }
185
+ });
186
+ return { nonNullTerms };
187
+ }
171
188
  function buildQueryPayload(term, lockContext) {
172
189
  assertValidNumericValue(term.value);
173
190
  const { indexType, queryOp } = resolveIndexType(
@@ -188,10 +205,15 @@ function buildQueryPayload(term, lockContext) {
188
205
  }
189
206
  return payload;
190
207
  }
191
- function assembleResults(terms, encryptedValues) {
192
- return terms.map(
193
- (term, i) => formatEncryptedResult(encryptedValues[i], term.returnType)
194
- );
208
+ function assembleResults(totalLength, encryptedValues, nonNullTerms) {
209
+ const results = new Array(totalLength).fill(null);
210
+ nonNullTerms.forEach(({ term, originalIndex }, i) => {
211
+ results[originalIndex] = formatEncryptedResult(
212
+ encryptedValues[i],
213
+ term.returnType
214
+ );
215
+ });
216
+ return results;
195
217
  }
196
218
  var BatchEncryptQueryOperation = class extends EncryptionOperation {
197
219
  constructor(client, terms) {
@@ -199,6 +221,8 @@ var BatchEncryptQueryOperation = class extends EncryptionOperation {
199
221
  this.client = client;
200
222
  this.terms = terms;
201
223
  }
224
+ client;
225
+ terms;
202
226
  withLockContext(lockContext) {
203
227
  return new BatchEncryptQueryOperationWithLockContext(
204
228
  this.client,
@@ -218,18 +242,23 @@ var BatchEncryptQueryOperation = class extends EncryptionOperation {
218
242
  log.emit();
219
243
  return { data: [] };
220
244
  }
245
+ const { nonNullTerms } = filterNullTerms(this.terms);
246
+ if (nonNullTerms.length === 0) {
247
+ log.emit();
248
+ return { data: this.terms.map(() => null) };
249
+ }
221
250
  const result = await withResult(
222
251
  async () => {
223
252
  if (!this.client) throw noClientError();
224
253
  const { metadata } = this.getAuditData();
225
- const queries = this.terms.map(
226
- (term) => buildQueryPayload(term)
254
+ const queries = nonNullTerms.map(
255
+ ({ term }) => buildQueryPayload(term)
227
256
  );
228
257
  const encrypted = await ffiEncryptQueryBulk(this.client, {
229
258
  queries,
230
259
  unverifiedContext: metadata
231
260
  });
232
- return assembleResults(this.terms, encrypted);
261
+ return assembleResults(this.terms.length, encrypted, nonNullTerms);
233
262
  },
234
263
  (error) => {
235
264
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -252,6 +281,9 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
252
281
  this.lockContext = lockContext;
253
282
  this.auditMetadata = auditMetadata;
254
283
  }
284
+ client;
285
+ terms;
286
+ lockContext;
255
287
  async execute() {
256
288
  const log = createRequestLogger();
257
289
  log.set({
@@ -263,6 +295,11 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
263
295
  log.emit();
264
296
  return { data: [] };
265
297
  }
298
+ const { nonNullTerms } = filterNullTerms(this.terms);
299
+ if (nonNullTerms.length === 0) {
300
+ log.emit();
301
+ return { data: this.terms.map(() => null) };
302
+ }
266
303
  const lockContextResult = await this.lockContext.getLockContext();
267
304
  if (lockContextResult.failure) {
268
305
  log.emit();
@@ -273,15 +310,15 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
273
310
  async () => {
274
311
  if (!this.client) throw noClientError();
275
312
  const { metadata } = this.getAuditData();
276
- const queries = this.terms.map(
277
- (term) => buildQueryPayload(term, context)
313
+ const queries = nonNullTerms.map(
314
+ ({ term }) => buildQueryPayload(term, context)
278
315
  );
279
316
  const encrypted = await ffiEncryptQueryBulk(this.client, {
280
317
  queries,
281
318
  serviceToken: ctsToken,
282
319
  unverifiedContext: metadata
283
320
  });
284
- return assembleResults(this.terms, encrypted);
321
+ return assembleResults(this.terms.length, encrypted, nonNullTerms);
285
322
  },
286
323
  (error) => {
287
324
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -303,25 +340,30 @@ import {
303
340
  decryptBulkFallible
304
341
  } from "@cipherstash/protect-ffi";
305
342
  var createDecryptPayloads = (encryptedPayloads, lockContext) => {
306
- return encryptedPayloads.map(({ id, data }) => ({
343
+ return encryptedPayloads.filter(({ data }) => data !== null).map(({ id, data }) => ({
307
344
  id,
308
345
  ciphertext: data,
309
346
  ...lockContext && { lockContext }
310
347
  }));
311
348
  };
349
+ var createNullResult = (encryptedPayloads) => encryptedPayloads.map(({ id }) => ({ id, data: null }));
312
350
  var mapDecryptedDataToResult = (encryptedPayloads, decryptedData) => {
313
- return decryptedData.map((decryptResult, i) => {
314
- if ("error" in decryptResult) {
315
- return {
316
- id: encryptedPayloads[i].id,
317
- error: decryptResult.error
318
- };
351
+ const result = new Array(encryptedPayloads.length);
352
+ let decryptedIndex = 0;
353
+ for (let i = 0; i < encryptedPayloads.length; i++) {
354
+ if (encryptedPayloads[i].data === null) {
355
+ result[i] = { id: encryptedPayloads[i].id, data: null };
356
+ } else {
357
+ const decryptResult = decryptedData[decryptedIndex];
358
+ if ("error" in decryptResult) {
359
+ result[i] = { id: encryptedPayloads[i].id, error: decryptResult.error };
360
+ } else {
361
+ result[i] = { id: encryptedPayloads[i].id, data: decryptResult.data };
362
+ }
363
+ decryptedIndex++;
319
364
  }
320
- return {
321
- id: encryptedPayloads[i].id,
322
- data: decryptResult.data
323
- };
324
- });
365
+ }
366
+ return result;
325
367
  };
326
368
  var BulkDecryptOperation = class extends EncryptionOperation {
327
369
  client;
@@ -346,10 +388,13 @@ var BulkDecryptOperation = class extends EncryptionOperation {
346
388
  if (!this.client) throw noClientError();
347
389
  if (!this.encryptedPayloads || this.encryptedPayloads.length === 0)
348
390
  return [];
349
- const payloads = createDecryptPayloads(this.encryptedPayloads);
391
+ const nonNullPayloads = createDecryptPayloads(this.encryptedPayloads);
392
+ if (nonNullPayloads.length === 0) {
393
+ return createNullResult(this.encryptedPayloads);
394
+ }
350
395
  const { metadata } = this.getAuditData();
351
396
  const decryptedData = await decryptBulkFallible(this.client, {
352
- ciphertexts: payloads,
397
+ ciphertexts: nonNullPayloads,
353
398
  unverifiedContext: metadata
354
399
  });
355
400
  return mapDecryptedDataToResult(this.encryptedPayloads, decryptedData);
@@ -401,13 +446,16 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
401
446
  if (context.failure) {
402
447
  throw new Error(`[encryption]: ${context.failure.message}`);
403
448
  }
404
- const payloads = createDecryptPayloads(
449
+ const nonNullPayloads = createDecryptPayloads(
405
450
  encryptedPayloads,
406
451
  context.data.context
407
452
  );
453
+ if (nonNullPayloads.length === 0) {
454
+ return createNullResult(encryptedPayloads);
455
+ }
408
456
  const { metadata } = this.getAuditData();
409
457
  const decryptedData = await decryptBulkFallible(client, {
410
- ciphertexts: payloads,
458
+ ciphertexts: nonNullPayloads,
411
459
  serviceToken: context.data.ctsToken,
412
460
  unverifiedContext: metadata
413
461
  });
@@ -1049,7 +1097,7 @@ var BulkDecryptModelsOperationWithLockContext = class extends EncryptionOperatio
1049
1097
  import { withResult as withResult4 } from "@byteslice/result";
1050
1098
  import { encryptBulk as encryptBulk2 } from "@cipherstash/protect-ffi";
1051
1099
  var createEncryptPayloads = (plaintexts, column, table, lockContext) => {
1052
- return plaintexts.map(({ id, plaintext }) => ({
1100
+ return plaintexts.filter(({ plaintext }) => plaintext !== null).map(({ id, plaintext }) => ({
1053
1101
  id,
1054
1102
  plaintext,
1055
1103
  column: column.getName(),
@@ -1057,6 +1105,20 @@ var createEncryptPayloads = (plaintexts, column, table, lockContext) => {
1057
1105
  ...lockContext && { lockContext }
1058
1106
  }));
1059
1107
  };
1108
+ var createNullResult2 = (plaintexts) => plaintexts.map(({ id }) => ({ id, data: null }));
1109
+ var mapEncryptedDataToResult = (plaintexts, encryptedData) => {
1110
+ const result = new Array(plaintexts.length);
1111
+ let encryptedIndex = 0;
1112
+ for (let i = 0; i < plaintexts.length; i++) {
1113
+ if (plaintexts[i].plaintext === null) {
1114
+ result[i] = { id: plaintexts[i].id, data: null };
1115
+ } else {
1116
+ result[i] = { id: plaintexts[i].id, data: encryptedData[encryptedIndex] };
1117
+ encryptedIndex++;
1118
+ }
1119
+ }
1120
+ return result;
1121
+ };
1060
1122
  var BulkEncryptOperation = class extends EncryptionOperation {
1061
1123
  client;
1062
1124
  plaintexts;
@@ -1089,20 +1151,20 @@ var BulkEncryptOperation = class extends EncryptionOperation {
1089
1151
  if (!this.plaintexts || this.plaintexts.length === 0) {
1090
1152
  return [];
1091
1153
  }
1092
- const payloads = createEncryptPayloads(
1154
+ const nonNullPayloads = createEncryptPayloads(
1093
1155
  this.plaintexts,
1094
1156
  this.column,
1095
1157
  this.table
1096
1158
  );
1159
+ if (nonNullPayloads.length === 0) {
1160
+ return createNullResult2(this.plaintexts);
1161
+ }
1097
1162
  const { metadata } = this.getAuditData();
1098
1163
  const encryptedData = await encryptBulk2(this.client, {
1099
- plaintexts: payloads,
1164
+ plaintexts: nonNullPayloads,
1100
1165
  unverifiedContext: metadata
1101
1166
  });
1102
- return encryptedData.map((data, i) => ({
1103
- id: this.plaintexts[i].id,
1104
- data
1105
- }));
1167
+ return mapEncryptedDataToResult(this.plaintexts, encryptedData);
1106
1168
  },
1107
1169
  (error) => {
1108
1170
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -1159,22 +1221,22 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1159
1221
  if (context.failure) {
1160
1222
  throw new Error(`[encryption]: ${context.failure.message}`);
1161
1223
  }
1162
- const payloads = createEncryptPayloads(
1224
+ const nonNullPayloads = createEncryptPayloads(
1163
1225
  plaintexts,
1164
1226
  column,
1165
1227
  table,
1166
1228
  context.data.context
1167
1229
  );
1230
+ if (nonNullPayloads.length === 0) {
1231
+ return createNullResult2(plaintexts);
1232
+ }
1168
1233
  const { metadata } = this.getAuditData();
1169
1234
  const encryptedData = await encryptBulk2(client, {
1170
- plaintexts: payloads,
1235
+ plaintexts: nonNullPayloads,
1171
1236
  serviceToken: context.data.ctsToken,
1172
1237
  unverifiedContext: metadata
1173
1238
  });
1174
- return encryptedData.map((data, i) => ({
1175
- id: plaintexts[i].id,
1176
- data
1177
- }));
1239
+ return mapEncryptedDataToResult(plaintexts, encryptedData);
1178
1240
  },
1179
1241
  (error) => {
1180
1242
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -1306,6 +1368,10 @@ import {
1306
1368
  } from "@cipherstash/protect-ffi";
1307
1369
  var DecryptOperation = class extends EncryptionOperation {
1308
1370
  client;
1371
+ // Internally widened to allow null so the runtime guard below can
1372
+ // short-circuit on legacy / manually-NULLed rows. The public
1373
+ // `Encryption.decrypt()` signature still rejects null at the type
1374
+ // layer; this is defense in depth for direct construction.
1309
1375
  encryptedData;
1310
1376
  constructor(client, encryptedData) {
1311
1377
  super();
@@ -1326,6 +1392,9 @@ var DecryptOperation = class extends EncryptionOperation {
1326
1392
  if (!this.client) {
1327
1393
  throw noClientError();
1328
1394
  }
1395
+ if (this.encryptedData === null) {
1396
+ return null;
1397
+ }
1329
1398
  const { metadata } = this.getAuditData();
1330
1399
  return await ffiDecrypt(this.client, {
1331
1400
  ciphertext: this.encryptedData,
@@ -1376,6 +1445,9 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
1376
1445
  if (!client) {
1377
1446
  throw noClientError();
1378
1447
  }
1448
+ if (encryptedData === null) {
1449
+ return null;
1450
+ }
1379
1451
  const { metadata } = this.getAuditData();
1380
1452
  const context = await this.lockContext.getLockContext();
1381
1453
  if (context.failure) {
@@ -1505,6 +1577,10 @@ import {
1505
1577
  } from "@cipherstash/protect-ffi";
1506
1578
  var EncryptOperation = class extends EncryptionOperation {
1507
1579
  client;
1580
+ // Internally widened to allow null so the runtime guard below can
1581
+ // short-circuit. The public `Encryption.encrypt()` signature still
1582
+ // rejects null at the type layer; this is defense in depth for callers
1583
+ // that reach this class through casts or dynamic field walking.
1508
1584
  plaintext;
1509
1585
  column;
1510
1586
  table;
@@ -1531,6 +1607,9 @@ var EncryptOperation = class extends EncryptionOperation {
1531
1607
  if (!this.client) {
1532
1608
  throw noClientError();
1533
1609
  }
1610
+ if (this.plaintext === null) {
1611
+ return null;
1612
+ }
1534
1613
  if (typeof this.plaintext === "number" && Number.isNaN(this.plaintext)) {
1535
1614
  throw new Error("[encryption]: Cannot encrypt NaN value");
1536
1615
  }
@@ -1592,6 +1671,9 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
1592
1671
  if (!client) {
1593
1672
  throw noClientError();
1594
1673
  }
1674
+ if (plaintext === null) {
1675
+ return null;
1676
+ }
1595
1677
  const { metadata } = this.getAuditData();
1596
1678
  const context = await this.lockContext.getLockContext();
1597
1679
  if (context.failure) {
@@ -1739,6 +1821,9 @@ var EncryptQueryOperation = class extends EncryptionOperation {
1739
1821
  this.plaintext = plaintext;
1740
1822
  this.opts = opts;
1741
1823
  }
1824
+ client;
1825
+ plaintext;
1826
+ opts;
1742
1827
  withLockContext(lockContext) {
1743
1828
  return new EncryptQueryOperationWithLockContext(
1744
1829
  this.client,
@@ -1757,7 +1842,12 @@ var EncryptQueryOperation = class extends EncryptionOperation {
1757
1842
  queryType: this.opts.queryType,
1758
1843
  lockContext: false
1759
1844
  });
1760
- const validationError = validateNumericValue(this.plaintext);
1845
+ if (this.plaintext === null || this.plaintext === void 0) {
1846
+ log.emit();
1847
+ return { data: null };
1848
+ }
1849
+ const plaintext = this.plaintext;
1850
+ const validationError = validateNumericValue(plaintext);
1761
1851
  if (validationError?.failure) {
1762
1852
  log.emit();
1763
1853
  return { failure: validationError.failure };
@@ -1769,15 +1859,15 @@ var EncryptQueryOperation = class extends EncryptionOperation {
1769
1859
  const { indexType, queryOp } = resolveIndexType(
1770
1860
  this.opts.column,
1771
1861
  this.opts.queryType,
1772
- this.plaintext
1862
+ plaintext
1773
1863
  );
1774
1864
  assertValueIndexCompatibility(
1775
- this.plaintext,
1865
+ plaintext,
1776
1866
  indexType,
1777
1867
  this.opts.column.getName()
1778
1868
  );
1779
1869
  const encrypted = await ffiEncryptQuery(this.client, {
1780
- plaintext: this.plaintext,
1870
+ plaintext,
1781
1871
  column: this.opts.column.getName(),
1782
1872
  table: this.opts.table.tableName,
1783
1873
  indexType,
@@ -1811,6 +1901,10 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
1811
1901
  this.lockContext = lockContext;
1812
1902
  this.auditMetadata = auditMetadata;
1813
1903
  }
1904
+ client;
1905
+ plaintext;
1906
+ opts;
1907
+ lockContext;
1814
1908
  async execute() {
1815
1909
  const log = createRequestLogger();
1816
1910
  log.set({
@@ -1820,7 +1914,12 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
1820
1914
  queryType: this.opts.queryType,
1821
1915
  lockContext: true
1822
1916
  });
1823
- const validationError = validateNumericValue(this.plaintext);
1917
+ if (this.plaintext === null || this.plaintext === void 0) {
1918
+ log.emit();
1919
+ return { data: null };
1920
+ }
1921
+ const plaintext = this.plaintext;
1922
+ const validationError = validateNumericValue(plaintext);
1824
1923
  if (validationError?.failure) {
1825
1924
  log.emit();
1826
1925
  return { failure: validationError.failure };
@@ -1838,15 +1937,15 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
1838
1937
  const { indexType, queryOp } = resolveIndexType(
1839
1938
  this.opts.column,
1840
1939
  this.opts.queryType,
1841
- this.plaintext
1940
+ plaintext
1842
1941
  );
1843
1942
  assertValueIndexCompatibility(
1844
- this.plaintext,
1943
+ plaintext,
1845
1944
  indexType,
1846
1945
  this.opts.column.getName()
1847
1946
  );
1848
1947
  const encrypted = await ffiEncryptQuery(this.client, {
1849
- plaintext: this.plaintext,
1948
+ plaintext,
1850
1949
  column: this.opts.column.getName(),
1851
1950
  table: this.opts.table.tableName,
1852
1951
  indexType,
@@ -2042,6 +2141,13 @@ var EncryptionClient = class {
2042
2141
  * .withLockContext(lockContext)
2043
2142
  * ```
2044
2143
  *
2144
+ * @remarks
2145
+ * The public input type rejects null, but at runtime `decrypt` will
2146
+ * short-circuit and return null when given a null ciphertext
2147
+ * (defense in depth for legacy / manually-NULLed DB rows reached via
2148
+ * casts or dynamic field walking). The narrow return type holds for
2149
+ * any caller that respects the input contract.
2150
+ *
2045
2151
  * @see {@link LockContext}
2046
2152
  * @see {@link DecryptOperation}
2047
2153
  */
@@ -2303,7 +2409,7 @@ var Encryption = async (config) => {
2303
2409
  "[encryption]: At least one encryptedTable must be provided to initialize the encryption client"
2304
2410
  );
2305
2411
  }
2306
- if (clientConfig?.keyset && "id" in clientConfig.keyset && !uuidValidate(clientConfig.keyset.id)) {
2412
+ if (clientConfig?.keyset && "id" in clientConfig.keyset && !validate_default(clientConfig.keyset.id)) {
2307
2413
  throw new Error(
2308
2414
  "[encryption]: Invalid UUID provided for keyset id. Must be a valid UUID."
2309
2415
  );
@@ -2321,8 +2427,18 @@ var Encryption = async (config) => {
2321
2427
  };
2322
2428
 
2323
2429
  export {
2430
+ BatchEncryptQueryOperation,
2431
+ BulkDecryptOperation,
2432
+ BulkDecryptModelsOperation,
2433
+ BulkEncryptOperation,
2434
+ BulkEncryptModelsOperation,
2435
+ DecryptOperation,
2436
+ DecryptModelOperation,
2437
+ EncryptOperation,
2438
+ EncryptModelOperation,
2439
+ EncryptQueryOperation,
2324
2440
  noClientError,
2325
2441
  EncryptionClient,
2326
2442
  Encryption
2327
2443
  };
2328
- //# sourceMappingURL=chunk-46S3YFRK.js.map
2444
+ //# sourceMappingURL=chunk-ZYOZHZMJ.js.map