@cipherstash/stack 0.18.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 (101) hide show
  1. package/CHANGELOG.md +173 -0
  2. package/README.md +2 -2
  3. package/dist/{chunk-ZYOZHZMJ.js → chunk-36AA7IBJ.js} +151 -160
  4. package/dist/chunk-36AA7IBJ.js.map +1 -0
  5. package/dist/{chunk-VPOTNP4K.js → chunk-4AVL4VZD.js} +1 -1
  6. package/dist/chunk-4AVL4VZD.js.map +1 -0
  7. package/dist/{chunk-XWPGAHBZ.js → chunk-BNO32ZMV.js} +1 -1
  8. package/dist/chunk-BNO32ZMV.js.map +1 -0
  9. package/dist/{chunk-LLCCNKDL.js → chunk-HQANMV7R.js} +3 -3
  10. package/dist/{chunk-LLCCNKDL.js.map → chunk-HQANMV7R.js.map} +1 -1
  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-Dt98Rugc.d.cts → client-DSGHBN-g.d.cts} +200 -58
  26. package/dist/{client-CIsfZ2zg.d.ts → client-DfCrlHXh.d.ts} +200 -58
  27. package/dist/client.cjs +4101 -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 +4133 -74
  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 +35 -30
  37. package/dist/drizzle/index.js.map +1 -1
  38. package/dist/dynamodb/index.cjs +19 -12
  39. package/dist/dynamodb/index.cjs.map +1 -1
  40. package/dist/dynamodb/index.d.cts +2 -2
  41. package/dist/dynamodb/index.d.ts +2 -2
  42. package/dist/dynamodb/index.js +8 -10
  43. package/dist/dynamodb/index.js.map +1 -1
  44. package/dist/encryption/index.cjs +4448 -212
  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 +15 -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 +4480 -228
  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 +4105 -43
  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-BTxqjmtv.d.ts → types-public-CpS5KjwX.d.cts} +250 -92
  88. package/dist/{types-public-BTxqjmtv.d.cts → types-public-CpS5KjwX.d.ts} +250 -92
  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 +54 -4
  97. package/dist/chunk-VPOTNP4K.js.map +0 -1
  98. package/dist/chunk-XWPGAHBZ.js.map +0 -1
  99. package/dist/chunk-YWQXTZ5M.js +0 -383
  100. package/dist/chunk-YWQXTZ5M.js.map +0 -1
  101. package/dist/chunk-ZYOZHZMJ.js.map +0 -1
@@ -1,26 +1,31 @@
1
+ import {
2
+ resolveLockContext
3
+ } from "./chunk-OFQ555AX.js";
1
4
  import {
2
5
  formatEncryptedResult,
3
6
  isEncryptedPayload,
4
7
  toFfiKeysetIdentifier
5
- } from "./chunk-XWPGAHBZ.js";
8
+ } from "./chunk-BNO32ZMV.js";
6
9
  import {
7
10
  buildEncryptConfig,
8
11
  encryptConfigSchema
9
- } from "./chunk-YWQXTZ5M.js";
12
+ } from "./chunk-MP3SSDNN.js";
10
13
  import {
11
14
  queryTypeToFfi,
12
15
  queryTypeToQueryOp
13
- } from "./chunk-VPOTNP4K.js";
16
+ } from "./chunk-4AVL4VZD.js";
17
+ import {
18
+ withResult
19
+ } from "./chunk-JSG2AMDI.js";
14
20
  import {
15
21
  createRequestLogger,
16
22
  logger
17
- } from "./chunk-LLCCNKDL.js";
23
+ } from "./chunk-HQANMV7R.js";
18
24
  import {
19
25
  EncryptionErrorTypes
20
26
  } from "./chunk-LBMC4D6D.js";
21
27
 
22
28
  // src/encryption/index.ts
23
- import { withResult as withResult11 } from "@byteslice/result";
24
29
  import { newClient } from "@cipherstash/protect-ffi";
25
30
 
26
31
  // ../../node_modules/.pnpm/uuid@14.0.0/node_modules/uuid/dist-node/regex.js
@@ -37,6 +42,11 @@ function isScalarQueryTermArray(value) {
37
42
  return Array.isArray(value) && value.length > 0 && typeof value[0] === "object" && value[0] !== null && "column" in value[0] && "table" in value[0];
38
43
  }
39
44
 
45
+ // src/encryption/operations/batch-encrypt-query.ts
46
+ import {
47
+ encryptQueryBulk as ffiEncryptQueryBulk
48
+ } from "@cipherstash/protect-ffi";
49
+
40
50
  // src/encryption/helpers/error-code.ts
