@cipherstash/stack 0.2.0 → 0.4.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 (67) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +2 -3
  3. package/dist/bin/stash.js +109 -186
  4. package/dist/bin/stash.js.map +1 -1
  5. package/dist/{chunk-SUYMGQBY.js → chunk-4RNBI3UH.js} +1 -7
  6. package/dist/chunk-4RNBI3UH.js.map +1 -0
  7. package/dist/{chunk-5G4F4JJG.js → chunk-KOU2MHXJ.js} +1 -1
  8. package/dist/chunk-KOU2MHXJ.js.map +1 -0
  9. package/dist/{chunk-5DCT6YU2.js → chunk-OAPLZLR5.js} +7 -3
  10. package/dist/{chunk-5DCT6YU2.js.map → chunk-OAPLZLR5.js.map} +1 -1
  11. package/dist/{chunk-LHZ6KZIG.js → chunk-WUZGKTMG.js} +84 -162
  12. package/dist/chunk-WUZGKTMG.js.map +1 -0
  13. package/dist/{chunk-7XRPN2KX.js → chunk-Y35W4WFN.js} +31 -28
  14. package/dist/chunk-Y35W4WFN.js.map +1 -0
  15. package/dist/{client-D-ZH8SB2.d.cts → client-CUGXheRq.d.cts} +33 -31
  16. package/dist/{client-BV9pXC-d.d.ts → client-CrGQnSlk.d.ts} +33 -31
  17. package/dist/client.cjs +30 -27
  18. package/dist/client.cjs.map +1 -1
  19. package/dist/client.d.cts +2 -2
  20. package/dist/client.d.ts +2 -2
  21. package/dist/client.js +5 -5
  22. package/dist/drizzle/index.cjs +24 -21
  23. package/dist/drizzle/index.cjs.map +1 -1
  24. package/dist/drizzle/index.d.cts +5 -5
  25. package/dist/drizzle/index.d.ts +5 -5
  26. package/dist/drizzle/index.js +2 -2
  27. package/dist/drizzle/index.js.map +1 -1
  28. package/dist/dynamodb/index.cjs.map +1 -1
  29. package/dist/dynamodb/index.d.cts +10 -10
  30. package/dist/dynamodb/index.d.ts +10 -10
  31. package/dist/dynamodb/index.js.map +1 -1
  32. package/dist/identity/index.cjs +6 -2
  33. package/dist/identity/index.cjs.map +1 -1
  34. package/dist/identity/index.js +1 -1
  35. package/dist/index.cjs +113 -190
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +3 -3
  38. package/dist/index.d.ts +3 -3
  39. package/dist/index.js +8 -8
  40. package/dist/schema/index.cjs +36 -33
  41. package/dist/schema/index.cjs.map +1 -1
  42. package/dist/schema/index.d.cts +1 -1
  43. package/dist/schema/index.d.ts +1 -1
  44. package/dist/schema/index.js +11 -11
  45. package/dist/secrets/index.cjs +109 -186
  46. package/dist/secrets/index.cjs.map +1 -1
  47. package/dist/secrets/index.d.cts +1 -1
  48. package/dist/secrets/index.d.ts +1 -1
  49. package/dist/secrets/index.js +5 -5
  50. package/dist/secrets/index.js.map +1 -1
  51. package/dist/supabase/index.cjs +9 -9
  52. package/dist/supabase/index.cjs.map +1 -1
  53. package/dist/supabase/index.d.cts +3 -3
  54. package/dist/supabase/index.d.ts +3 -3
  55. package/dist/supabase/index.js +4 -4
  56. package/dist/supabase/index.js.map +1 -1
  57. package/dist/{types-public-Dfg-hkuQ.d.cts → types-public-Wj6tB_ux.d.cts} +115 -76
  58. package/dist/{types-public-Dfg-hkuQ.d.ts → types-public-Wj6tB_ux.d.ts} +115 -76
  59. package/dist/types-public.cjs.map +1 -1
  60. package/dist/types-public.d.cts +1 -1
  61. package/dist/types-public.d.ts +1 -1
  62. package/dist/types-public.js +1 -1
  63. package/package.json +2 -2
  64. package/dist/chunk-5G4F4JJG.js.map +0 -1
  65. package/dist/chunk-7XRPN2KX.js.map +0 -1
  66. package/dist/chunk-LHZ6KZIG.js.map +0 -1
  67. package/dist/chunk-SUYMGQBY.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -33,8 +33,8 @@ __export(index_exports, {
33
33
  Encryption: () => Encryption,
34
34
  EncryptionErrorTypes: () => EncryptionErrorTypes,
35
35
  encryptedColumn: () => encryptedColumn,
36
+ encryptedField: () => encryptedField,
36
37
  encryptedTable: () => encryptedTable,
37
- encryptedValue: () => encryptedValue,
38
38
  getErrorMessage: () => getErrorMessage
39
39
  });
40
40
  module.exports = __toCommonJS(index_exports);
