@cipherstash/stack 0.3.0 → 0.5.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 (93) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +10 -37
  3. package/dist/bin/stash.js +261 -320
  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-OAPLZLR5.js → chunk-GXGEW6T4.js} +2 -76
  8. package/dist/chunk-GXGEW6T4.js.map +1 -0
  9. package/dist/{chunk-JLI27P46.js → chunk-HCL75LXQ.js} +1 -1
  10. package/dist/chunk-HCL75LXQ.js.map +1 -0
  11. package/dist/chunk-LBMC4D6D.js +19 -0
  12. package/dist/chunk-LBMC4D6D.js.map +1 -0
  13. package/dist/chunk-Q5FTQLYG.js +68 -0
  14. package/dist/chunk-Q5FTQLYG.js.map +1 -0
  15. package/dist/{chunk-MW6D52V2.js → chunk-TGUELLJS.js} +58 -150
  16. package/dist/chunk-TGUELLJS.js.map +1 -0
  17. package/dist/{chunk-TBAIVO6T.js → chunk-Y35W4WFN.js} +6 -6
  18. package/dist/chunk-Y35W4WFN.js.map +1 -0
  19. package/dist/chunk-YLISU7FD.js +357 -0
  20. package/dist/chunk-YLISU7FD.js.map +1 -0
  21. package/dist/{client-Bf0Xw2xo.d.cts → client-BFrHTgC6.d.ts} +50 -18
  22. package/dist/{client-Kfp8OsPB.d.ts → client-BVQvgvdY.d.cts} +50 -18
  23. package/dist/client.cjs +5 -5
  24. package/dist/client.cjs.map +1 -1
  25. package/dist/client.d.cts +4 -4
  26. package/dist/client.d.ts +4 -4
  27. package/dist/client.js +1 -1
  28. package/dist/drizzle/index.cjs +5 -5
  29. package/dist/drizzle/index.cjs.map +1 -1
  30. package/dist/drizzle/index.d.cts +14 -6
  31. package/dist/drizzle/index.d.ts +14 -6
  32. package/dist/drizzle/index.js +4 -4
  33. package/dist/drizzle/index.js.map +1 -1
  34. package/dist/dynamodb/index.cjs +68 -0
  35. package/dist/dynamodb/index.cjs.map +1 -1
  36. package/dist/dynamodb/index.d.cts +4 -4
  37. package/dist/dynamodb/index.d.ts +4 -4
  38. package/dist/dynamodb/index.js +9 -0
  39. package/dist/dynamodb/index.js.map +1 -1
  40. package/dist/encryption/index.cjs +2572 -0
  41. package/dist/encryption/index.cjs.map +1 -0
  42. package/dist/encryption/index.d.cts +7 -0
  43. package/dist/encryption/index.d.ts +7 -0
  44. package/dist/encryption/index.js +17 -0
  45. package/dist/encryption/index.js.map +1 -0
  46. package/dist/errors/index.cjs +44 -0
  47. package/dist/errors/index.cjs.map +1 -0
  48. package/dist/errors/index.d.cts +94 -0
  49. package/dist/errors/index.d.ts +94 -0
  50. package/dist/errors/index.js +9 -0
  51. package/dist/errors/index.js.map +1 -0
  52. package/dist/identity/index.cjs +21 -13
  53. package/dist/identity/index.cjs.map +1 -1
  54. package/dist/identity/index.d.cts +78 -2
  55. package/dist/identity/index.d.ts +78 -2
  56. package/dist/identity/index.js +7 -3
  57. package/dist/identity/index.js.map +1 -1
  58. package/dist/index.cjs +425 -182
  59. package/dist/index.cjs.map +1 -1
  60. package/dist/index.d.cts +21 -19
  61. package/dist/index.d.ts +21 -19
  62. package/dist/index.js +15 -9
  63. package/dist/schema/index.cjs +5 -5
  64. package/dist/schema/index.cjs.map +1 -1
  65. package/dist/schema/index.d.cts +1 -2
  66. package/dist/schema/index.d.ts +1 -2
  67. package/dist/schema/index.js +1 -1
  68. package/dist/secrets/index.cjs +116 -180
  69. package/dist/secrets/index.cjs.map +1 -1
  70. package/dist/secrets/index.d.cts +4 -6
  71. package/dist/secrets/index.d.ts +4 -6
  72. package/dist/secrets/index.js +9 -318
  73. package/dist/secrets/index.js.map +1 -1
  74. package/dist/supabase/index.cjs +86 -3
  75. package/dist/supabase/index.cjs.map +1 -1
  76. package/dist/supabase/index.d.cts +4 -4
  77. package/dist/supabase/index.d.ts +4 -4
  78. package/dist/supabase/index.js +26 -3
  79. package/dist/supabase/index.js.map +1 -1
  80. package/dist/{types-public-0CzBV45X.d.cts → types-public-dKxDzTIL.d.cts} +47 -34
  81. package/dist/{types-public-0CzBV45X.d.ts → types-public-dKxDzTIL.d.ts} +47 -34
  82. package/dist/types-public.cjs.map +1 -1
  83. package/dist/types-public.d.cts +1 -2
  84. package/dist/types-public.d.ts +1 -2
  85. package/dist/types-public.js +1 -1
  86. package/package.json +30 -2
  87. package/dist/chunk-JLI27P46.js.map +0 -1
  88. package/dist/chunk-MW6D52V2.js.map +0 -1
  89. package/dist/chunk-OAPLZLR5.js.map +0 -1
  90. package/dist/chunk-SUYMGQBY.js.map +0 -1
  91. package/dist/chunk-TBAIVO6T.js.map +0 -1
  92. package/dist/index-9-Ya3fDK.d.cts +0 -169
  93. package/dist/index-9-Ya3fDK.d.ts +0 -169
