@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
@@ -41,15 +41,9 @@ function encryptedToPgComposite(obj) {
41
41
  };
42
42
  }
43
43
  function encryptedToCompositeLiteral(obj) {
44
- if (obj === null) {
45
- throw new Error("encryptedToCompositeLiteral: obj cannot be null");
46
- }
47
44
  return `(${JSON.stringify(JSON.stringify(obj))})`;
48
45
  }
49
46
  function encryptedToEscapedCompositeLiteral(obj) {
50
- if (obj === null) {
51
- throw new Error("encryptedToEscapedCompositeLiteral: obj cannot be null");
52
- }
53
47
  return JSON.stringify(encryptedToCompositeLiteral(obj));
54
48
  }
55
49
  function formatEncryptedResult(encrypted, returnType) {
@@ -89,7 +83,7 @@ var EncryptionErrorTypes = {
89
83
 
90
84
  // src/schema/index.ts
91
85
  var import_zod = require("zod");
92
- var castAsEnum = import_zod.z.enum(["bigint", "boolean", "date", "number", "string", "json"]).default("string");
86
+ var castAsEnum = import_zod.z.enum(["bigint", "boolean", "date", "number", "string", "json", "text"]).default("text");
93
87
  var tokenFilterSchema = import_zod.z.object({
94
88
  kind: import_zod.z.literal("downcase")
95
89
  });
@@ -132,28 +126,28 @@ var encryptConfigSchema = import_zod.z.object({
132
126
  v: import_zod.z.number(),
133
127
  tables: tablesSchema
134
128
  });
135
- var ProtectValue = class {
129
+ var EncryptedField = class {
136
130
  valueName;
137
131
  castAsValue;
138
132
  constructor(valueName) {
139
133
  this.valueName = valueName;
140
- this.castAsValue = "string";
134
+ this.castAsValue = "text";
141
135
  }
142
136
  /**
143
- * Set or override the plaintext data type for this value.
137
+ * Set or override the plaintext data type for this field.
144
138
  *
145
139
  * By default all values are treated as `'string'`. Use this method to specify
146
140
  * a different type so the encryption layer knows how to encode the plaintext
147
141
  * before encrypting.
148
142
  *
149
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
150
- * @returns This `ProtectValue` instance for method chaining.
143
+ * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'text'`, `'bigint'`, or `'json'`.
144
+ * @returns This `EncryptedField` instance for method chaining.
151
145
  *
152
146
  * @example
153
147
  * ```typescript
154
- * import { encryptedValue } from "@cipherstash/stack/schema"
148
+ * import { encryptedField } from "@cipherstash/stack/schema"
155
149
  *
156
- * const age = encryptedValue("age").dataType("number")
150
+ * const age = encryptedField("age").dataType("number")
157
151
  * ```
158
152
  */
159
153
  dataType(castAs) {
@@ -162,7 +156,7 @@ var ProtectValue = class {
162
156
  }
163
157
  build() {
164
158
  return {
165
- cast_as: this.castAsValue,
159
+ cast_as: this.castAsValue === "string" ? "text" : this.castAsValue,
166
160
  indexes: {}
167
161
  };
168
162
  }
@@ -170,7 +164,7 @@ var ProtectValue = class {
170
164
  return this.valueName;
171
165
  }
172
166
  };
173
- var ProtectColumn = class {
167
+ var EncryptedColumn = class {
174
168
  columnName;
175
169
  castAsValue;
176
170
  indexesValue = {};
@@ -186,7 +180,7 @@ var ProtectColumn = class {
186
180
  * before encrypting.
187
181
  *
188
182
  * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
189
- * @returns This `ProtectColumn` instance for method chaining.
183
+ * @returns This `EncryptedColumn` instance for method chaining.
190
184
  *
191
185
  * @example
192
186
  * ```typescript
@@ -205,7 +199,7 @@ var ProtectColumn = class {
205
199
  * ORE allows sorting, comparison, and range queries on encrypted data.
206
200
  * Use with `encryptQuery` and `queryType: 'orderAndRange'`.
207
201
  *
208
- * @returns This `ProtectColumn` instance for method chaining.
202
+ * @returns This `EncryptedColumn` instance for method chaining.
209
203
  *
210
204
  * @example
211
205
  * ```typescript
@@ -228,7 +222,7 @@ var ProtectColumn = class {
228
222
  *
229
223
  * @param tokenFilters - Optional array of token filters (e.g. `[{ kind: 'downcase' }]`).
230
224
  * When omitted, no token filters are applied.
231
- * @returns This `ProtectColumn` instance for method chaining.
225
+ * @returns This `EncryptedColumn` instance for method chaining.
232
226
  *
233
227
  * @example
234
228
  * ```typescript
@@ -253,7 +247,7 @@ var ProtectColumn = class {
253
247
  *
254
248
  * @param opts - Optional match index configuration. Defaults to 3-character ngram
255
249
  * tokenization with a downcase filter, `k=6`, `m=2048`, and `include_original=true`.
256
- * @returns This `ProtectColumn` instance for method chaining.
250
+ * @returns This `EncryptedColumn` instance for method chaining.
257
251
  *
258
252
  * @example
259
253
  * ```typescript
@@ -298,7 +292,7 @@ var ProtectColumn = class {
298
292
  * the plaintext type: strings become selector queries, objects/arrays become
299
293
  * containment queries.
300
294
  *
301
- * @returns This `ProtectColumn` instance for method chaining.
295
+ * @returns This `EncryptedColumn` instance for method chaining.
302
296
  *
303
297
  * @example
304
298
  * ```typescript
@@ -316,7 +310,7 @@ var ProtectColumn = class {
316
310
  }
317
311
  build() {
318
312
  return {
319
- cast_as: this.castAsValue,
313
+ cast_as: this.castAsValue === "string" ? "text" : this.castAsValue,
320
314
  indexes: this.indexesValue
321
315
  };
322
316
  }
@@ -324,7 +318,7 @@ var ProtectColumn = class {
324
318
  return this.columnName;
325
319
  }
326
320
  };
327
- var ProtectTable = class {
321
+ var EncryptedTable = class {
328
322
  constructor(tableName, columnBuilders) {
329
323
  this.tableName = tableName;
330
324
  this.columnBuilders = columnBuilders;
@@ -351,7 +345,7 @@ var ProtectTable = class {
351
345
  build() {
352
346
  const builtColumns = {};
353
347
  const processColumn = (builder, colName) => {
354
- if (builder instanceof ProtectColumn) {
348
+ if (builder instanceof EncryptedColumn) {
355
349
  const builtColumn = builder.build();
356
350
  if (builtColumn.cast_as === "json" && builtColumn.indexes.ste_vec?.prefix === "enabled") {
357
351
  builtColumns[colName] = {
@@ -368,7 +362,7 @@ var ProtectTable = class {
368
362
  }
369
363
  } else {
370
364
  for (const [key, value] of Object.entries(builder)) {
371
- if (value instanceof ProtectValue) {
365
+ if (value instanceof EncryptedField) {
372
366
  builtColumns[value.getName()] = value.build();
373
367
  } else {
374
368
  processColumn(value, key);
@@ -386,7 +380,10 @@ var ProtectTable = class {
386
380
  }
387
381
  };
388
382
  function encryptedTable(tableName, columns) {
389
- const tableBuilder = new ProtectTable(tableName, columns);
383
+ const tableBuilder = new EncryptedTable(
384
+ tableName,
385
+ columns
386
+ );
390
387
  for (const [colName, colBuilder] of Object.entries(columns)) {
391
388
  ;
392
389
  tableBuilder[colName] = colBuilder;
@@ -394,7 +391,7 @@ function encryptedTable(tableName, columns) {
394
391
  return tableBuilder;
395
392
  }
396
393
  function encryptedColumn(columnName) {
397
- return new ProtectColumn(columnName);
394
+ return new EncryptedColumn(columnName);
398
395
  }
399
396
  function buildEncryptConfig(...protectTables) {
400
397
  const config = {
@@ -488,7 +485,7 @@ function initStackLogger(config) {
488
485
  const rates = samplingFromEnv();
489
486
  (0, import_evlog.initLogger)({
490
487
  env: { service: "@cipherstash/stack" },
491
- enabled: config?.enabled ?? true,
488
+ enabled: config?.enabled ?? !!rates,
492
489
  pretty: config?.pretty,
493
490
  ...rates && { sampling: { rates } },
494
491
  ...config?.drain && { drain: config.drain }
@@ -501,7 +498,11 @@ function safeMessage(args) {
501
498
  var logger = {
502
499
  debug(...args) {
503
500
  const log = (0, import_evlog.createRequestLogger)();
504
- log.set({ level: "debug", source: "@cipherstash/stack", message: safeMessage(args) });
501
+ log.set({
502
+ level: "debug",
503
+ source: "@cipherstash/stack",
504
+ message: safeMessage(args)
505
+ });
505
506
  log.emit();
506
507
  },
507
508
  info(...args) {
@@ -522,22 +523,22 @@ var logger = {
522
523
  }
523
524
  };
524
525
 
525
- // src/encryption/ffi/index.ts
526
+ // src/encryption/index.ts
526
527
  var import_result11 = require("@byteslice/result");
527
528
  var import_protect_ffi9 = require("@cipherstash/protect-ffi");
528
529
 
529
- // src/encryption/ffi/helpers/type-guards.ts
530
+ // src/encryption/helpers/type-guards.ts
530
531
  function isScalarQueryTermArray(value) {
531
532
  return Array.isArray(value) && value.length > 0 && typeof value[0] === "object" && value[0] !== null && "column" in value[0] && "table" in value[0];
532
533
  }
533
534
 
534
- // src/encryption/ffi/helpers/error-code.ts
535
+ // src/encryption/helpers/error-code.ts
535
536
  var import_protect_ffi = require("@cipherstash/protect-ffi");
536
537
  function getErrorCode(error) {
537
538
  return error instanceof import_protect_ffi.ProtectError ? error.code : void 0;
538
539
  }
539
540
 
540
- // src/encryption/ffi/operations/batch-encrypt-query.ts
541
+ // src/encryption/operations/batch-encrypt-query.ts
541
542
  var import_result = require("@byteslice/result");
542
543
  var import_protect_ffi2 = require("@cipherstash/protect-ffi");
543
544
 
@@ -555,7 +556,7 @@ var queryTypeToQueryOp = {
555
556
  steVecTerm: "ste_vec_term"
556
557
  };
557
558
 
558
- // src/encryption/ffi/helpers/infer-index-type.ts
559
+ // src/encryption/helpers/infer-index-type.ts
559
560
  function inferIndexType(column) {
560
561
  const config = column.build();
561
562
  const indexes = config.indexes;
@@ -615,7 +616,7 @@ function resolveIndexType(column, queryType, plaintext) {
615
616
  return { indexType };
616
617
  }
617
618
 
618
- // src/encryption/ffi/helpers/validation.ts
619
+ // src/encryption/helpers/validation.ts
619
620
  function validateNumericValue(value) {
620
621
  if (typeof value === "number" && Number.isNaN(value)) {
621
622
  return {
@@ -651,7 +652,7 @@ function assertValueIndexCompatibility(value, indexType, columnName) {
651
652
  }
652
653
  }
653
654
 
654
- // src/encryption/ffi/operations/base-operation.ts
655
+ // src/encryption/operations/base-operation.ts
655
656
  var EncryptionOperation = class {
656
657
  auditMetadata;
657
658
  /**
@@ -679,19 +680,7 @@ var EncryptionOperation = class {
679
680
  }
680
681
  };
681
682
 
682
- // src/encryption/ffi/operations/batch-encrypt-query.ts
683
- function filterNullTerms(terms) {
684
- const nullIndices = /* @__PURE__ */ new Set();
685
- const nonNullTerms = [];
686
- terms.forEach((term, index) => {
687
- if (term.value === null || term.value === void 0) {
688
- nullIndices.add(index);
689
- } else {
690
- nonNullTerms.push({ term, originalIndex: index });
691
- }
692
- });
693
- return { nullIndices, nonNullTerms };
694
- }
683
+ // src/encryption/operations/batch-encrypt-query.ts
695
684
  function buildQueryPayload(term, lockContext) {
696
685
  assertValidNumericValue(term.value);
697
686
  const { indexType, queryOp } = resolveIndexType(
@@ -712,13 +701,10 @@ function buildQueryPayload(term, lockContext) {
712
701
  }
713
702
  return payload;
714
703
  }
715
- function assembleResults(totalLength, encryptedValues, nonNullTerms) {
716
- const results = new Array(totalLength).fill(null);
717
- nonNullTerms.forEach(({ term, originalIndex }, i) => {
718
- const encrypted = encryptedValues[i];
719
- results[originalIndex] = formatEncryptedResult(encrypted, term.returnType);
720
- });
721
- return results;
704
+ function assembleResults(terms, encryptedValues) {
705
+ return terms.map(
706
+ (term, i) => formatEncryptedResult(encryptedValues[i], term.returnType)
707
+ );
722
708
  }
723
709
  var BatchEncryptQueryOperation = class extends EncryptionOperation {
724
710
  constructor(client, terms) {
@@ -745,23 +731,18 @@ var BatchEncryptQueryOperation = class extends EncryptionOperation {
745
731
  log.emit();
746
732
  return { data: [] };
747
733
  }
748
- const { nullIndices, nonNullTerms } = filterNullTerms(this.terms);
749
- if (nonNullTerms.length === 0) {
750
- log.emit();
751
- return { data: this.terms.map(() => null) };
752
- }
753
734
  const result = await (0, import_result.withResult)(
754
735
  async () => {
755
736
  if (!this.client) throw noClientError();
756
737
  const { metadata } = this.getAuditData();
757
- const queries = nonNullTerms.map(
758
- ({ term }) => buildQueryPayload(term)
738
+ const queries = this.terms.map(
739
+ (term) => buildQueryPayload(term)
759
740
  );
760
741
  const encrypted = await (0, import_protect_ffi2.encryptQueryBulk)(this.client, {
761
742
  queries,
762
743
  unverifiedContext: metadata
763
744
  });
764
- return assembleResults(this.terms.length, encrypted, nonNullTerms);
745
+ return assembleResults(this.terms, encrypted);
765
746
  },
766
747
  (error) => {
767
748
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -795,11 +776,6 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
795
776
  log.emit();
796
777
  return { data: [] };
797
778
  }
798
- const { nullIndices, nonNullTerms } = filterNullTerms(this.terms);
799
- if (nonNullTerms.length === 0) {
800
- log.emit();
801
- return { data: this.terms.map(() => null) };
802
- }
803
779
  const lockContextResult = await this.lockContext.getLockContext();
804
780
  if (lockContextResult.failure) {
805
781
  log.emit();
@@ -810,15 +786,15 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
810
786
  async () => {
811
787
  if (!this.client) throw noClientError();
812
788
  const { metadata } = this.getAuditData();
813
- const queries = nonNullTerms.map(
814
- ({ term }) => buildQueryPayload(term, context)
789
+ const queries = this.terms.map(
790
+ (term) => buildQueryPayload(term, context)
815
791
  );
816
792
  const encrypted = await (0, import_protect_ffi2.encryptQueryBulk)(this.client, {
817
793
  queries,
818
794
  serviceToken: ctsToken,
819
795
  unverifiedContext: metadata
820
796
  });
821
- return assembleResults(this.terms.length, encrypted, nonNullTerms);
797
+ return assembleResults(this.terms, encrypted);
822
798
  },
823
799
  (error) => {
824
800
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -834,46 +810,29 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
834
810
  }
835
811
  };
836
812
 
837
- // src/encryption/ffi/operations/bulk-decrypt.ts
813
+ // src/encryption/operations/bulk-decrypt.ts
838
814
  var import_result2 = require("@byteslice/result");
839
815
  var import_protect_ffi3 = require("@cipherstash/protect-ffi");
840
816
  var createDecryptPayloads = (encryptedPayloads, lockContext) => {
841
- return encryptedPayloads.map((item, index) => ({ ...item, originalIndex: index })).filter(({ data }) => data !== null).map(({ id, data, originalIndex }) => ({
817
+ return encryptedPayloads.map(({ id, data }) => ({
842
818
  id,
843
819
  ciphertext: data,
844
- originalIndex,
845
820
  ...lockContext && { lockContext }
846
821
  }));
847
822
  };
848
- var createNullResult = (encryptedPayloads) => {
849
- return encryptedPayloads.map(({ id }) => ({
850
- id,
851
- data: null
852
- }));
853
- };
854
823
  var mapDecryptedDataToResult = (encryptedPayloads, decryptedData) => {
855
- const result = new Array(encryptedPayloads.length);
856
- let decryptedIndex = 0;
857
- for (let i = 0; i < encryptedPayloads.length; i++) {
858
- if (encryptedPayloads[i].data === null) {
859
- result[i] = { id: encryptedPayloads[i].id, data: null };
860
- } else {
861
- const decryptResult = decryptedData[decryptedIndex];
862
- if ("error" in decryptResult) {
863
- result[i] = {
864
- id: encryptedPayloads[i].id,
865
- error: decryptResult.error
866
- };
867
- } else {
868
- result[i] = {
869
- id: encryptedPayloads[i].id,
870
- data: decryptResult.data
871
- };
872
- }
873
- decryptedIndex++;
824
+ return decryptedData.map((decryptResult, i) => {
825
+ if ("error" in decryptResult) {
826
+ return {
827
+ id: encryptedPayloads[i].id,
828
+ error: decryptResult.error
829
+ };
874
830
  }
875
- }
876
- return result;
831
+ return {
832
+ id: encryptedPayloads[i].id,
833
+ data: decryptResult.data
834
+ };
835
+ });
877
836
  };
878
837
  var BulkDecryptOperation = class extends EncryptionOperation {
879
838
  client;
@@ -898,13 +857,10 @@ var BulkDecryptOperation = class extends EncryptionOperation {
898
857
  if (!this.client) throw noClientError();
899
858
  if (!this.encryptedPayloads || this.encryptedPayloads.length === 0)
900
859
  return [];
901
- const nonNullPayloads = createDecryptPayloads(this.encryptedPayloads);
902
- if (nonNullPayloads.length === 0) {
903
- return createNullResult(this.encryptedPayloads);
904
- }
860
+ const payloads = createDecryptPayloads(this.encryptedPayloads);
905
861
  const { metadata } = this.getAuditData();
906
862
  const decryptedData = await (0, import_protect_ffi3.decryptBulkFallible)(this.client, {
907
- ciphertexts: nonNullPayloads,
863
+ ciphertexts: payloads,
908
864
  unverifiedContext: metadata
909
865
  });
910
866
  return mapDecryptedDataToResult(this.encryptedPayloads, decryptedData);
@@ -956,16 +912,13 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
956
912
  if (context.failure) {
957
913
  throw new Error(`[encryption]: ${context.failure.message}`);
958
914
  }
959
- const nonNullPayloads = createDecryptPayloads(
915
+ const payloads = createDecryptPayloads(
960
916
  encryptedPayloads,
961
917
  context.data.context
962
918
  );
963
- if (nonNullPayloads.length === 0) {
964
- return createNullResult(encryptedPayloads);
965
- }
966
919
  const { metadata } = this.getAuditData();
967
920
  const decryptedData = await (0, import_protect_ffi3.decryptBulkFallible)(client, {
968
- ciphertexts: nonNullPayloads,
921
+ ciphertexts: payloads,
969
922
  serviceToken: context.data.ctsToken,
970
923
  unverifiedContext: metadata
971
924
  });
@@ -985,10 +938,10 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
985
938
  }
986
939
  };
987
940
 
988
- // src/encryption/ffi/operations/bulk-decrypt-models.ts
941
+ // src/encryption/operations/bulk-decrypt-models.ts
989
942
  var import_result3 = require("@byteslice/result");
990
943
 
991
- // src/encryption/ffi/model-helpers.ts
944
+ // src/encryption/helpers/model-helpers.ts
992
945
  var import_protect_ffi4 = require("@cipherstash/protect-ffi");
993
946
  function setNestedValue(obj, path2, value) {
994
947
  const FORBIDDEN_KEYS = ["__proto__", "prototype", "constructor"];
@@ -1503,7 +1456,7 @@ async function bulkEncryptModelsWithLockContext(models, table, client, lockConte
1503
1456
  });
1504
1457
  }
1505
1458
 
1506
- // src/encryption/ffi/operations/bulk-decrypt-models.ts
1459
+ // src/encryption/operations/bulk-decrypt-models.ts
1507
1460
  var BulkDecryptModelsOperation = class extends EncryptionOperation {
1508
1461
  client;
1509
1462
  models;
@@ -1600,38 +1553,18 @@ var BulkDecryptModelsOperationWithLockContext = class extends EncryptionOperatio
1600
1553
  }
1601
1554
  };
1602
1555
 
1603
- // src/encryption/ffi/operations/bulk-encrypt.ts
1556
+ // src/encryption/operations/bulk-encrypt.ts
1604
1557
  var import_result4 = require("@byteslice/result");
1605
1558
  var import_protect_ffi5 = require("@cipherstash/protect-ffi");
1606
1559
  var createEncryptPayloads = (plaintexts, column, table, lockContext) => {
1607
- return plaintexts.map((item, index) => ({ ...item, originalIndex: index })).filter(({ plaintext }) => plaintext !== null).map(({ id, plaintext, originalIndex }) => ({
1560
+ return plaintexts.map(({ id, plaintext }) => ({
1608
1561
  id,
1609
1562
  plaintext,
1610
1563
  column: column.getName(),
1611
1564
  table: table.tableName,
1612
- originalIndex,
1613
1565
  ...lockContext && { lockContext }
1614
1566
  }));
1615
1567
  };
1616
- var createNullResult2 = (plaintexts) => {
1617
- return plaintexts.map(({ id }) => ({ id, data: null }));
1618
- };
1619
- var mapEncryptedDataToResult = (plaintexts, encryptedData) => {
1620
- const result = new Array(plaintexts.length);
1621
- let encryptedIndex = 0;
1622
- for (let i = 0; i < plaintexts.length; i++) {
1623
- if (plaintexts[i].plaintext === null) {
1624
- result[i] = { id: plaintexts[i].id, data: null };
1625
- } else {
1626
- result[i] = {
1627
- id: plaintexts[i].id,
1628
- data: encryptedData[encryptedIndex]
1629
- };
1630
- encryptedIndex++;
1631
- }
1632
- }
1633
- return result;
1634
- };
1635
1568
  var BulkEncryptOperation = class extends EncryptionOperation {
1636
1569
  client;
1637
1570
  plaintexts;
@@ -1664,20 +1597,20 @@ var BulkEncryptOperation = class extends EncryptionOperation {
1664
1597
  if (!this.plaintexts || this.plaintexts.length === 0) {
1665
1598
  return [];
1666
1599
  }
1667
- const nonNullPayloads = createEncryptPayloads(
1600
+ const payloads = createEncryptPayloads(
1668
1601
  this.plaintexts,
1669
1602
  this.column,
1670
1603
  this.table
1671
1604
  );
1672
- if (nonNullPayloads.length === 0) {
1673
- return createNullResult2(this.plaintexts);
1674
- }
1675
1605
  const { metadata } = this.getAuditData();
1676
1606
  const encryptedData = await (0, import_protect_ffi5.encryptBulk)(this.client, {
1677
- plaintexts: nonNullPayloads,
1607
+ plaintexts: payloads,
1678
1608
  unverifiedContext: metadata
1679
1609
  });
1680
- return mapEncryptedDataToResult(this.plaintexts, encryptedData);
1610
+ return encryptedData.map((data, i) => ({
1611
+ id: this.plaintexts[i].id,
1612
+ data
1613
+ }));
1681
1614
  },
1682
1615
  (error) => {
1683
1616
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -1734,22 +1667,22 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1734
1667
  if (context.failure) {
1735
1668
  throw new Error(`[encryption]: ${context.failure.message}`);
1736
1669
  }
1737
- const nonNullPayloads = createEncryptPayloads(
1670
+ const payloads = createEncryptPayloads(
1738
1671
  plaintexts,
1739
1672
  column,
1740
1673
  table,
1741
1674
  context.data.context
1742
1675
  );
1743
- if (nonNullPayloads.length === 0) {
1744
- return createNullResult2(plaintexts);
1745
- }
1746
1676
  const { metadata } = this.getAuditData();
1747
1677
  const encryptedData = await (0, import_protect_ffi5.encryptBulk)(client, {
1748
- plaintexts: nonNullPayloads,
1678
+ plaintexts: payloads,
1749
1679
  serviceToken: context.data.ctsToken,
1750
1680
  unverifiedContext: metadata
1751
1681
  });
1752
- return mapEncryptedDataToResult(plaintexts, encryptedData);
1682
+ return encryptedData.map((data, i) => ({
1683
+ id: plaintexts[i].id,
1684
+ data
1685
+ }));
1753
1686
  },
1754
1687
  (error) => {
1755
1688
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -1765,7 +1698,7 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1765
1698
  }
1766
1699
  };
1767
1700
 
1768
- // src/encryption/ffi/operations/bulk-encrypt-models.ts
1701
+ // src/encryption/operations/bulk-encrypt-models.ts
1769
1702
  var import_result5 = require("@byteslice/result");
1770
1703
  var BulkEncryptModelsOperation = class extends EncryptionOperation {
1771
1704
  client;
@@ -1874,7 +1807,7 @@ var BulkEncryptModelsOperationWithLockContext = class extends EncryptionOperatio
1874
1807
  }
1875
1808
  };
1876
1809
 
1877
- // src/encryption/ffi/operations/decrypt.ts
1810
+ // src/encryption/operations/decrypt.ts
1878
1811
  var import_result6 = require("@byteslice/result");
1879
1812
  var import_protect_ffi6 = require("@cipherstash/protect-ffi");
1880
1813
  var DecryptOperation = class extends EncryptionOperation {
@@ -1899,9 +1832,6 @@ var DecryptOperation = class extends EncryptionOperation {
1899
1832
  if (!this.client) {
1900
1833
  throw noClientError();
1901
1834
  }
1902
- if (this.encryptedData === null) {
1903
- return null;
1904
- }
1905
1835
  const { metadata } = this.getAuditData();
1906
1836
  return await (0, import_protect_ffi6.decrypt)(this.client, {
1907
1837
  ciphertext: this.encryptedData,
@@ -1952,9 +1882,6 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
1952
1882
  if (!client) {
1953
1883
  throw noClientError();
1954
1884
  }
1955
- if (encryptedData === null) {
1956
- return null;
1957
- }
1958
1885
  const { metadata } = this.getAuditData();
1959
1886
  const context = await this.lockContext.getLockContext();
1960
1887
  if (context.failure) {
@@ -1981,7 +1908,7 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
1981
1908
  }
1982
1909
  };
1983
1910
 
1984
- // src/encryption/ffi/operations/decrypt-model.ts
1911
+ // src/encryption/operations/decrypt-model.ts
1985
1912
  var import_result7 = require("@byteslice/result");
1986
1913
  var DecryptModelOperation = class extends EncryptionOperation {
1987
1914
  client;
@@ -2077,7 +2004,7 @@ var DecryptModelOperationWithLockContext = class extends EncryptionOperation {
2077
2004
  }
2078
2005
  };
2079
2006
 
2080
- // src/encryption/ffi/operations/encrypt.ts
2007
+ // src/encryption/operations/encrypt.ts
2081
2008
  var import_result8 = require("@byteslice/result");
2082
2009
  var import_protect_ffi7 = require("@cipherstash/protect-ffi");
2083
2010
  var EncryptOperation = class extends EncryptionOperation {
@@ -2108,9 +2035,6 @@ var EncryptOperation = class extends EncryptionOperation {
2108
2035
  if (!this.client) {
2109
2036
  throw noClientError();
2110
2037
  }
2111
- if (this.plaintext === null) {
2112
- return null;
2113
- }
2114
2038
  if (typeof this.plaintext === "number" && Number.isNaN(this.plaintext)) {
2115
2039
  throw new Error("[encryption]: Cannot encrypt NaN value");
2116
2040
  }
@@ -2172,9 +2096,6 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
2172
2096
  if (!client) {
2173
2097
  throw noClientError();
2174
2098
  }
2175
- if (plaintext === null) {
2176
- return null;
2177
- }
2178
2099
  const { metadata } = this.getAuditData();
2179
2100
  const context = await this.lockContext.getLockContext();
2180
2101
  if (context.failure) {
@@ -2203,7 +2124,7 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
2203
2124
  }
2204
2125
  };
2205
2126
 
2206
- // src/encryption/ffi/operations/encrypt-model.ts
2127
+ // src/encryption/operations/encrypt-model.ts
2207
2128
  var import_result9 = require("@byteslice/result");
2208
2129
  var EncryptModelOperation = class extends EncryptionOperation {
2209
2130
  client;
@@ -2310,7 +2231,7 @@ var EncryptModelOperationWithLockContext = class extends EncryptionOperation {
2310
2231
  }
2311
2232
  };
2312
2233
 
2313
- // src/encryption/ffi/operations/encrypt-query.ts
2234
+ // src/encryption/operations/encrypt-query.ts
2314
2235
  var import_result10 = require("@byteslice/result");
2315
2236
  var import_protect_ffi8 = require("@cipherstash/protect-ffi");
2316
2237
  var EncryptQueryOperation = class extends EncryptionOperation {
@@ -2338,10 +2259,6 @@ var EncryptQueryOperation = class extends EncryptionOperation {
2338
2259
  queryType: this.opts.queryType,
2339
2260
  lockContext: false
2340
2261
  });
2341
- if (this.plaintext === null || this.plaintext === void 0) {
2342
- log.emit();
2343
- return { data: null };
2344
- }
2345
2262
  const validationError = validateNumericValue(this.plaintext);
2346
2263
  if (validationError?.failure) {
2347
2264
  log.emit();
@@ -2405,10 +2322,6 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
2405
2322
  queryType: this.opts.queryType,
2406
2323
  lockContext: true
2407
2324
  });
2408
- if (this.plaintext === null || this.plaintext === void 0) {
2409
- log.emit();
2410
- return { data: null };
2411
- }
2412
2325
  const validationError = validateNumericValue(this.plaintext);
2413
2326
  if (validationError?.failure) {
2414
2327
  log.emit();
@@ -2460,9 +2373,9 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
2460
2373
  }
2461
2374
  };
2462
2375
 
2463
- // src/encryption/ffi/index.ts
2376
+ // src/encryption/index.ts
2464
2377
  var noClientError = () => new Error(
2465
- "The EQL client has not been initialized. Please call init() before using the client."
2378
+ "The Encryption client has not been initialized. Please call init() before using the client."
2466
2379
  );
2467
2380
  var EncryptionClient = class {
2468
2381
  client;
@@ -2485,7 +2398,7 @@ var EncryptionClient = class {
2485
2398
  config.encryptConfig
2486
2399
  );
2487
2400
  logger.debug(
2488
- "Initializing the Protect.js client with the following encrypt config:",
2401
+ "Initializing the Encryption client with the following config:",
2489
2402
  {
2490
2403
  encryptConfig: validated
2491
2404
  }
@@ -2501,7 +2414,7 @@ var EncryptionClient = class {
2501
2414
  }
2502
2415
  });
2503
2416
  this.encryptConfig = validated;
2504
- logger.debug("Successfully initialized the Protect.js client.");
2417
+ logger.debug("Successfully initialized the Encryption client.");
2505
2418
  return this;
2506
2419
  },
2507
2420
  (error) => ({
@@ -2513,8 +2426,8 @@ var EncryptionClient = class {
2513
2426
  /**
2514
2427
  * Encrypt a value - returns a promise which resolves to an encrypted value.
2515
2428
  *
2516
- * @param plaintext - The plaintext value to be encrypted. Can be null.
2517
- * @param opts - Options specifying the column and table for encryption.
2429
+ * @param plaintext - The plaintext value to be encrypted.
2430
+ * @param opts - Options specifying the column (or nested field) and table for encryption. See {@link EncryptOptions}.
2518
2431
  * @returns An EncryptOperation that can be awaited or chained with additional methods.
2519
2432
  *
2520
2433
  * @example
@@ -2577,8 +2490,11 @@ var EncryptionClient = class {
2577
2490
  * .withLockContext(lockContext)
2578
2491
  * ```
2579
2492
  *
2493
+ * @see {@link EncryptOptions}
2580
2494
  * @see {@link Result}
2581
2495
  * @see {@link encryptedTable}
2496
+ * @see {@link encryptedColumn}
2497
+ * @see {@link encryptedField}
2582
2498
  * @see {@link LockContext}
2583
2499
  * @see {@link EncryptOperation}
2584
2500
  */
@@ -2686,7 +2602,11 @@ var EncryptionClient = class {
2686
2602
  * ```
2687
2603
  */
2688
2604
  encryptModel(input, table) {
2689
- return new EncryptModelOperation(this.client, input, table);
2605
+ return new EncryptModelOperation(
2606
+ this.client,
2607
+ input,
2608
+ table
2609
+ );
2690
2610
  }
2691
2611
  /**
2692
2612
  * Decrypt a model (object) whose fields contain encrypted values.
@@ -2765,7 +2685,11 @@ var EncryptionClient = class {
2765
2685
  * ```
2766
2686
  */
2767
2687
  bulkEncryptModels(input, table) {
2768
- return new BulkEncryptModelsOperation(this.client, input, table);
2688
+ return new BulkEncryptModelsOperation(
2689
+ this.client,
2690
+ input,
2691
+ table
2692
+ );
2769
2693
  }
2770
2694
  /**
2771
2695
  * Decrypt multiple models (objects) in a single bulk operation.
@@ -2803,10 +2727,10 @@ var EncryptionClient = class {
2803
2727
  *
2804
2728
  * Each value is encrypted with its own unique key via a single call to ZeroKMS.
2805
2729
  * Values can include optional `id` fields for correlating results back to
2806
- * your application data. Null plaintext values are preserved as null.
2730
+ * your application data.
2807
2731
  *
2808
2732
  * @param plaintexts - An array of objects with `plaintext` (and optional `id`) fields.
2809
- * @param opts - Options specifying the target column and table for encryption.
2733
+ * @param opts - Options specifying the target column (or nested {@link encryptedField}) and table. See {@link EncryptOptions}.
2810
2734
  * @returns A `BulkEncryptOperation` that can be awaited to get a `Result`
2811
2735
  * containing an array of `{ id?, data: Encrypted }` objects, or an `EncryptionError`.
2812
2736
  *
@@ -2824,7 +2748,6 @@ var EncryptionClient = class {
2824
2748
  * [
2825
2749
  * { id: "u1", plaintext: "alice@example.com" },
2826
2750
  * { id: "u2", plaintext: "bob@example.com" },
2827
- * { id: "u3", plaintext: null },
2828
2751
  * ],
2829
2752
  * { column: users.email, table: users },
2830
2753
  * )