@@ -55,7 +55,7 @@ function getErrorMessage(error) {
55
55
 
56
56
  // src/schema/index.ts
57
57
  var import_zod = require("zod");
58
- var castAsEnum = import_zod.z.enum(["bigint", "boolean", "date", "number", "string", "json"]).default("string");
58
+ var castAsEnum = import_zod.z.enum(["bigint", "boolean", "date", "number", "string", "json", "text"]).default("text");
59
59
  var tokenFilterSchema = import_zod.z.object({
60
60
  kind: import_zod.z.literal("downcase")
61
61
  });
@@ -98,28 +98,28 @@ var encryptConfigSchema = import_zod.z.object({
98
98
  v: import_zod.z.number(),
99
99
  tables: tablesSchema
100
100
  });
101
- var ProtectValue = class {
101
+ var EncryptedField = class {
102
102
  valueName;
103
103
  castAsValue;
104
104
  constructor(valueName) {
105
105
  this.valueName = valueName;
106
- this.castAsValue = "string";
106
+ this.castAsValue = "text";
107
107
  }
108
108
  /**
109
- * Set or override the plaintext data type for this value.
109
+ * Set or override the plaintext data type for this field.
110
110
  *
111
111
  * By default all values are treated as `'string'`. Use this method to specify
112
112
  * a different type so the encryption layer knows how to encode the plaintext
113
113
  * before encrypting.
114
114
  *
115
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
116
- * @returns This `ProtectValue` instance for method chaining.
115
+ * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'text'`, `'bigint'`, or `'json'`.
116
+ * @returns This `EncryptedField` instance for method chaining.
117
117
  *
118
118
  * @example
119
119
  * ```typescript
120
- * import { encryptedValue } from "@cipherstash/stack/schema"
120
+ * import { encryptedField } from "@cipherstash/stack/schema"
121
121
  *
122
- * const age = encryptedValue("age").dataType("number")
122
+ * const age = encryptedField("age").dataType("number")
123
123
  * ```
124
124
  */
125
125
  dataType(castAs) {
@@ -128,7 +128,7 @@ var ProtectValue = class {
128
128
  }
129
129
  build() {
130
130
  return {
131
- cast_as: this.castAsValue,
131
+ cast_as: this.castAsValue === "string" ? "text" : this.castAsValue,
132
132
  indexes: {}
133
133
  };
134
134
  }
@@ -136,7 +136,7 @@ var ProtectValue = class {
136
136
  return this.valueName;
137
137
  }
138
138
  };
139
- var ProtectColumn = class {
139
+ var EncryptedColumn = class {
140
140
  columnName;
141
141
  castAsValue;
142
142
  indexesValue = {};
@@ -152,7 +152,7 @@ var ProtectColumn = class {
152
152
  * before encrypting.
153
153
  *
154
154
  * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
155
- * @returns This `ProtectColumn` instance for method chaining.
155
+ * @returns This `EncryptedColumn` instance for method chaining.
156
156
  *
157
157
  * @example
158
158
  * ```typescript
@@ -171,7 +171,7 @@ var ProtectColumn = class {
171
171
  * ORE allows sorting, comparison, and range queries on encrypted data.
172
172
  * Use with `encryptQuery` and `queryType: 'orderAndRange'`.
173
173
  *
174
- * @returns This `ProtectColumn` instance for method chaining.
174
+ * @returns This `EncryptedColumn` instance for method chaining.
175
175
  *
176
176
  * @example
177
177
  * ```typescript
@@ -194,7 +194,7 @@ var ProtectColumn = class {
194
194
  *
195
195
  * @param tokenFilters - Optional array of token filters (e.g. `[{ kind: 'downcase' }]`).
196
196
  * When omitted, no token filters are applied.
197
- * @returns This `ProtectColumn` instance for method chaining.
197
+ * @returns This `EncryptedColumn` instance for method chaining.
198
198
  *
199
199
  * @example
200
200
  * ```typescript
@@ -219,7 +219,7 @@ var ProtectColumn = class {
219
219
  *
220
220
  * @param opts - Optional match index configuration. Defaults to 3-character ngram
221
221
  * tokenization with a downcase filter, `k=6`, `m=2048`, and `include_original=true`.
222
- * @returns This `ProtectColumn` instance for method chaining.
222
+ * @returns This `EncryptedColumn` instance for method chaining.
223
223
  *
224
224
  * @example
225
225
  * ```typescript
@@ -264,7 +264,7 @@ var ProtectColumn = class {
264
264
  * the plaintext type: strings become selector queries, objects/arrays become
265
265
  * containment queries.
266
266
  *
267
- * @returns This `ProtectColumn` instance for method chaining.
267
+ * @returns This `EncryptedColumn` instance for method chaining.
268
268
  *
269
269
  * @example
270
270
  * ```typescript
@@ -282,7 +282,7 @@ var ProtectColumn = class {
282
282
  }
283
283
  build() {
284
284
  return {
285
- cast_as: this.castAsValue,
285
+ cast_as: this.castAsValue === "string" ? "text" : this.castAsValue,
286
286
  indexes: this.indexesValue
287
287
  };
288
288
  }
@@ -290,7 +290,7 @@ var ProtectColumn = class {
290
290
  return this.columnName;
291
291
  }
292
292
  };
293
- var ProtectTable = class {
293
+ var EncryptedTable = class {
294
294
  constructor(tableName, columnBuilders) {
295
295
  this.tableName = tableName;
296
296
  this.columnBuilders = columnBuilders;
@@ -317,7 +317,7 @@ var ProtectTable = class {
317
317
  build() {
318
318
  const builtColumns = {};
319
319
  const processColumn = (builder, colName) => {
320
- if (builder instanceof ProtectColumn) {
320
+ if (builder instanceof EncryptedColumn) {
321
321
  const builtColumn = builder.build();
322
322
  if (builtColumn.cast_as === "json" && builtColumn.indexes.ste_vec?.prefix === "enabled") {
323
323
  builtColumns[colName] = {
@@ -334,7 +334,7 @@ var ProtectTable = class {
334
334
  }
335
335
  } else {
336
336
  for (const [key, value] of Object.entries(builder)) {
337
- if (value instanceof ProtectValue) {
337
+ if (value instanceof EncryptedField) {
338
338
  builtColumns[value.getName()] = value.build();
339
339
  } else {
340
340
  processColumn(value, key);
@@ -352,7 +352,10 @@ var ProtectTable = class {
352
352
  }
353
353
  };
354
354
  function encryptedTable(tableName, columns) {
355
- const tableBuilder = new ProtectTable(tableName, columns);
355
+ const tableBuilder = new EncryptedTable(
356
+ tableName,
357
+ columns
358
+ );
356
359
  for (const [colName, colBuilder] of Object.entries(columns)) {
357
360
  ;
358
361
  tableBuilder[colName] = colBuilder;
@@ -360,10 +363,10 @@ function encryptedTable(tableName, columns) {
360
363
  return tableBuilder;
361
364
  }
362
365
  function encryptedColumn(columnName) {
363
- return new ProtectColumn(columnName);
366
+ return new EncryptedColumn(columnName);
364
367
  }
365
- function encryptedValue(valueName) {
366
- return new ProtectValue(valueName);
368
+ function encryptedField(valueName) {
369
+ return new EncryptedField(valueName);
367
370
  }
368
371
  function buildEncryptConfig(...protectTables) {
369
372
  const config = {
@@ -457,7 +460,7 @@ function initStackLogger(config) {
457
460
  const rates = samplingFromEnv();
458
461
  (0, import_evlog.initLogger)({
459
462
  env: { service: "@cipherstash/stack" },
460
- enabled: config?.enabled ?? true,
463
+ enabled: config?.enabled ?? !!rates,
461
464
  pretty: config?.pretty,
462
465
  ...rates && { sampling: { rates } },
463
466
  ...config?.drain && { drain: config.drain }
@@ -470,7 +473,11 @@ function safeMessage(args) {
470
473
  var logger = {
471
474
  debug(...args) {
472
475
  const log = (0, import_evlog.createRequestLogger)();
473
- log.set({ level: "debug", source: "@cipherstash/stack", message: safeMessage(args) });
476
+ log.set({
477
+ level: "debug",
478
+ source: "@cipherstash/stack",
479
+ message: safeMessage(args)
480
+ });
474
481
  log.emit();
475
482
  },
476
483
  info(...args) {
@@ -491,21 +498,15 @@ var logger = {
491
498
  }
492
499
  };
493
500
 
494
- // src/encryption/ffi/index.ts
501
+ // src/encryption/index.ts
495
502
  var import_result11 = require("@byteslice/result");
496
503
  var import_protect_ffi9 = require("@cipherstash/protect-ffi");
497
504
 
498
505
  // src/encryption/helpers/index.ts
499
506
  function encryptedToCompositeLiteral(obj) {
500
- if (obj === null) {
501
- throw new Error("encryptedToCompositeLiteral: obj cannot be null");
502
- }
503
507
  return `(${JSON.stringify(JSON.stringify(obj))})`;
504
508
  }
505
509
  function encryptedToEscapedCompositeLiteral(obj) {
506
- if (obj === null) {
507
- throw new Error("encryptedToEscapedCompositeLiteral: obj cannot be null");
508
- }
509
510
  return JSON.stringify(encryptedToCompositeLiteral(obj));
510
511
  }
511
512
  function formatEncryptedResult(encrypted, returnType) {
@@ -534,18 +535,18 @@ function isEncryptedPayload(value) {
534
535
  return true;
535
536
  }
536
537
 
537
- // src/encryption/ffi/helpers/type-guards.ts
538
+ // src/encryption/helpers/type-guards.ts
538
539
  function isScalarQueryTermArray(value) {
539
540
  return Array.isArray(value) && value.length > 0 && typeof value[0] === "object" && value[0] !== null && "column" in value[0] && "table" in value[0];
540
541
  }
541
542
 
542
- // src/encryption/ffi/helpers/error-code.ts
543
+ // src/encryption/helpers/error-code.ts
543
544
  var import_protect_ffi = require("@cipherstash/protect-ffi");
544
545
  function getErrorCode(error) {
545
546
  return error instanceof import_protect_ffi.ProtectError ? error.code : void 0;
546
547
  }
547
548
 
548
- // src/encryption/ffi/operations/batch-encrypt-query.ts
549
+ // src/encryption/operations/batch-encrypt-query.ts
549
550
  var import_result = require("@byteslice/result");
550
551
  var import_protect_ffi2 = require("@cipherstash/protect-ffi");
551
552
 
@@ -563,7 +564,7 @@ var queryTypeToQueryOp = {
563
564
  steVecTerm: "ste_vec_term"
564
565
  };
565
566
 
566
- // src/encryption/ffi/helpers/infer-index-type.ts
567
+ // src/encryption/helpers/infer-index-type.ts
567
568
  function inferIndexType(column) {
568
569
  const config = column.build();
569
570
  const indexes = config.indexes;
@@ -623,7 +624,7 @@ function resolveIndexType(column, queryType, plaintext) {
623
624
  return { indexType };
624
625
  }
625
626
 
626
- // src/encryption/ffi/helpers/validation.ts
627
+ // src/encryption/helpers/validation.ts
627
628
  function validateNumericValue(value) {
628
629
  if (typeof value === "number" && Number.isNaN(value)) {
629
630
  return {
@@ -659,7 +660,7 @@ function assertValueIndexCompatibility(value, indexType, columnName) {
659
660
  }
660
661
  }
661
662
 
662
- // src/encryption/ffi/operations/base-operation.ts
663
+ // src/encryption/operations/base-operation.ts
663
664
  var EncryptionOperation = class {
664
665
  auditMetadata;
665
666
  /**
@@ -687,19 +688,7 @@ var EncryptionOperation = class {
687
688
  }
688
689
  };
689
690
 
690
- // src/encryption/ffi/operations/batch-encrypt-query.ts
691
- function filterNullTerms(terms) {
692
- const nullIndices = /* @__PURE__ */ new Set();
693
- const nonNullTerms = [];
694
- terms.forEach((term, index) => {
695
- if (term.value === null || term.value === void 0) {
696
- nullIndices.add(index);
697
- } else {
698
- nonNullTerms.push({ term, originalIndex: index });
699
- }
700
- });
701
- return { nullIndices, nonNullTerms };
702
- }
691
+ // src/encryption/operations/batch-encrypt-query.ts
703
692
  function buildQueryPayload(term, lockContext) {
704
693
  assertValidNumericValue(term.value);
705
694
  const { indexType, queryOp } = resolveIndexType(
@@ -720,13 +709,10 @@ function buildQueryPayload(term, lockContext) {
720
709
  }
721
710
  return payload;
722
711
  }
723
- function assembleResults(totalLength, encryptedValues, nonNullTerms) {
724
- const results = new Array(totalLength).fill(null);
725
- nonNullTerms.forEach(({ term, originalIndex }, i) => {
726
- const encrypted = encryptedValues[i];
727
- results[originalIndex] = formatEncryptedResult(encrypted, term.returnType);
728
- });
729
- return results;
712
+ function assembleResults(terms, encryptedValues) {
713
+ return terms.map(
714
+ (term, i) => formatEncryptedResult(encryptedValues[i], term.returnType)
715
+ );
730
716
  }
731
717
  var BatchEncryptQueryOperation = class extends EncryptionOperation {
732
718
  constructor(client, terms) {
@@ -753,23 +739,18 @@ var BatchEncryptQueryOperation = class extends EncryptionOperation {
753
739
  log.emit();
754
740
  return { data: [] };
755
741
  }
756
- const { nullIndices, nonNullTerms } = filterNullTerms(this.terms);
757
- if (nonNullTerms.length === 0) {
758
- log.emit();
759
- return { data: this.terms.map(() => null) };
760
- }
761
742
  const result = await (0, import_result.withResult)(
762
743
  async () => {
763
744
  if (!this.client) throw noClientError();
764
745
  const { metadata } = this.getAuditData();
765
- const queries = nonNullTerms.map(
766
- ({ term }) => buildQueryPayload(term)
746
+ const queries = this.terms.map(
747
+ (term) => buildQueryPayload(term)
767
748
  );
768
749
  const encrypted = await (0, import_protect_ffi2.encryptQueryBulk)(this.client, {
769
750
  queries,
770
751
  unverifiedContext: metadata
771
752
  });
772
- return assembleResults(this.terms.length, encrypted, nonNullTerms);
753
+ return assembleResults(this.terms, encrypted);
773
754
  },
774
755
  (error) => {
775
756
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -803,11 +784,6 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
803
784
  log.emit();
804
785
  return { data: [] };
805
786
  }
806
- const { nullIndices, nonNullTerms } = filterNullTerms(this.terms);
807
- if (nonNullTerms.length === 0) {
808
- log.emit();
809
- return { data: this.terms.map(() => null) };
810
- }
811
787
  const lockContextResult = await this.lockContext.getLockContext();
812
788
  if (lockContextResult.failure) {
813
789
  log.emit();
@@ -818,15 +794,15 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
818
794
  async () => {
819
795
  if (!this.client) throw noClientError();
820
796
  const { metadata } = this.getAuditData();
821
- const queries = nonNullTerms.map(
822
- ({ term }) => buildQueryPayload(term, context)
797
+ const queries = this.terms.map(
798
+ (term) => buildQueryPayload(term, context)
823
799
  );
824
800
  const encrypted = await (0, import_protect_ffi2.encryptQueryBulk)(this.client, {
825
801
  queries,
826
802
  serviceToken: ctsToken,
827
803
  unverifiedContext: metadata
828
804
  });
829
- return assembleResults(this.terms.length, encrypted, nonNullTerms);
805
+ return assembleResults(this.terms, encrypted);
830
806
  },
831
807
  (error) => {
832
808
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -842,46 +818,29 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
842
818
  }
843
819
  };
844
820
 
845
- // src/encryption/ffi/operations/bulk-decrypt.ts
821
+ // src/encryption/operations/bulk-decrypt.ts
846
822
  var import_result2 = require("@byteslice/result");
847
823
  var import_protect_ffi3 = require("@cipherstash/protect-ffi");
848
824
  var createDecryptPayloads = (encryptedPayloads, lockContext) => {
849
- return encryptedPayloads.map((item, index) => ({ ...item, originalIndex: index })).filter(({ data }) => data !== null).map(({ id, data, originalIndex }) => ({
825
+ return encryptedPayloads.map(({ id, data }) => ({
850
826
  id,
851
827
  ciphertext: data,
852
- originalIndex,
853
828
  ...lockContext && { lockContext }
854
829
  }));
855
830
  };
856
- var createNullResult = (encryptedPayloads) => {
857
- return encryptedPayloads.map(({ id }) => ({
858
- id,
859
- data: null
860
- }));
861
- };
862
831
  var mapDecryptedDataToResult = (encryptedPayloads, decryptedData) => {
863
- const result = new Array(encryptedPayloads.length);
864
- let decryptedIndex = 0;
865
- for (let i = 0; i < encryptedPayloads.length; i++) {
866
- if (encryptedPayloads[i].data === null) {
867
- result[i] = { id: encryptedPayloads[i].id, data: null };
868
- } else {
869
- const decryptResult = decryptedData[decryptedIndex];
870
- if ("error" in decryptResult) {
871
- result[i] = {
872
- id: encryptedPayloads[i].id,
873
- error: decryptResult.error
874
- };
875
- } else {
876
- result[i] = {
877
- id: encryptedPayloads[i].id,
878
- data: decryptResult.data
879
- };
880
- }
881
- decryptedIndex++;
832
+ return decryptedData.map((decryptResult, i) => {
833
+ if ("error" in decryptResult) {
834
+ return {
835
+ id: encryptedPayloads[i].id,
836
+ error: decryptResult.error
837
+ };
882
838
  }
883
- }
884
- return result;
839
+ return {
840
+ id: encryptedPayloads[i].id,
841
+ data: decryptResult.data
842
+ };
843
+ });
885
844
  };
886
845
  var BulkDecryptOperation = class extends EncryptionOperation {
887
846
  client;
@@ -906,13 +865,10 @@ var BulkDecryptOperation = class extends EncryptionOperation {
906
865
  if (!this.client) throw noClientError();
907
866
  if (!this.encryptedPayloads || this.encryptedPayloads.length === 0)
908
867
  return [];
909
- const nonNullPayloads = createDecryptPayloads(this.encryptedPayloads);
910
- if (nonNullPayloads.length === 0) {
911
- return createNullResult(this.encryptedPayloads);
912
- }
868
+ const payloads = createDecryptPayloads(this.encryptedPayloads);
913
869
  const { metadata } = this.getAuditData();
914
870
  const decryptedData = await (0, import_protect_ffi3.decryptBulkFallible)(this.client, {
915
- ciphertexts: nonNullPayloads,
871
+ ciphertexts: payloads,
916
872
  unverifiedContext: metadata
917
873
  });
918
874
  return mapDecryptedDataToResult(this.encryptedPayloads, decryptedData);
@@ -964,16 +920,13 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
964
920
  if (context.failure) {
965
921
  throw new Error(`[encryption]: ${context.failure.message}`);
966
922
  }
967
- const nonNullPayloads = createDecryptPayloads(
923
+ const payloads = createDecryptPayloads(
968
924
  encryptedPayloads,
969
925
  context.data.context
970
926
  );
971
- if (nonNullPayloads.length === 0) {
972
- return createNullResult(encryptedPayloads);
973
- }
974
927
  const { metadata } = this.getAuditData();
975
928
  const decryptedData = await (0, import_protect_ffi3.decryptBulkFallible)(client, {
976
- ciphertexts: nonNullPayloads,
929
+ ciphertexts: payloads,
977
930
  serviceToken: context.data.ctsToken,
978
931
  unverifiedContext: metadata
979
932
  });
@@ -993,10 +946,10 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
993
946
  }
994
947
  };
995
948
 
996
- // src/encryption/ffi/operations/bulk-decrypt-models.ts
949
+ // src/encryption/operations/bulk-decrypt-models.ts
997
950
  var import_result3 = require("@byteslice/result");
998
951
 
999
- // src/encryption/ffi/model-helpers.ts
952
+ // src/encryption/helpers/model-helpers.ts
1000
953
  var import_protect_ffi4 = require("@cipherstash/protect-ffi");
1001
954
  function setNestedValue(obj, path2, value) {
1002
955
  const FORBIDDEN_KEYS = ["__proto__", "prototype", "constructor"];
@@ -1511,7 +1464,7 @@ async function bulkEncryptModelsWithLockContext(models, table, client, lockConte
1511
1464
  });
1512
1465
  }
1513
1466
 
1514
- // src/encryption/ffi/operations/bulk-decrypt-models.ts
1467
+ // src/encryption/operations/bulk-decrypt-models.ts
1515
1468
  var BulkDecryptModelsOperation = class extends EncryptionOperation {
1516
1469
  client;
1517
1470
  models;
@@ -1608,38 +1561,18 @@ var BulkDecryptModelsOperationWithLockContext = class extends EncryptionOperatio
1608
1561
  }
1609
1562
  };
1610
1563
 
1611
- // src/encryption/ffi/operations/bulk-encrypt.ts
1564
+ // src/encryption/operations/bulk-encrypt.ts
1612
1565
  var import_result4 = require("@byteslice/result");
1613
1566
  var import_protect_ffi5 = require("@cipherstash/protect-ffi");
1614
1567
  var createEncryptPayloads = (plaintexts, column, table, lockContext) => {
1615
- return plaintexts.map((item, index) => ({ ...item, originalIndex: index })).filter(({ plaintext }) => plaintext !== null).map(({ id, plaintext, originalIndex }) => ({
1568
+ return plaintexts.map(({ id, plaintext }) => ({
1616
1569
  id,
1617
1570
  plaintext,
1618
1571
  column: column.getName(),
1619
1572
  table: table.tableName,
1620
- originalIndex,
1621
1573
  ...lockContext && { lockContext }
1622
1574
  }));
1623
1575
  };
1624
- var createNullResult2 = (plaintexts) => {
1625
- return plaintexts.map(({ id }) => ({ id, data: null }));
1626
- };
1627
- var mapEncryptedDataToResult = (plaintexts, encryptedData) => {
1628
- const result = new Array(plaintexts.length);
1629
- let encryptedIndex = 0;
1630
- for (let i = 0; i < plaintexts.length; i++) {
1631
- if (plaintexts[i].plaintext === null) {
1632
- result[i] = { id: plaintexts[i].id, data: null };
1633
- } else {
1634
- result[i] = {
1635
- id: plaintexts[i].id,
1636
- data: encryptedData[encryptedIndex]
1637
- };
1638
- encryptedIndex++;
1639
- }
1640
- }
1641
- return result;
1642
- };
1643
1576
  var BulkEncryptOperation = class extends EncryptionOperation {
1644
1577
  client;
1645
1578
  plaintexts;
@@ -1672,20 +1605,20 @@ var BulkEncryptOperation = class extends EncryptionOperation {
1672
1605
  if (!this.plaintexts || this.plaintexts.length === 0) {
1673
1606
  return [];
1674
1607
  }
1675
- const nonNullPayloads = createEncryptPayloads(
1608
+ const payloads = createEncryptPayloads(
1676
1609
  this.plaintexts,
1677
1610
  this.column,
1678
1611
  this.table
1679
1612
  );
1680
- if (nonNullPayloads.length === 0) {
1681
- return createNullResult2(this.plaintexts);
1682
- }
1683
1613
  const { metadata } = this.getAuditData();
1684
1614
  const encryptedData = await (0, import_protect_ffi5.encryptBulk)(this.client, {
1685
- plaintexts: nonNullPayloads,
1615
+ plaintexts: payloads,
1686
1616
  unverifiedContext: metadata
1687
1617
  });
1688
- return mapEncryptedDataToResult(this.plaintexts, encryptedData);
1618
+ return encryptedData.map((data, i) => ({
1619
+ id: this.plaintexts[i].id,
1620
+ data
1621
+ }));
1689
1622
  },
1690
1623
  (error) => {
1691
1624
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -1742,22 +1675,22 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1742
1675
  if (context.failure) {
1743
1676
  throw new Error(`[encryption]: ${context.failure.message}`);
1744
1677
  }
1745
- const nonNullPayloads = createEncryptPayloads(
1678
+ const payloads = createEncryptPayloads(
1746
1679
  plaintexts,
1747
1680
  column,
1748
1681
  table,
1749
1682
  context.data.context
1750
1683
  );
1751
- if (nonNullPayloads.length === 0) {
1752
- return createNullResult2(plaintexts);
1753
- }
1754
1684
  const { metadata } = this.getAuditData();
1755
1685
  const encryptedData = await (0, import_protect_ffi5.encryptBulk)(client, {
1756
- plaintexts: nonNullPayloads,
1686
+ plaintexts: payloads,
1757
1687
  serviceToken: context.data.ctsToken,
1758
1688
  unverifiedContext: metadata
1759
1689
  });
1760
- return mapEncryptedDataToResult(plaintexts, encryptedData);
1690
+ return encryptedData.map((data, i) => ({
1691
+ id: plaintexts[i].id,
1692
+ data
1693
+ }));
1761
1694
  },
1762
1695
  (error) => {
1763
1696
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -1773,7 +1706,7 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1773
1706
  }
1774
1707
  };
1775
1708
 
1776
- // src/encryption/ffi/operations/bulk-encrypt-models.ts
1709
+ // src/encryption/operations/bulk-encrypt-models.ts
1777
1710
  var import_result5 = require("@byteslice/result");
1778
1711
  var BulkEncryptModelsOperation = class extends EncryptionOperation {
1779
1712
  client;
@@ -1882,7 +1815,7 @@ var BulkEncryptModelsOperationWithLockContext = class extends EncryptionOperatio
1882
1815
  }
1883
1816
  };
1884
1817
 
1885
- // src/encryption/ffi/operations/decrypt.ts
1818
+ // src/encryption/operations/decrypt.ts
1886
1819
  var import_result6 = require("@byteslice/result");
1887
1820
  var import_protect_ffi6 = require("@cipherstash/protect-ffi");
1888
1821
  var DecryptOperation = class extends EncryptionOperation {
@@ -1907,9 +1840,6 @@ var DecryptOperation = class extends EncryptionOperation {
1907
1840
  if (!this.client) {
1908
1841
  throw noClientError();
1909
1842
  }
1910
- if (this.encryptedData === null) {
1911
- return null;
1912
- }
1913
1843
  const { metadata } = this.getAuditData();
1914
1844
  return await (0, import_protect_ffi6.decrypt)(this.client, {
1915
1845
  ciphertext: this.encryptedData,
@@ -1960,9 +1890,6 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
1960
1890
  if (!client) {
1961
1891
  throw noClientError();
1962
1892
  }
1963
- if (encryptedData === null) {
1964
- return null;
1965
- }
1966
1893
  const { metadata } = this.getAuditData();
1967
1894
  const context = await this.lockContext.getLockContext();
1968
1895
  if (context.failure) {
@@ -1989,7 +1916,7 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
1989
1916
  }
1990
1917
  };
1991
1918
 
1992
- // src/encryption/ffi/operations/decrypt-model.ts
1919
+ // src/encryption/operations/decrypt-model.ts
1993
1920
  var import_result7 = require("@byteslice/result");
1994
1921
  var DecryptModelOperation = class extends EncryptionOperation {
1995
1922
  client;
@@ -2085,7 +2012,7 @@ var DecryptModelOperationWithLockContext = class extends EncryptionOperation {
2085
2012
  }
2086
2013
  };
2087
2014
 
2088
- // src/encryption/ffi/operations/encrypt.ts
2015
+ // src/encryption/operations/encrypt.ts
2089
2016
  var import_result8 = require("@byteslice/result");
2090
2017
  var import_protect_ffi7 = require("@cipherstash/protect-ffi");
2091
2018
  var EncryptOperation = class extends EncryptionOperation {
@@ -2116,9 +2043,6 @@ var EncryptOperation = class extends EncryptionOperation {
2116
2043
  if (!this.client) {
2117
2044
  throw noClientError();
2118
2045
  }
2119
- if (this.plaintext === null) {
2120
- return null;
2121
- }
2122
2046
  if (typeof this.plaintext === "number" && Number.isNaN(this.plaintext)) {
2123
2047
  throw new Error("[encryption]: Cannot encrypt NaN value");
2124
2048
  }
@@ -2180,9 +2104,6 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
2180
2104
  if (!client) {
2181
2105
  throw noClientError();
2182
2106
  }
2183
- if (plaintext === null) {
2184
- return null;
2185
- }
2186
2107
  const { metadata } = this.getAuditData();
2187
2108
  const context = await this.lockContext.getLockContext();
2188
2109
  if (context.failure) {
@@ -2211,7 +2132,7 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
2211
2132
  }
2212
2133
  };
2213
2134
 
2214
- // src/encryption/ffi/operations/encrypt-model.ts
2135
+ // src/encryption/operations/encrypt-model.ts
2215
2136
  var import_result9 = require("@byteslice/result");
2216
2137
  var EncryptModelOperation = class extends EncryptionOperation {
2217
2138
  client;
@@ -2318,7 +2239,7 @@ var EncryptModelOperationWithLockContext = class extends EncryptionOperation {
2318
2239
  }
2319
2240
  };
2320
2241
 
2321
- // src/encryption/ffi/operations/encrypt-query.ts
2242
+ // src/encryption/operations/encrypt-query.ts
2322
2243
  var import_result10 = require("@byteslice/result");
2323
2244
  var import_protect_ffi8 = require("@cipherstash/protect-ffi");
2324
2245
  var EncryptQueryOperation = class extends EncryptionOperation {
@@ -2346,10 +2267,6 @@ var EncryptQueryOperation = class extends EncryptionOperation {
2346
2267
  queryType: this.opts.queryType,
2347
2268
  lockContext: false
2348
2269
  });
2349
- if (this.plaintext === null || this.plaintext === void 0) {
2350
- log.emit();
2351
- return { data: null };
2352
- }
2353
2270
  const validationError = validateNumericValue(this.plaintext);
2354
2271
  if (validationError?.failure) {
2355
2272
  log.emit();
@@ -2413,10 +2330,6 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
2413
2330
  queryType: this.opts.queryType,
2414
2331
  lockContext: true
2415
2332
  });
2416
- if (this.plaintext === null || this.plaintext === void 0) {
2417
- log.emit();
2418
- return { data: null };
2419
- }
2420
2333
  const validationError = validateNumericValue(this.plaintext);
2421
2334
  if (validationError?.failure) {
2422
2335
  log.emit();
@@ -2468,9 +2381,9 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
2468
2381
  }
2469
2382
  };
2470
2383
 
2471
- // src/encryption/ffi/index.ts
2384
+ // src/encryption/index.ts
2472
2385
  var noClientError = () => new Error(
2473
- "The EQL client has not been initialized. Please call init() before using the client."
2386
+ "The Encryption client has not been initialized. Please call init() before using the client."
2474
2387
  );
2475
2388
  var EncryptionClient = class {
2476
2389
  client;
@@ -2493,7 +2406,7 @@ var EncryptionClient = class {
2493
2406
  config.encryptConfig
2494
2407
  );
2495
2408
  logger.debug(
2496
- "Initializing the Protect.js client with the following encrypt config:",
2409
+ "Initializing the Encryption client with the following config:",
2497
2410
  {
2498
2411
  encryptConfig: validated
2499
2412
  }
@@ -2509,7 +2422,7 @@ var EncryptionClient = class {
2509
2422
  }
2510
2423
  });
2511
2424
  this.encryptConfig = validated;
2512
- logger.debug("Successfully initialized the Protect.js client.");
2425
+ logger.debug("Successfully initialized the Encryption client.");
2513
2426
  return this;
2514
2427
  },
2515
2428
  (error) => ({
@@ -2521,8 +2434,8 @@ var EncryptionClient = class {
2521
2434
  /**
2522
2435
  * Encrypt a value - returns a promise which resolves to an encrypted value.
2523
2436
  *
2524
- * @param plaintext - The plaintext value to be encrypted. Can be null.
2525
- * @param opts - Options specifying the column and table for encryption.
2437
+ * @param plaintext - The plaintext value to be encrypted.
2438
+ * @param opts - Options specifying the column (or nested field) and table for encryption. See {@link EncryptOptions}.
2526
2439
  * @returns An EncryptOperation that can be awaited or chained with additional methods.
2527
2440
  *
2528
2441
  * @example
@@ -2585,8 +2498,11 @@ var EncryptionClient = class {
2585
2498
  * .withLockContext(lockContext)
2586
2499
  * ```
2587
2500
  *
2501
+ * @see {@link EncryptOptions}
2588
2502
  * @see {@link Result}
2589
2503
  * @see {@link encryptedTable}
2504
+ * @see {@link encryptedColumn}
2505
+ * @see {@link encryptedField}
2590
2506
  * @see {@link LockContext}
2591
2507
  * @see {@link EncryptOperation}
2592
2508
  */
@@ -2694,7 +2610,11 @@ var EncryptionClient = class {
2694
2610
  * ```
2695
2611
  */
2696
2612
  encryptModel(input, table) {
2697
- return new EncryptModelOperation(this.client, input, table);
2613
+ return new EncryptModelOperation(
2614
+ this.client,
2615
+ input,
2616
+ table
2617
+ );
2698
2618
  }
2699
2619
  /**
2700
2620
  * Decrypt a model (object) whose fields contain encrypted values.
@@ -2773,7 +2693,11 @@ var EncryptionClient = class {
2773
2693
  * ```
2774
2694
  */
2775
2695
  bulkEncryptModels(input, table) {
2776
- return new BulkEncryptModelsOperation(this.client, input, table);
2696
+ return new BulkEncryptModelsOperation(
2697
+ this.client,
2698
+ input,
2699
+ table
2700
+ );
2777
2701
  }
2778
2702
  /**
2779
2703
  * Decrypt multiple models (objects) in a single bulk operation.
@@ -2811,10 +2735,10 @@ var EncryptionClient = class {
2811
2735
  *
2812
2736
  * Each value is encrypted with its own unique key via a single call to ZeroKMS.
2813
2737
  * Values can include optional `id` fields for correlating results back to
2814
- * your application data. Null plaintext values are preserved as null.
2738
+ * your application data.
2815
2739
  *
2816
2740
  * @param plaintexts - An array of objects with `plaintext` (and optional `id`) fields.
2817
- * @param opts - Options specifying the target column and table for encryption.
2741
+ * @param opts - Options specifying the target column (or nested {@link encryptedField}) and table. See {@link EncryptOptions}.
2818
2742
  * @returns A `BulkEncryptOperation` that can be awaited to get a `Result`
2819
2743
  * containing an array of `{ id?, data: Encrypted }` objects, or an `EncryptionError`.
2820
2744
  *
@@ -2832,7 +2756,6 @@ var EncryptionClient = class {
2832
2756
  * [
2833
2757
  * { id: "u1", plaintext: "alice@example.com" },
2834
2758
  * { id: "u2", plaintext: "bob@example.com" },
2835
- * { id: "u3", plaintext: null },
2836
2759
  * ],
2837
2760
  * { column: users.email, table: users },
2838
2761
  * )
@@ -2923,8 +2846,8 @@ var Encryption = async (config) => {
2923
2846
  Encryption,
2924
2847
  EncryptionErrorTypes,
2925
2848
  encryptedColumn,
2849
+ encryptedField,
2926
2850
  encryptedTable,
2927
- encryptedValue,
2928
2851
  getErrorMessage
2929
2852
  });
2930
2853
  //# sourceMappingURL=index.cjs.map