@@ -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) {
@@ -78,18 +72,9 @@ function isEncryptedPayload(value) {
78
72
  return true;
79
73
  }
80
74
 
81
- // src/errors/index.ts
82
- var EncryptionErrorTypes = {
83
- ClientInitError: "ClientInitError",
84
- EncryptionError: "EncryptionError",
85
- DecryptionError: "DecryptionError",
86
- LockContextError: "LockContextError",
87
- CtsTokenError: "CtsTokenError"
88
- };
89
-
90
75
  // src/schema/index.ts
91
76
  var import_zod = require("zod");
92
- var castAsEnum = import_zod.z.enum(["bigint", "boolean", "date", "number", "string", "json"]).default("string");
77
+ var castAsEnum = import_zod.z.enum(["bigint", "boolean", "date", "number", "string", "json", "text"]).default("text");
93
78
  var tokenFilterSchema = import_zod.z.object({
94
79
  kind: import_zod.z.literal("downcase")
95
80
  });
@@ -137,7 +122,7 @@ var EncryptedField = class {
137
122
  castAsValue;
138
123
  constructor(valueName) {
139
124
  this.valueName = valueName;
140
- this.castAsValue = "string";
125
+ this.castAsValue = "text";
141
126
  }
142
127
  /**
143
128
  * Set or override the plaintext data type for this field.
@@ -146,7 +131,7 @@ var EncryptedField = class {
146
131
  * a different type so the encryption layer knows how to encode the plaintext
147
132
  * before encrypting.
148
133
  *
149
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
134
+ * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'text'`, `'bigint'`, or `'json'`.
150
135
  * @returns This `EncryptedField` instance for method chaining.
151
136
  *
152
137
  * @example
@@ -162,7 +147,7 @@ var EncryptedField = class {
162
147
  }
163
148
  build() {
164
149
  return {
165
- cast_as: this.castAsValue,
150
+ cast_as: this.castAsValue === "string" ? "text" : this.castAsValue,
166
151
  indexes: {}
167
152
  };
168
153
  }
@@ -316,7 +301,7 @@ var EncryptedColumn = class {
316
301
  }
317
302
  build() {
318
303
  return {
319
- cast_as: this.castAsValue,
304
+ cast_as: this.castAsValue === "string" ? "text" : this.castAsValue,
320
305
  indexes: this.indexesValue
321
306
  };
322
307
  }
@@ -411,6 +396,15 @@ function buildEncryptConfig(...protectTables) {
411
396
  return config;
412
397
  }
413
398
 
399
+ // src/errors/index.ts
400
+ var EncryptionErrorTypes = {
401
+ ClientInitError: "ClientInitError",
402
+ EncryptionError: "EncryptionError",
403
+ DecryptionError: "DecryptionError",
404
+ LockContextError: "LockContextError",
405
+ CtsTokenError: "CtsTokenError"
406
+ };
407
+
414
408
  // src/utils/config/index.ts
415
409
  var import_node_fs = __toESM(require("fs"), 1);
416
410
  var import_node_path = __toESM(require("path"), 1);
@@ -476,25 +470,33 @@ function loadWorkSpaceId(suppliedCrn) {
476
470
 
477
471
  // src/utils/logger/index.ts
478
472
  var import_evlog = require("evlog");
479
- function samplingFromEnv() {
480
- const env = process.env.STASH_LOG_LEVEL;
481
- if (!env) return void 0;
482
- const levels = ["debug", "info", "warn", "error"];
483
- const idx = levels.indexOf(env);
484
- if (idx === -1) return void 0;
485
- return Object.fromEntries(levels.map((l, i) => [l, i >= idx ? 100 : 0]));
473
+ var validLevels = ["debug", "info", "error"];
474
+ function levelFromEnv() {
475
+ const env = process.env.STASH_STACK_LOG;
476
+ if (env && validLevels.includes(env)) return env;
477
+ return "error";
478
+ }
479
+ function samplingRatesForLevel(level) {
480
+ switch (level) {
481
+ case "debug":
482
+ return { debug: 100, info: 100, warn: 100, error: 100 };
483
+ case "info":
484
+ return { debug: 0, info: 100, warn: 100, error: 100 };
485
+ case "error":
486
+ default:
487
+ return { debug: 0, info: 0, warn: 0, error: 100 };
488
+ }
486
489
  }
487
490
  var initialized = false;
488
- function initStackLogger(config) {
491
+ function initStackLogger() {
489
492
  if (initialized) return;
490
493
  initialized = true;
491
- const rates = samplingFromEnv();
494
+ const level = levelFromEnv();
495
+ const rates = samplingRatesForLevel(level);
492
496
  (0, import_evlog.initLogger)({
493
497
  env: { service: "@cipherstash/stack" },
494
- enabled: config?.enabled ?? !!rates,
495
- pretty: config?.pretty,
496
- ...rates && { sampling: { rates } },
497
- ...config?.drain && { drain: config.drain }
498
+ enabled: true,
499
+ sampling: { rates }
498
500
  });
499
501
  }
500
502
  initStackLogger();
@@ -532,6 +534,7 @@ var logger = {
532
534
  // src/encryption/index.ts
533
535
  var import_result11 = require("@byteslice/result");
534
536
  var import_protect_ffi9 = require("@cipherstash/protect-ffi");
537
+ var import_uuid = require("uuid");
535
538
 
536
539
  // src/encryption/helpers/type-guards.ts
537
540
  function isScalarQueryTermArray(value) {
@@ -687,18 +690,6 @@ var EncryptionOperation = class {
687
690
  };
688
691
 
689
692
  // src/encryption/operations/batch-encrypt-query.ts
690
- function filterNullTerms(terms) {
691
- const nullIndices = /* @__PURE__ */ new Set();
692
- const nonNullTerms = [];
693
- terms.forEach((term, index) => {
694
- if (term.value === null || term.value === void 0) {
695
- nullIndices.add(index);
696
- } else {
697
- nonNullTerms.push({ term, originalIndex: index });
698
- }
699
- });
700
- return { nullIndices, nonNullTerms };
701
- }
702
693
  function buildQueryPayload(term, lockContext) {
703
694
  assertValidNumericValue(term.value);
704
695
  const { indexType, queryOp } = resolveIndexType(
@@ -719,13 +710,10 @@ function buildQueryPayload(term, lockContext) {
719
710
  }
720
711
  return payload;
721
712
  }
722
- function assembleResults(totalLength, encryptedValues, nonNullTerms) {
723
- const results = new Array(totalLength).fill(null);
724
- nonNullTerms.forEach(({ term, originalIndex }, i) => {
725
- const encrypted = encryptedValues[i];
726
- results[originalIndex] = formatEncryptedResult(encrypted, term.returnType);
727
- });
728
- return results;
713
+ function assembleResults(terms, encryptedValues) {
714
+ return terms.map(
715
+ (term, i) => formatEncryptedResult(encryptedValues[i], term.returnType)
716
+ );
729
717
  }
730
718
  var BatchEncryptQueryOperation = class extends EncryptionOperation {
731
719
  constructor(client, terms) {
@@ -752,23 +740,18 @@ var BatchEncryptQueryOperation = class extends EncryptionOperation {
752
740
  log.emit();
753
741
  return { data: [] };
754
742
  }
755
- const { nullIndices, nonNullTerms } = filterNullTerms(this.terms);
756
- if (nonNullTerms.length === 0) {
757
- log.emit();
758
- return { data: this.terms.map(() => null) };
759
- }
760
743
  const result = await (0, import_result.withResult)(
761
744
  async () => {
762
745
  if (!this.client) throw noClientError();
763
746
  const { metadata } = this.getAuditData();
764
- const queries = nonNullTerms.map(
765
- ({ term }) => buildQueryPayload(term)
747
+ const queries = this.terms.map(
748
+ (term) => buildQueryPayload(term)
766
749
  );
767
750
  const encrypted = await (0, import_protect_ffi2.encryptQueryBulk)(this.client, {
768
751
  queries,
769
752
  unverifiedContext: metadata
770
753
  });
771
- return assembleResults(this.terms.length, encrypted, nonNullTerms);
754
+ return assembleResults(this.terms, encrypted);
772
755
  },
773
756
  (error) => {
774
757
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -802,11 +785,6 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
802
785
  log.emit();
803
786
  return { data: [] };
804
787
  }
805
- const { nullIndices, nonNullTerms } = filterNullTerms(this.terms);
806
- if (nonNullTerms.length === 0) {
807
- log.emit();
808
- return { data: this.terms.map(() => null) };
809
- }
810
788
  const lockContextResult = await this.lockContext.getLockContext();
811
789
  if (lockContextResult.failure) {
812
790
  log.emit();
@@ -817,15 +795,15 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
817
795
  async () => {
818
796
  if (!this.client) throw noClientError();
819
797
  const { metadata } = this.getAuditData();
820
- const queries = nonNullTerms.map(
821
- ({ term }) => buildQueryPayload(term, context)
798
+ const queries = this.terms.map(
799
+ (term) => buildQueryPayload(term, context)
822
800
  );
823
801
  const encrypted = await (0, import_protect_ffi2.encryptQueryBulk)(this.client, {
824
802
  queries,
825
803
  serviceToken: ctsToken,
826
804
  unverifiedContext: metadata
827
805
  });
828
- return assembleResults(this.terms.length, encrypted, nonNullTerms);
806
+ return assembleResults(this.terms, encrypted);
829
807
  },
830
808
  (error) => {
831
809
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -845,42 +823,25 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
845
823
  var import_result2 = require("@byteslice/result");
846
824
  var import_protect_ffi3 = require("@cipherstash/protect-ffi");
847
825
  var createDecryptPayloads = (encryptedPayloads, lockContext) => {
848
- return encryptedPayloads.map((item, index) => ({ ...item, originalIndex: index })).filter(({ data }) => data !== null).map(({ id, data, originalIndex }) => ({
826
+ return encryptedPayloads.map(({ id, data }) => ({
849
827
  id,
850
828
  ciphertext: data,
851
- originalIndex,
852
829
  ...lockContext && { lockContext }
853
830
  }));
854
831
  };
855
- var createNullResult = (encryptedPayloads) => {
856
- return encryptedPayloads.map(({ id }) => ({
857
- id,
858
- data: null
859
- }));
860
- };
861
832
  var mapDecryptedDataToResult = (encryptedPayloads, decryptedData) => {
862
- const result = new Array(encryptedPayloads.length);
863
- let decryptedIndex = 0;
864
- for (let i = 0; i < encryptedPayloads.length; i++) {
865
- if (encryptedPayloads[i].data === null) {
866
- result[i] = { id: encryptedPayloads[i].id, data: null };
867
- } else {
868
- const decryptResult = decryptedData[decryptedIndex];
869
- if ("error" in decryptResult) {
870
- result[i] = {
871
- id: encryptedPayloads[i].id,
872
- error: decryptResult.error
873
- };
874
- } else {
875
- result[i] = {
876
- id: encryptedPayloads[i].id,
877
- data: decryptResult.data
878
- };
879
- }
880
- decryptedIndex++;
833
+ return decryptedData.map((decryptResult, i) => {
834
+ if ("error" in decryptResult) {
835
+ return {
836
+ id: encryptedPayloads[i].id,
837
+ error: decryptResult.error
838
+ };
881
839
  }
882
- }
883
- return result;
840
+ return {
841
+ id: encryptedPayloads[i].id,
842
+ data: decryptResult.data
843
+ };
844
+ });
884
845
  };
885
846
  var BulkDecryptOperation = class extends EncryptionOperation {
886
847
  client;
@@ -905,13 +866,10 @@ var BulkDecryptOperation = class extends EncryptionOperation {
905
866
  if (!this.client) throw noClientError();
906
867
  if (!this.encryptedPayloads || this.encryptedPayloads.length === 0)
907
868
  return [];
908
- const nonNullPayloads = createDecryptPayloads(this.encryptedPayloads);
909
- if (nonNullPayloads.length === 0) {
910
- return createNullResult(this.encryptedPayloads);
911
- }
869
+ const payloads = createDecryptPayloads(this.encryptedPayloads);
912
870
  const { metadata } = this.getAuditData();
913
871
  const decryptedData = await (0, import_protect_ffi3.decryptBulkFallible)(this.client, {
914
- ciphertexts: nonNullPayloads,
872
+ ciphertexts: payloads,
915
873
  unverifiedContext: metadata
916
874
  });
917
875
  return mapDecryptedDataToResult(this.encryptedPayloads, decryptedData);
@@ -963,16 +921,13 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
963
921
  if (context.failure) {
964
922
  throw new Error(`[encryption]: ${context.failure.message}`);
965
923
  }
966
- const nonNullPayloads = createDecryptPayloads(
924
+ const payloads = createDecryptPayloads(
967
925
  encryptedPayloads,
968
926
  context.data.context
969
927
  );
970
- if (nonNullPayloads.length === 0) {
971
- return createNullResult(encryptedPayloads);
972
- }
973
928
  const { metadata } = this.getAuditData();
974
929
  const decryptedData = await (0, import_protect_ffi3.decryptBulkFallible)(client, {
975
- ciphertexts: nonNullPayloads,
930
+ ciphertexts: payloads,
976
931
  serviceToken: context.data.ctsToken,
977
932
  unverifiedContext: metadata
978
933
  });
@@ -1611,34 +1566,14 @@ var BulkDecryptModelsOperationWithLockContext = class extends EncryptionOperatio
1611
1566
  var import_result4 = require("@byteslice/result");
1612
1567
  var import_protect_ffi5 = require("@cipherstash/protect-ffi");
1613
1568
  var createEncryptPayloads = (plaintexts, column, table, lockContext) => {
1614
- return plaintexts.map((item, index) => ({ ...item, originalIndex: index })).filter(({ plaintext }) => plaintext !== null).map(({ id, plaintext, originalIndex }) => ({
1569
+ return plaintexts.map(({ id, plaintext }) => ({
1615
1570
  id,
1616
1571
  plaintext,
1617
1572
  column: column.getName(),
1618
1573
  table: table.tableName,
1619
- originalIndex,
1620
1574
  ...lockContext && { lockContext }
1621
1575
  }));
1622
1576
  };
1623
- var createNullResult2 = (plaintexts) => {
1624
- return plaintexts.map(({ id }) => ({ id, data: null }));
1625
- };
1626
- var mapEncryptedDataToResult = (plaintexts, encryptedData) => {
1627
- const result = new Array(plaintexts.length);
1628
- let encryptedIndex = 0;
1629
- for (let i = 0; i < plaintexts.length; i++) {
1630
- if (plaintexts[i].plaintext === null) {
1631
- result[i] = { id: plaintexts[i].id, data: null };
1632
- } else {
1633
- result[i] = {
1634
- id: plaintexts[i].id,
1635
- data: encryptedData[encryptedIndex]
1636
- };
1637
- encryptedIndex++;
1638
- }
1639
- }
1640
- return result;
1641
- };
1642
1577
  var BulkEncryptOperation = class extends EncryptionOperation {
1643
1578
  client;
1644
1579
  plaintexts;
@@ -1671,20 +1606,20 @@ var BulkEncryptOperation = class extends EncryptionOperation {
1671
1606
  if (!this.plaintexts || this.plaintexts.length === 0) {
1672
1607
  return [];
1673
1608
  }
1674
- const nonNullPayloads = createEncryptPayloads(
1609
+ const payloads = createEncryptPayloads(
1675
1610
  this.plaintexts,
1676
1611
  this.column,
1677
1612
  this.table
1678
1613
  );
1679
- if (nonNullPayloads.length === 0) {
1680
- return createNullResult2(this.plaintexts);
1681
- }
1682
1614
  const { metadata } = this.getAuditData();
1683
1615
  const encryptedData = await (0, import_protect_ffi5.encryptBulk)(this.client, {
1684
- plaintexts: nonNullPayloads,
1616
+ plaintexts: payloads,
1685
1617
  unverifiedContext: metadata
1686
1618
  });
1687
- return mapEncryptedDataToResult(this.plaintexts, encryptedData);
1619
+ return encryptedData.map((data, i) => ({
1620
+ id: this.plaintexts[i].id,
1621
+ data
1622
+ }));
1688
1623
  },
1689
1624
  (error) => {
1690
1625
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -1741,22 +1676,22 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1741
1676
  if (context.failure) {
1742
1677
  throw new Error(`[encryption]: ${context.failure.message}`);
1743
1678
  }
1744
- const nonNullPayloads = createEncryptPayloads(
1679
+ const payloads = createEncryptPayloads(
1745
1680
  plaintexts,
1746
1681
  column,
1747
1682
  table,
1748
1683
  context.data.context
1749
1684
  );
1750
- if (nonNullPayloads.length === 0) {
1751
- return createNullResult2(plaintexts);
1752
- }
1753
1685
  const { metadata } = this.getAuditData();
1754
1686
  const encryptedData = await (0, import_protect_ffi5.encryptBulk)(client, {
1755
- plaintexts: nonNullPayloads,
1687
+ plaintexts: payloads,
1756
1688
  serviceToken: context.data.ctsToken,
1757
1689
  unverifiedContext: metadata
1758
1690
  });
1759
- return mapEncryptedDataToResult(plaintexts, encryptedData);
1691
+ return encryptedData.map((data, i) => ({
1692
+ id: plaintexts[i].id,
1693
+ data
1694
+ }));
1760
1695
  },
1761
1696
  (error) => {
1762
1697
  log.set({ errorCode: getErrorCode(error) ?? "unknown" });
@@ -1906,9 +1841,6 @@ var DecryptOperation = class extends EncryptionOperation {
1906
1841
  if (!this.client) {
1907
1842
  throw noClientError();
1908
1843
  }
1909
- if (this.encryptedData === null) {
1910
- return null;
1911
- }
1912
1844
  const { metadata } = this.getAuditData();
1913
1845
  return await (0, import_protect_ffi6.decrypt)(this.client, {
1914
1846
  ciphertext: this.encryptedData,
@@ -1959,9 +1891,6 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
1959
1891
  if (!client) {
1960
1892
  throw noClientError();
1961
1893
  }
1962
- if (encryptedData === null) {
1963
- return null;
1964
- }
1965
1894
  const { metadata } = this.getAuditData();
1966
1895
  const context = await this.lockContext.getLockContext();
1967
1896
  if (context.failure) {
@@ -2115,9 +2044,6 @@ var EncryptOperation = class extends EncryptionOperation {
2115
2044
  if (!this.client) {
2116
2045
  throw noClientError();
2117
2046
  }
2118
- if (this.plaintext === null) {
2119
- return null;
2120
- }
2121
2047
  if (typeof this.plaintext === "number" && Number.isNaN(this.plaintext)) {
2122
2048
  throw new Error("[encryption]: Cannot encrypt NaN value");
2123
2049
  }
@@ -2179,9 +2105,6 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
2179
2105
  if (!client) {
2180
2106
  throw noClientError();
2181
2107
  }
2182
- if (plaintext === null) {
2183
- return null;
2184
- }
2185
2108
  const { metadata } = this.getAuditData();
2186
2109
  const context = await this.lockContext.getLockContext();
2187
2110
  if (context.failure) {
@@ -2345,10 +2268,6 @@ var EncryptQueryOperation = class extends EncryptionOperation {
2345
2268
  queryType: this.opts.queryType,
2346
2269
  lockContext: false
2347
2270
  });
2348
- if (this.plaintext === null || this.plaintext === void 0) {
2349
- log.emit();
2350
- return { data: null };
2351
- }
2352
2271
  const validationError = validateNumericValue(this.plaintext);
2353
2272
  if (validationError?.failure) {
2354
2273
  log.emit();
@@ -2412,10 +2331,6 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
2412
2331
  queryType: this.opts.queryType,
2413
2332
  lockContext: true
2414
2333
  });
2415
- if (this.plaintext === null || this.plaintext === void 0) {
2416
- log.emit();
2417
- return { data: null };
2418
- }
2419
2334
  const validationError = validateNumericValue(this.plaintext);
2420
2335
  if (validationError?.failure) {
2421
2336
  log.emit();
@@ -2520,7 +2435,7 @@ var EncryptionClient = class {
2520
2435
  /**
2521
2436
  * Encrypt a value - returns a promise which resolves to an encrypted value.
2522
2437
  *
2523
- * @param plaintext - The plaintext value to be encrypted. Can be null.
2438
+ * @param plaintext - The plaintext value to be encrypted.
2524
2439
  * @param opts - Options specifying the column (or nested field) and table for encryption. See {@link EncryptOptions}.
2525
2440
  * @returns An EncryptOperation that can be awaited or chained with additional methods.
2526
2441
  *
@@ -2821,7 +2736,7 @@ var EncryptionClient = class {
2821
2736
  *
2822
2737
  * Each value is encrypted with its own unique key via a single call to ZeroKMS.
2823
2738
  * Values can include optional `id` fields for correlating results back to
2824
- * your application data. Null plaintext values are preserved as null.
2739
+ * your application data.
2825
2740
  *
2826
2741
  * @param plaintexts - An array of objects with `plaintext` (and optional `id`) fields.
2827
2742
  * @param opts - Options specifying the target column (or nested {@link encryptedField}) and table. See {@link EncryptOptions}.
@@ -2842,7 +2757,6 @@ var EncryptionClient = class {
2842
2757
  * [
2843
2758
  * { id: "u1", plaintext: "alice@example.com" },
2844
2759
  * { id: "u2", plaintext: "bob@example.com" },
2845
- * { id: "u3", plaintext: null },
2846
2760
  * ],
2847
2761
  * { column: users.email, table: users },
2848
2762
  * )
@@ -2896,23 +2810,14 @@ var EncryptionClient = class {
2896
2810
  };
2897
2811
  }
2898
2812
  };
2899
-
2900
- // src/index.ts
2901
- function isValidUuid(uuid) {
2902
- const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
2903
- return uuidRegex.test(uuid);
2904
- }
2905
2813
  var Encryption = async (config) => {
2906
- if (config.logging) {
2907
- initStackLogger(config.logging);
2908
- }
2909
2814
  const { schemas, config: clientConfig } = config;
2910
2815
  if (!schemas.length) {
2911
2816
  throw new Error(
2912
2817
  "[encryption]: At least one encryptedTable must be provided to initialize the encryption client"
2913
2818
  );
2914
2819
  }
2915
- if (clientConfig?.keyset && "id" in clientConfig.keyset && !isValidUuid(clientConfig.keyset.id)) {
2820
+ if (clientConfig?.keyset && "id" in clientConfig.keyset && !(0, import_uuid.validate)(clientConfig.keyset.id)) {
2916
2821
  throw new Error(
2917
2822
  "[encryption]: Invalid UUID provided for keyset id. Must be a valid UUID."
2918
2823
  );
@@ -2938,7 +2843,22 @@ var Secrets = class {
2938
2843
  value: encryptedColumn("value")
2939
2844
  });
2940
2845
  constructor(config) {
2941
- this.config = config;
2846
+ const workspaceCRN = config.workspaceCRN ?? process.env.CS_WORKSPACE_CRN;
2847
+ const clientId = config.clientId ?? process.env.CS_CLIENT_ID;
2848
+ const clientKey = config.clientKey ?? process.env.CS_CLIENT_KEY;
2849
+ const accessKey = config.accessKey ?? process.env.CS_CLIENT_ACCESS_KEY;
2850
+ if (!workspaceCRN || !clientId || !clientKey || !accessKey) {
2851
+ throw new Error(
2852
+ "Missing required configuration or environment variables."
2853
+ );
2854
+ }
2855
+ this.config = {
2856
+ environment: config.environment,
2857
+ workspaceCRN,
2858
+ clientId,
2859
+ clientKey,
2860
+ accessKey
2861
+ };
2942
2862
  }
2943
2863
  initPromise = null;
2944
2864
  /**
@@ -2951,24 +2871,24 @@ var Secrets = class {
2951
2871
  return this.initPromise;
2952
2872
  }
2953
2873
  async _doInit() {
2874
+ logger.debug("Initializing the Secrets client.");
2954
2875
  this.encryptionClient = await Encryption({
2955
2876
  schemas: [this.secretsSchema],
2956
2877
  config: {
2957
2878
  workspaceCrn: this.config.workspaceCRN,
2958
2879
  clientId: this.config.clientId,
2959
2880
  clientKey: this.config.clientKey,
2960
- accessKey: this.config.apiKey,
2961
- keyset: {
2962
- name: this.config.environment
2963
- }
2881
+ accessKey: this.config.accessKey,
2882
+ keyset: { name: this.config.environment }
2964
2883
  }
2965
2884
  });
2885
+ logger.debug("Successfully initialized the Secrets client.");
2966
2886
  }
2967
2887
  /**
2968
2888
  * Get the authorization header for API requests
2969
2889
  */
2970
2890
  getAuthHeader() {
2971
- return `Bearer ${this.config.apiKey}`;
2891
+ return `Bearer ${this.config.accessKey}`;
2972
2892
  }
2973
2893
  /**
2974
2894
  * Make an API request with error handling.
@@ -2983,6 +2903,7 @@ var Secrets = class {
2983
2903
  const searchParams = new URLSearchParams(options.params);
2984
2904
  url = `${url}?${searchParams.toString()}`;
2985
2905
  }
2906
+ logger.debug(`Secrets API request: ${method} ${path2}`);
2986
2907
  const headers = {
2987
2908
  "Content-Type": "application/json",
2988
2909
  Authorization: this.getAuthHeader()
@@ -3001,6 +2922,7 @@ var Secrets = class {
3001
2922
  } catch {
3002
2923
  errorMessage = errorText || errorMessage;
3003
2924
  }
2925
+ logger.error(`Secrets API error on ${method} ${path2}: ${errorMessage}`);
3004
2926
  return {
3005
2927
  failure: {
3006
2928
  type: "ApiError",
@@ -3008,13 +2930,16 @@ var Secrets = class {
3008
2930
  }
3009
2931
  };
3010
2932
  }
2933
+ logger.debug(`Secrets API request successful: ${method} ${path2}`);
3011
2934
  const data = await response.json();
3012
2935
  return { data };
3013
2936
  } catch (error) {
2937
+ const message = error instanceof Error ? error.message : "Unknown network error occurred";
2938
+ logger.error(`Secrets network error on ${method} ${path2}: ${message}`);
3014
2939
  return {
3015
2940
  failure: {
3016
2941
  type: "NetworkError",
3017
- message: error instanceof Error ? error.message : "Unknown network error occurred"
2942
+ message
3018
2943
  }
3019
2944
  };
3020
2945
  }
@@ -3030,6 +2955,7 @@ var Secrets = class {
3030
2955
  * @returns A Result containing the API response or an error
3031
2956
  */
3032
2957
  async set(name, value) {
2958
+ logger.debug("Setting secret");
3033
2959
  await this.ensureInitialized();
3034
2960
  if (!this.encryptionClient) {
3035
2961
  return {
@@ -3044,6 +2970,7 @@ var Secrets = class {
3044
2970
  table: this.secretsSchema
3045
2971
  });
3046
2972
  if (encryptResult.failure) {
2973
+ logger.error("Failed to encrypt secret");
3047
2974
  return {
3048
2975
  failure: {
3049
2976
  type: "EncryptionError",
@@ -3071,6 +2998,7 @@ var Secrets = class {
3071
2998
  * @returns A Result containing the decrypted value or an error
3072
2999
  */
3073
3000
  async get(name) {
3001
+ logger.debug("Getting secret");
3074
3002
  await this.ensureInitialized();
3075
3003
  if (!this.encryptionClient) {
3076
3004
  return {
@@ -3095,6 +3023,7 @@ var Secrets = class {
3095
3023
  apiResult.data.encryptedValue.data
3096
3024
  );
3097
3025
  if (decryptResult.failure) {
3026
+ logger.error("Failed to decrypt secret");
3098
3027
  return {
3099
3028
  failure: {
3100
3029
  type: "DecryptionError",
@@ -3103,6 +3032,7 @@ var Secrets = class {
3103
3032
  };
3104
3033
  }
3105
3034
  if (typeof decryptResult.data !== "string") {
3035
+ logger.error("Decrypted secret value is not a string");
3106
3036
  return {
3107
3037
  failure: {
3108
3038
  type: "DecryptionError",
@@ -3127,6 +3057,7 @@ var Secrets = class {
3127
3057
  * @returns A Result containing an object mapping secret names to their decrypted values
3128
3058
  */
3129
3059
  async getMany(names) {
3060
+ logger.debug(`Getting ${names.length} secrets.`);
3130
3061
  await this.ensureInitialized();
3131
3062
  if (!this.encryptionClient) {
3132
3063
  return {
@@ -3173,6 +3104,9 @@ var Secrets = class {
3173
3104
  }));
3174
3105
  const decryptResult = await this.encryptionClient.bulkDecryptModels(dataToDecrypt);
3175
3106
  if (decryptResult.failure) {
3107
+ logger.error(
3108
+ `Failed to decrypt secrets: ${decryptResult.failure.message}`
3109
+ );
3176
3110
  return {
3177
3111
  failure: {
3178
3112
  type: "DecryptionError",
@@ -3198,6 +3132,7 @@ var Secrets = class {
3198
3132
  * @returns A Result containing the list of secrets or an error
3199
3133
  */
3200
3134
  async list() {
3135
+ logger.debug("Listing secrets.");
3201
3136
  const workspaceId = extractWorkspaceIdFromCrn(this.config.workspaceCRN);
3202
3137
  const apiResult = await this.apiRequest(
3203
3138
  "GET",
@@ -3223,6 +3158,7 @@ var Secrets = class {
3223
3158
  * @returns A Result containing the API response or an error
3224
3159
  */
3225
3160
  async delete(name) {
3161
+ logger.debug("Deleting secret");
3226
3162
  const workspaceId = extractWorkspaceIdFromCrn(this.config.workspaceCRN);
3227
3163
  return await this.apiRequest("POST", "/delete", {
3228
3164
  body: {