41
51
  import {
42
52
  ProtectError as FfiProtectError
@@ -45,12 +55,6 @@ function getErrorCode(error) {
45
55
  return error instanceof FfiProtectError ? error.code : void 0;
46
56
  }
47
57
 
48
- // src/encryption/operations/batch-encrypt-query.ts
49
- import { withResult } from "@byteslice/result";
50
- import {
51
- encryptQueryBulk as ffiEncryptQueryBulk
52
- } from "@cipherstash/protect-ffi";
53
-
54
58
  // src/encryption/helpers/infer-index-type.ts
55
59
  function inferIndexType(column) {
56
60
  const config = column.build();
@@ -70,7 +74,7 @@ function inferQueryOpFromPlaintext(plaintext) {
70
74
  if (typeof plaintext === "string") {
71
75
  return "ste_vec_selector";
72
76
  }
73
- if (typeof plaintext === "object" || typeof plaintext === "number" || typeof plaintext === "boolean" || typeof plaintext === "bigint") {
77
+ if (typeof plaintext === "object" || typeof plaintext === "number" || typeof plaintext === "boolean") {
74
78
  return "ste_vec_term";
75
79
  }
76
80
  return "ste_vec_term";
@@ -90,9 +94,18 @@ function validateIndexType(column, indexType) {
90
94
  );
91
95
  }
92
96
  }
97
+ function resolvesEqualityViaOre(column) {
98
+ if (!("getQueryCapabilities" in column)) return false;
99
+ if (!column.getQueryCapabilities().equality) return false;
100
+ const indexes = column.build().indexes ?? {};
101
+ return !indexes.unique && !!indexes.ore;
102
+ }
93
103
  function resolveIndexType(column, queryType, plaintext) {
94
104
  const indexType = queryType ? queryTypeToFfi[queryType] : inferIndexType(column);
95
105
  if (queryType) {
106
+ if (queryType === "equality" && resolvesEqualityViaOre(column)) {
107
+ return { indexType: "ore" };
108
+ }
96
109
  validateIndexType(column, indexType);
97
110
  if (queryType === "searchableJson") {
98
111
  if (plaintext === void 0 || plaintext === null) {
@@ -300,22 +313,16 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
300
313
  log.emit();
301
314
  return { data: this.terms.map(() => null) };
302
315
  }
303
- const lockContextResult = await this.lockContext.getLockContext();
304
- if (lockContextResult.failure) {
305
- log.emit();
306
- return { failure: lockContextResult.failure };
307
- }
308
- const { ctsToken, context } = lockContextResult.data;
309
316
  const result = await withResult(
310
317
  async () => {
311
318
  if (!this.client) throw noClientError();
319
+ const context = resolveLockContext(this.lockContext);
312
320
  const { metadata } = this.getAuditData();
313
321
  const queries = nonNullTerms.map(
314
322
  ({ term }) => buildQueryPayload(term, context)
315
323
  );
316
324
  const encrypted = await ffiEncryptQueryBulk(this.client, {
317
325
  queries,
318
- serviceToken: ctsToken,
319
326
  unverifiedContext: metadata
320
327
  });
321
328
  return assembleResults(this.terms.length, encrypted, nonNullTerms);
@@ -335,7 +342,6 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
335
342
  };
336
343
 
337
344
  // src/encryption/operations/bulk-decrypt.ts
338
- import { withResult as withResult2 } from "@byteslice/result";
339
345
  import {
340
346
  decryptBulkFallible
341
347
  } from "@cipherstash/protect-ffi";
@@ -383,7 +389,7 @@ var BulkDecryptOperation = class extends EncryptionOperation {
383
389
  count: this.encryptedPayloads?.length ?? 0,
384
390
  lockContext: false
385
391
  });
386
- const result = await withResult2(
392
+ const result = await withResult(
387
393
  async () => {
388
394
  if (!this.client) throw noClientError();
389
395
  if (!this.encryptedPayloads || this.encryptedPayloads.length === 0)
@@ -438,17 +444,14 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
438
444
  count: encryptedPayloads?.length ?? 0,
439
445
  lockContext: true
440
446
  });
441
- const result = await withResult2(
447
+ const result = await withResult(
442
448
  async () => {
443
449
  if (!client) throw noClientError();
444
450
  if (!encryptedPayloads || encryptedPayloads.length === 0) return [];
445
- const context = await this.lockContext.getLockContext();
446
- if (context.failure) {
447
- throw new Error(`[encryption]: ${context.failure.message}`);
448
- }
451
+ const lockContext = resolveLockContext(this.lockContext);
449
452
  const nonNullPayloads = createDecryptPayloads(
450
453
  encryptedPayloads,
451
- context.data.context
454
+ lockContext
452
455
  );
453
456
  if (nonNullPayloads.length === 0) {
454
457
  return createNullResult(encryptedPayloads);
@@ -456,7 +459,6 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
456
459
  const { metadata } = this.getAuditData();
457
460
  const decryptedData = await decryptBulkFallible(client, {
458
461
  ciphertexts: nonNullPayloads,
459
- serviceToken: context.data.ctsToken,
460
462
  unverifiedContext: metadata
461
463
  });
462
464
  return mapDecryptedDataToResult(encryptedPayloads, decryptedData);
@@ -475,9 +477,6 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
475
477
  }
476
478
  };
477
479
 
478
- // src/encryption/operations/bulk-decrypt-models.ts
479
- import { withResult as withResult3 } from "@byteslice/result";
480
-
481
480
  // src/encryption/helpers/model-helpers.ts
482
481
  import {
483
482
  decryptBulk,
@@ -559,6 +558,17 @@ function prepareFieldsForDecryption(model) {
559
558
  processNestedFields(model);
560
559
  return { otherFields, operationFields, keyMap, nullFields };
561
560
  }
561
+ function resolveEncryptColumnMap(table) {
562
+ const keyMap = table.buildColumnKeyMap?.();
563
+ if (keyMap) {
564
+ return {
565
+ columnPaths: Object.keys(keyMap),
566
+ toColumnName: (path) => keyMap[path] ?? path
567
+ };
568
+ }
569
+ const columnPaths = Object.keys(table.build().columns);
570
+ return { columnPaths, toColumnName: (path) => path };
571
+ }
562
572
  function prepareFieldsForEncryption(model, table) {
563
573
  const otherFields = { ...model };
564
574
  const operationFields = {};
@@ -594,7 +604,7 @@ function prepareFieldsForEncryption(model, table) {
594
604
  }
595
605
  }
596
606
  };
597
- const columnPaths = Object.keys(table.build().columns);
607
+ const { columnPaths } = resolveEncryptColumnMap(table);
598
608
  processNestedFields(model, "", columnPaths);
599
609
  return { otherFields, operationFields, keyMap, nullFields };
600
610
  }
@@ -633,12 +643,13 @@ async function encryptModelFields(model, table, client, auditData) {
633
643
  throw new Error("Client not initialized");
634
644
  }
635
645
  const { otherFields, operationFields, keyMap, nullFields } = prepareFieldsForEncryption(model, table);
646
+ const { toColumnName } = resolveEncryptColumnMap(table);
636
647
  const bulkEncryptPayload = Object.entries(operationFields).map(
637
648
  ([key, value]) => ({
638
649
  id: key,
639
650
  plaintext: value,
640
651
  table: table.tableName,
641
- column: key
652
+ column: toColumnName(key)
642
653
  })
643
654
  );
644
655
  const encryptedData = await handleSingleModelBulkOperation(
@@ -672,14 +683,13 @@ async function decryptModelFieldsWithLockContext(model, client, lockContext, aud
672
683
  ([key, value]) => ({
673
684
  id: key,
674
685
  ciphertext: value,
675
- lockContext: lockContext.context
686
+ lockContext
676
687
  })
677
688
  );
678
689
  const decryptedFields = await handleSingleModelBulkOperation(
679
690
  bulkDecryptPayload,
680
691
  (items) => decryptBulk(client, {
681
692
  ciphertexts: items,
682
- serviceToken: lockContext.ctsToken,
683
693
  unverifiedContext: auditData?.metadata
684
694
  }),
685
695
  keyMap
@@ -703,20 +713,20 @@ async function encryptModelFieldsWithLockContext(model, table, client, lockConte
703
713
  throw new Error("Lock context is not initialized");
704
714
  }
705
715
  const { otherFields, operationFields, keyMap, nullFields } = prepareFieldsForEncryption(model, table);
716
+ const { toColumnName } = resolveEncryptColumnMap(table);
706
717
  const bulkEncryptPayload = Object.entries(operationFields).map(
707
718
  ([key, value]) => ({
708
719
  id: key,
709
720
  plaintext: value,
710
721
  table: table.tableName,
711
- column: key,
712
- lockContext: lockContext.context
722
+ column: toColumnName(key),
723
+ lockContext
713
724
  })
714
725
  );
715
726
  const encryptedData = await handleSingleModelBulkOperation(
716
727
  bulkEncryptPayload,
717
728
  (items) => encryptBulk(client, {
718
729
  plaintexts: items,
719
- serviceToken: lockContext.ctsToken,
720
730
  unverifiedContext: auditData?.metadata
721
731
  }),
722
732
  keyMap
@@ -773,7 +783,7 @@ function prepareBulkModelsForOperation(models, table) {
773
783
  }
774
784
  };
775
785
  if (table) {
776
- const columnPaths = Object.keys(table.build().columns);
786
+ const { columnPaths } = resolveEncryptColumnMap(table);
777
787
  processNestedFields(model, "", columnPaths);
778
788
  } else {
779
789
  const processEncryptedFields = (obj, prefix = "", columnPaths = []) => {
@@ -811,6 +821,15 @@ function prepareBulkModelsForOperation(models, table) {
811
821
  }
812
822
  return { otherFields, operationFields, keyMap, nullFields };
813
823
  }
824
+ function fieldsForModelIndex(fields, modelIndex) {
825
+ const result = {};
826
+ for (const [id, value] of Object.entries(fields)) {
827
+ const sep = id.indexOf("-");
828
+ if (Number.parseInt(id.slice(0, sep), 10) !== modelIndex) continue;
829
+ result[id.slice(sep + 1)] = value;
830
+ }
831
+ return result;
832
+ }
814
833
  async function bulkEncryptModels(models, table, client, auditData) {
815
834
  if (!client) {
816
835
  throw new Error("Client not initialized");
@@ -819,12 +838,13 @@ async function bulkEncryptModels(models, table, client, auditData) {
819
838
  return [];
820
839
  }
821
840
  const { otherFields, operationFields, keyMap, nullFields } = prepareBulkModelsForOperation(models, table);
841
+ const { toColumnName } = resolveEncryptColumnMap(table);
822
842
  const bulkEncryptPayload = operationFields.flatMap(
823
843
  (fields, modelIndex) => Object.entries(fields).map(([key, value]) => ({
824
844
  id: `${modelIndex}-${key}`,
825
845
  plaintext: value,
826
846
  table: table.tableName,
827
- column: key
847
+ column: toColumnName(key)
828
848
  }))
829
849
  );
830
850
  const encryptedData = await handleMultiModelBulkOperation(
@@ -841,15 +861,7 @@ async function bulkEncryptModels(models, table, client, auditData) {
841
861
  const parts = key.split(".");
842
862
  setNestedValue(result, parts, value);
843
863
  }
844
- const modelData = Object.fromEntries(
845
- Object.entries(encryptedData).filter(([key]) => {
846
- const [idx] = key.split("-");
847
- return Number.parseInt(idx) === modelIndex;
848
- }).map(([key, value]) => {
849
- const [_2, fieldKey] = key.split("-");
850
- return [fieldKey, value];
851
- })
852
- );
864
+ const modelData = fieldsForModelIndex(encryptedData, modelIndex);
853
865
  for (const [key, value] of Object.entries(modelData)) {
854
866
  const parts = key.split(".");
855
867
  setNestedValue(result, parts, value);
@@ -885,15 +897,7 @@ async function bulkDecryptModels(models, client, auditData) {
885
897
  const parts = key.split(".");
886
898
  setNestedValue(result, parts, value);
887
899
  }
888
- const modelData = Object.fromEntries(
889
- Object.entries(decryptedFields).filter(([key]) => {
890
- const [idx] = key.split("-");
891
- return Number.parseInt(idx) === modelIndex;
892
- }).map(([key, value]) => {
893
- const [_2, fieldKey] = key.split("-");
894
- return [fieldKey, value];
895
- })
896
- );
900
+ const modelData = fieldsForModelIndex(decryptedFields, modelIndex);
897
901
  for (const [key, value] of Object.entries(modelData)) {
898
902
  const parts = key.split(".");
899
903
  setNestedValue(result, parts, value);
@@ -913,14 +917,13 @@ async function bulkDecryptModelsWithLockContext(models, client, lockContext, aud
913
917
  (fields, modelIndex) => Object.entries(fields).map(([key, value]) => ({
914
918
  id: `${modelIndex}-${key}`,
915
919
  ciphertext: value,
916
- lockContext: lockContext.context
920
+ lockContext
917
921
  }))
918
922
  );
919
923
  const decryptedFields = await handleMultiModelBulkOperation(
920
924
  bulkDecryptPayload,
921
925
  (items) => decryptBulk(client, {
922
926
  ciphertexts: items,
923
- serviceToken: lockContext.ctsToken,
924
927
  unverifiedContext: auditData?.metadata
925
928
  }),
926
929
  keyMap
@@ -931,15 +934,7 @@ async function bulkDecryptModelsWithLockContext(models, client, lockContext, aud
931
934
  const parts = key.split(".");
932
935
  setNestedValue(result, parts, value);
933
936
  }
934
- const modelData = Object.fromEntries(
935
- Object.entries(decryptedFields).filter(([key]) => {
936
- const [idx] = key.split("-");
937
- return Number.parseInt(idx) === modelIndex;
938
- }).map(([key, value]) => {
939
- const [_2, fieldKey] = key.split("-");
940
- return [fieldKey, value];
941
- })
942
- );
937
+ const modelData = fieldsForModelIndex(decryptedFields, modelIndex);
943
938
  for (const [key, value] of Object.entries(modelData)) {
944
939
  const parts = key.split(".");
945
940
  setNestedValue(result, parts, value);
@@ -955,20 +950,20 @@ async function bulkEncryptModelsWithLockContext(models, table, client, lockConte
955
950
  throw new Error("Lock context is not initialized");
956
951
  }
957
952
  const { otherFields, operationFields, keyMap, nullFields } = prepareBulkModelsForOperation(models, table);
953
+ const { toColumnName } = resolveEncryptColumnMap(table);
958
954
  const bulkEncryptPayload = operationFields.flatMap(
959
955
  (fields, modelIndex) => Object.entries(fields).map(([key, value]) => ({
960
956
  id: `${modelIndex}-${key}`,
961
957
  plaintext: value,
962
958
  table: table.tableName,
963
- column: key,
964
- lockContext: lockContext.context
959
+ column: toColumnName(key),
960
+ lockContext
965
961
  }))
966
962
  );
967
963
  const encryptedData = await handleMultiModelBulkOperation(
968
964
  bulkEncryptPayload,
969
965
  (items) => encryptBulk(client, {
970
966
  plaintexts: items,
971
- serviceToken: lockContext.ctsToken,
972
967
  unverifiedContext: auditData?.metadata
973
968
  }),
974
969
  keyMap
@@ -979,15 +974,7 @@ async function bulkEncryptModelsWithLockContext(models, table, client, lockConte
979
974
  const parts = key.split(".");
980
975
  setNestedValue(result, parts, value);
981
976
  }
982
- const modelData = Object.fromEntries(
983
- Object.entries(encryptedData).filter(([key]) => {
984
- const [idx] = key.split("-");
985
- return Number.parseInt(idx) === modelIndex;
986
- }).map(([key, value]) => {
987
- const [_2, fieldKey] = key.split("-");
988
- return [fieldKey, value];
989
- })
990
- );
977
+ const modelData = fieldsForModelIndex(encryptedData, modelIndex);
991
978
  for (const [key, value] of Object.entries(modelData)) {
992
979
  const parts = key.split(".");
993
980
  setNestedValue(result, parts, value);
@@ -1015,7 +1002,7 @@ var BulkDecryptModelsOperation = class extends EncryptionOperation {
1015
1002
  count: this.models.length,
1016
1003
  lockContext: false
1017
1004
  });
1018
- const result = await withResult3(
1005
+ const result = await withResult(
1019
1006
  async () => {
1020
1007
  if (!this.client) {
1021
1008
  throw noClientError();
@@ -1062,20 +1049,17 @@ var BulkDecryptModelsOperationWithLockContext = class extends EncryptionOperatio
1062
1049
  count: models.length,
1063
1050
  lockContext: true
1064
1051
  });
1065
- const result = await withResult3(
1052
+ const result = await withResult(
1066
1053
  async () => {
1067
1054
  if (!client) {
1068
1055
  throw noClientError();
1069
1056
  }
1070
- const context = await this.lockContext.getLockContext();
1071
- if (context.failure) {
1072
- throw new Error(`[encryption]: ${context.failure.message}`);
1073
- }
1057
+ const context = resolveLockContext(this.lockContext);
1074
1058
  const auditData = this.getAuditData();
1075
1059
  return await bulkDecryptModelsWithLockContext(
1076
1060
  models,
1077
1061
  client,
1078
- context.data,
1062
+ context,
1079
1063
  auditData
1080
1064
  );
1081
1065
  },
@@ -1094,7 +1078,6 @@ var BulkDecryptModelsOperationWithLockContext = class extends EncryptionOperatio
1094
1078
  };
1095
1079
 
1096
1080
  // src/encryption/operations/bulk-encrypt.ts
1097
- import { withResult as withResult4 } from "@byteslice/result";
1098
1081
  import { encryptBulk as encryptBulk2 } from "@cipherstash/protect-ffi";
1099
1082
  var createEncryptPayloads = (plaintexts, column, table, lockContext) => {
1100
1083
  return plaintexts.filter(({ plaintext }) => plaintext !== null).map(({ id, plaintext }) => ({
@@ -1143,7 +1126,7 @@ var BulkEncryptOperation = class extends EncryptionOperation {
1143
1126
  count: this.plaintexts?.length ?? 0,
1144
1127
  lockContext: false
1145
1128
  });
1146
- const result = await withResult4(
1129
+ const result = await withResult(
1147
1130
  async () => {
1148
1131
  if (!this.client) {
1149
1132
  throw noClientError();
@@ -1209,7 +1192,7 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1209
1192
  count: plaintexts?.length ?? 0,
1210
1193
  lockContext: true
1211
1194
  });
1212
- const result = await withResult4(
1195
+ const result = await withResult(
1213
1196
  async () => {
1214
1197
  if (!client) {
1215
1198
  throw noClientError();
@@ -1217,15 +1200,12 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1217
1200
  if (!plaintexts || plaintexts.length === 0) {
1218
1201
  return [];
1219
1202
  }
1220
- const context = await this.lockContext.getLockContext();
1221
- if (context.failure) {
1222
- throw new Error(`[encryption]: ${context.failure.message}`);
1223
- }
1203
+ const lockContext = resolveLockContext(this.lockContext);
1224
1204
  const nonNullPayloads = createEncryptPayloads(
1225
1205
  plaintexts,
1226
1206
  column,
1227
1207
  table,
1228
- context.data.context
1208
+ lockContext
1229
1209
  );
1230
1210
  if (nonNullPayloads.length === 0) {
1231
1211
  return createNullResult2(plaintexts);
@@ -1233,7 +1213,6 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1233
1213
  const { metadata } = this.getAuditData();
1234
1214
  const encryptedData = await encryptBulk2(client, {
1235
1215
  plaintexts: nonNullPayloads,
1236
- serviceToken: context.data.ctsToken,
1237
1216
  unverifiedContext: metadata
1238
1217
  });
1239
1218
  return mapEncryptedDataToResult(plaintexts, encryptedData);
@@ -1253,7 +1232,6 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1253
1232
  };
1254
1233
 
1255
1234
  // src/encryption/operations/bulk-encrypt-models.ts
1256
- import { withResult as withResult5 } from "@byteslice/result";
1257
1235
  var BulkEncryptModelsOperation = class extends EncryptionOperation {
1258
1236
  client;
1259
1237
  models;
@@ -1275,7 +1253,7 @@ var BulkEncryptModelsOperation = class extends EncryptionOperation {
1275
1253
  count: this.models.length,
1276
1254
  lockContext: false
1277
1255
  });
1278
- const result = await withResult5(
1256
+ const result = await withResult(
1279
1257
  async () => {
1280
1258
  if (!this.client) {
1281
1259
  throw noClientError();
@@ -1329,21 +1307,18 @@ var BulkEncryptModelsOperationWithLockContext = class extends EncryptionOperatio
1329
1307
  count: models.length,
1330
1308
  lockContext: true
1331
1309
  });
1332
- const result = await withResult5(
1310
+ const result = await withResult(
1333
1311
  async () => {
1334
1312
  if (!client) {
1335
1313
  throw noClientError();
1336
1314
  }
1337
- const context = await this.lockContext.getLockContext();
1338
- if (context.failure) {
1339
- throw new Error(`[encryption]: ${context.failure.message}`);
1340
- }
1315
+ const context = resolveLockContext(this.lockContext);
1341
1316
  const auditData = this.getAuditData();
1342
1317
  return await bulkEncryptModelsWithLockContext(
1343
1318
  models,
1344
1319
  table,
1345
1320
  client,
1346
- context.data,
1321
+ context,
1347
1322
  auditData
1348
1323
  );
1349
1324
  },
@@ -1362,7 +1337,6 @@ var BulkEncryptModelsOperationWithLockContext = class extends EncryptionOperatio
1362
1337
  };
1363
1338
 
1364
1339
  // src/encryption/operations/decrypt.ts
1365
- import { withResult as withResult6 } from "@byteslice/result";
1366
1340
  import {
1367
1341
  decrypt as ffiDecrypt
1368
1342
  } from "@cipherstash/protect-ffi";
@@ -1387,7 +1361,7 @@ var DecryptOperation = class extends EncryptionOperation {
1387
1361
  op: "decrypt",
1388
1362
  lockContext: false
1389
1363
  });
1390
- const result = await withResult6(
1364
+ const result = await withResult(
1391
1365
  async () => {
1392
1366
  if (!this.client) {
1393
1367
  throw noClientError();
@@ -1439,7 +1413,7 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
1439
1413
  op: "decrypt",
1440
1414
  lockContext: true
1441
1415
  });
1442
- const result = await withResult6(
1416
+ const result = await withResult(
1443
1417
  async () => {
1444
1418
  const { client, encryptedData } = this.operation.getOperation();
1445
1419
  if (!client) {
@@ -1449,15 +1423,11 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
1449
1423
  return null;
1450
1424
  }
1451
1425
  const { metadata } = this.getAuditData();
1452
- const context = await this.lockContext.getLockContext();
1453
- if (context.failure) {
1454
- throw new Error(`[encryption]: ${context.failure.message}`);
1455
- }
1426
+ const lockContext = resolveLockContext(this.lockContext);
1456
1427
  return await ffiDecrypt(client, {
1457
1428
  ciphertext: encryptedData,
1458
1429
  unverifiedContext: metadata,
1459
- lockContext: context.data.context,
1460
- serviceToken: context.data.ctsToken
1430
+ lockContext
1461
1431
  });
1462
1432
  },
1463
1433
  (error) => {
@@ -1475,7 +1445,6 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
1475
1445
  };
1476
1446
 
1477
1447
  // src/encryption/operations/decrypt-model.ts
1478
- import { withResult as withResult7 } from "@byteslice/result";
1479
1448
  var DecryptModelOperation = class extends EncryptionOperation {
1480
1449
  client;
1481
1450
  model;
@@ -1493,7 +1462,7 @@ var DecryptModelOperation = class extends EncryptionOperation {
1493
1462
  op: "decryptModel",
1494
1463
  lockContext: false
1495
1464
  });
1496
- const result = await withResult7(
1465
+ const result = await withResult(
1497
1466
  async () => {
1498
1467
  if (!this.client) {
1499
1468
  throw noClientError();
@@ -1538,21 +1507,18 @@ var DecryptModelOperationWithLockContext = class extends EncryptionOperation {
1538
1507
  op: "decryptModel",
1539
1508
  lockContext: true
1540
1509
  });
1541
- const result = await withResult7(
1510
+ const result = await withResult(
1542
1511
  async () => {
1543
1512
  const { client, model } = this.operation.getOperation();
1544
1513
  if (!client) {
1545
1514
  throw noClientError();
1546
1515
  }
1547
- const context = await this.lockContext.getLockContext();
1548
- if (context.failure) {
1549
- throw new Error(`[encryption]: ${context.failure.message}`);
1550
- }
1516
+ const context = resolveLockContext(this.lockContext);
1551
1517
  const auditData = this.getAuditData();
1552
1518
  return await decryptModelFieldsWithLockContext(
1553
1519
  model,
1554
1520
  client,
1555
- context.data,
1521
+ context,
1556
1522
  auditData
1557
1523
  );
1558
1524
  },
@@ -1571,7 +1537,6 @@ var DecryptModelOperationWithLockContext = class extends EncryptionOperation {
1571
1537
  };
1572
1538
 
1573
1539
  // src/encryption/operations/encrypt.ts
1574
- import { withResult as withResult8 } from "@byteslice/result";
1575
1540
  import {
1576
1541
  encrypt as ffiEncrypt
1577
1542
  } from "@cipherstash/protect-ffi";
@@ -1602,7 +1567,7 @@ var EncryptOperation = class extends EncryptionOperation {
1602
1567
  column: this.column.getName(),
1603
1568
  lockContext: false
1604
1569
  });
1605
- const result = await withResult8(
1570
+ const result = await withResult(
1606
1571
  async () => {
1607
1572
  if (!this.client) {
1608
1573
  throw noClientError();
@@ -1610,14 +1575,12 @@ var EncryptOperation = class extends EncryptionOperation {
1610
1575
  if (this.plaintext === null) {
1611
1576
  return null;
1612
1577
  }
1613
- if (typeof this.plaintext === "number" && Number.isNaN(this.plaintext)) {
1614
- throw new Error("[encryption]: Cannot encrypt NaN value");
1615
- }
1616
- if (typeof this.plaintext === "number" && !Number.isFinite(this.plaintext)) {
1617
- throw new Error("[encryption]: Cannot encrypt Infinity value");
1618
- }
1578
+ assertValidNumericValue(this.plaintext);
1619
1579
  const { metadata } = this.getAuditData();
1620
1580
  return await ffiEncrypt(this.client, {
1581
+ // `Plaintext` widens the FFI `JsPlaintext` with `Date` (serialized via
1582
+ // `toJSON` at the boundary); cast until the upstream `JsPlaintext` input
1583
+ // union is corrected to include it.
1621
1584
  plaintext: this.plaintext,
1622
1585
  column: this.column.getName(),
1623
1586
  table: this.table.tableName,
@@ -1666,7 +1629,7 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
1666
1629
  column: column.getName(),
1667
1630
  lockContext: true
1668
1631
  });
1669
- const result = await withResult8(
1632
+ const result = await withResult(
1670
1633
  async () => {
1671
1634
  if (!client) {
1672
1635
  throw noClientError();
@@ -1674,17 +1637,14 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
1674
1637
  if (plaintext === null) {
1675
1638
  return null;
1676
1639
  }
1640
+ assertValidNumericValue(plaintext);
1677
1641
  const { metadata } = this.getAuditData();
1678
- const context = await this.lockContext.getLockContext();
1679
- if (context.failure) {
1680
- throw new Error(`[encryption]: ${context.failure.message}`);
1681
- }
1642
+ const lockContext = resolveLockContext(this.lockContext);
1682
1643
  return await ffiEncrypt(client, {
1683
1644
  plaintext,
1684
1645
  column: column.getName(),
1685
1646
  table: table.tableName,
1686
- lockContext: context.data.context,
1687
- serviceToken: context.data.ctsToken,
1647
+ lockContext,
1688
1648
  unverifiedContext: metadata
1689
1649
  });
1690
1650
  },
@@ -1703,7 +1663,6 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
1703
1663
  };
1704
1664
 
1705
1665
  // src/encryption/operations/encrypt-model.ts
1706
- import { withResult as withResult9 } from "@byteslice/result";
1707
1666
  var EncryptModelOperation = class extends EncryptionOperation {
1708
1667
  client;
1709
1668
  model;
@@ -1724,7 +1683,7 @@ var EncryptModelOperation = class extends EncryptionOperation {
1724
1683
  table: this.table.tableName,
1725
1684
  lockContext: false
1726
1685
  });
1727
- const result = await withResult9(
1686
+ const result = await withResult(
1728
1687
  async () => {
1729
1688
  if (!this.client) {
1730
1689
  throw noClientError();
@@ -1777,21 +1736,18 @@ var EncryptModelOperationWithLockContext = class extends EncryptionOperation {
1777
1736
  table: table.tableName,
1778
1737
  lockContext: true
1779
1738
  });
1780
- const result = await withResult9(
1739
+ const result = await withResult(
1781
1740
  async () => {
1782
1741
  if (!client) {
1783
1742
  throw noClientError();
1784
1743
  }
1785
- const context = await this.lockContext.getLockContext();
1786
- if (context.failure) {
1787
- throw new Error(`[encryption]: ${context.failure.message}`);
1788
- }
1744
+ const context = resolveLockContext(this.lockContext);
1789
1745
  const auditData = this.getAuditData();
1790
1746
  return await encryptModelFieldsWithLockContext(
1791
1747
  model,
1792
1748
  table,
1793
1749
  client,
1794
- context.data,
1750
+ context,
1795
1751
  auditData
1796
1752
  );
1797
1753
  },
@@ -1810,7 +1766,6 @@ var EncryptModelOperationWithLockContext = class extends EncryptionOperation {
1810
1766
  };
1811
1767
 
1812
1768
  // src/encryption/operations/encrypt-query.ts
1813
- import { withResult as withResult10 } from "@byteslice/result";
1814
1769
  import {
1815
1770
  encryptQuery as ffiEncryptQuery
1816
1771
  } from "@cipherstash/protect-ffi";
@@ -1852,7 +1807,7 @@ var EncryptQueryOperation = class extends EncryptionOperation {
1852
1807
  log.emit();
1853
1808
  return { failure: validationError.failure };
1854
1809
  }
1855
- const result = await withResult10(
1810
+ const result = await withResult(
1856
1811
  async () => {
1857
1812
  if (!this.client) throw noClientError();
1858
1813
  const { metadata } = this.getAuditData();
@@ -1867,6 +1822,9 @@ var EncryptQueryOperation = class extends EncryptionOperation {
1867
1822
  this.opts.column.getName()
1868
1823
  );
1869
1824
  const encrypted = await ffiEncryptQuery(this.client, {
1825
+ // `Plaintext` widens the FFI `JsPlaintext` with `Date` (serialized via
1826
+ // `toJSON` at the boundary); cast until the upstream input union is
1827
+ // corrected to include it.
1870
1828
  plaintext,
1871
1829
  column: this.opts.column.getName(),
1872
1830
  table: this.opts.table.tableName,
@@ -1924,15 +1882,10 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
1924
1882
  log.emit();
1925
1883
  return { failure: validationError.failure };
1926
1884
  }
1927
- const lockContextResult = await this.lockContext.getLockContext();
1928
- if (lockContextResult.failure) {
1929
- log.emit();
1930
- return { failure: lockContextResult.failure };
1931
- }
1932
- const { ctsToken, context } = lockContextResult.data;
1933
- const result = await withResult10(
1885
+ const result = await withResult(
1934
1886
  async () => {
1935
1887
  if (!this.client) throw noClientError();
1888
+ const context = resolveLockContext(this.lockContext);
1936
1889
  const { metadata } = this.getAuditData();
1937
1890
  const { indexType, queryOp } = resolveIndexType(
1938
1891
  this.opts.column,
@@ -1945,13 +1898,15 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
1945
1898
  this.opts.column.getName()
1946
1899
  );
1947
1900
  const encrypted = await ffiEncryptQuery(this.client, {
1901
+ // `Plaintext` widens the FFI `JsPlaintext` with `Date` (serialized via
1902
+ // `toJSON` at the boundary); cast until the upstream input union is
1903
+ // corrected to include it.
1948
1904
  plaintext,
1949
1905
  column: this.opts.column.getName(),
1950
1906
  table: this.opts.table.tableName,
1951
1907
  indexType,
1952
1908
  queryOp,
1953
1909
  lockContext: context,
1954
- serviceToken: ctsToken,
1955
1910
  unverifiedContext: metadata
1956
1911
  });
1957
1912
  return formatEncryptedResult(encrypted, this.opts.returnType);
@@ -1974,6 +1929,20 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
1974
1929
  var noClientError = () => new Error(
1975
1930
  "The Encryption client has not been initialized. Please call init() before using the client."
1976
1931
  );
1932
+ function resolveEqlVersion(schemas, explicit) {
1933
+ const v3Count = schemas.filter(
1934
+ (schema) => typeof schema.buildColumnKeyMap === "function"
1935
+ ).length;
1936
+ if (v3Count > 0 && v3Count < schemas.length) {
1937
+ throw new Error(
1938
+ "[encryption]: cannot mix EQL v2 and EQL v3 tables in one client \u2014 one client emits exactly one wire format. Create separate clients for the v2 and v3 schemas."
1939
+ );
1940
+ }
1941
+ if (explicit !== void 0) {
1942
+ return explicit;
1943
+ }
1944
+ return v3Count === 0 ? void 0 : 3;
1945
+ }
1977
1946
  var EncryptionClient = class {
1978
1947
  client;
1979
1948
  encryptConfig;
@@ -1984,7 +1953,7 @@ var EncryptionClient = class {
1984
1953
  * @returns A promise that resolves to a {@link Result} containing the initialized EncryptionClient or an {@link EncryptionError}.
1985
1954
  **/
1986
1955
  async init(config) {
1987
- return await withResult11(
1956
+ return await withResult(
1988
1957
  async () => {
1989
1958
  const validated = encryptConfigSchema.parse(
1990
1959
  config.encryptConfig
@@ -2003,7 +1972,9 @@ var EncryptionClient = class {
2003
1972
  clientId: config.clientId,
2004
1973
  clientKey: config.clientKey,
2005
1974
  keyset: toFfiKeysetIdentifier(config.keyset)
2006
- }
1975
+ },
1976
+ strategy: config.authStrategy,
1977
+ eqlVersion: config.eqlVersion
2007
1978
  });
2008
1979
  this.encryptConfig = validated;
2009
1980
  logger.debug("Successfully initialized the Encryption client.");
@@ -2094,7 +2065,7 @@ var EncryptionClient = class {
2094
2065
  return new EncryptOperation(this.client, plaintext, opts);
2095
2066
  }
2096
2067
  encryptQuery(plaintextOrTerms, opts) {
2097
- if (isScalarQueryTermArray(plaintextOrTerms)) {
2068
+ if (!opts && isScalarQueryTermArray(plaintextOrTerms)) {
2098
2069
  return new BatchEncryptQueryOperation(this.client, plaintextOrTerms);
2099
2070
  }
2100
2071
  if (Array.isArray(plaintextOrTerms) && plaintextOrTerms.length === 0 && !opts) {
@@ -2402,6 +2373,17 @@ var EncryptionClient = class {
2402
2373
  return this.encryptConfig;
2403
2374
  }
2404
2375
  };
2376
+ var warnedStrategyDeprecated = false;
2377
+ function warnStrategyDeprecated() {
2378
+ if (warnedStrategyDeprecated) return;
2379
+ warnedStrategyDeprecated = true;
2380
+ console.warn(
2381
+ "[encryption]: `config.strategy` is deprecated and will be removed in a future release \u2014 use `config.authStrategy` instead."
2382
+ );
2383
+ }
2384
+ function __resetStrategyDeprecationWarningForTests() {
2385
+ warnedStrategyDeprecated = false;
2386
+ }
2405
2387
  var Encryption = async (config) => {
2406
2388
  const { schemas, config: clientConfig } = config;
2407
2389
  if (!schemas.length) {
@@ -2414,11 +2396,18 @@ var Encryption = async (config) => {
2414
2396
  "[encryption]: Invalid UUID provided for keyset id. Must be a valid UUID."
2415
2397
  );
2416
2398
  }
2399
+ if (clientConfig?.strategy) {
2400
+ warnStrategyDeprecated();
2401
+ }
2402
+ const authStrategy = clientConfig?.authStrategy ?? clientConfig?.strategy;
2417
2403
  const client = new EncryptionClient();
2418
2404
  const encryptConfig = buildEncryptConfig(...schemas);
2405
+ const eqlVersion = resolveEqlVersion(schemas, clientConfig?.eqlVersion);
2419
2406
  const result = await client.init({
2420
2407
  encryptConfig,
2421
- ...clientConfig
2408
+ ...clientConfig,
2409
+ authStrategy,
2410
+ eqlVersion
2422
2411
  });
2423
2412
  if (result.failure) {
2424
2413
  throw new Error(`[encryption]: ${result.failure.message}`);
@@ -2438,7 +2427,9 @@ export {
2438
2427
  EncryptModelOperation,
2439
2428
  EncryptQueryOperation,
2440
2429
  noClientError,
2430
+ resolveEqlVersion,
2441
2431
  EncryptionClient,
2432
+ __resetStrategyDeprecationWarningForTests,
2442
2433
  Encryption
2443
2434
  };
2444
- //# sourceMappingURL=chunk-ZYOZHZMJ.js.map
2435
+ //# sourceMappingURL=chunk-36AA7IBJ.js.map