@cipherstash/protect-ffi 0.25.0 → 0.27.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 (139) hide show
  1. package/README.md +60 -0
  2. package/dist/wasm/protect_ffi_bg.js +11 -11
  3. package/dist/wasm/protect_ffi_bg.wasm +0 -0
  4. package/dist/wasm/protect_ffi_bg.wasm.d.ts +5 -5
  5. package/dist/wasm/protect_ffi_inline.js +1 -1
  6. package/lib/eql-v3-types/Bigint.d.ts +13 -0
  7. package/lib/eql-v3-types/Bigint.js +2 -0
  8. package/lib/eql-v3-types/BigintEq.d.ts +15 -0
  9. package/lib/eql-v3-types/BigintEq.js +2 -0
  10. package/lib/eql-v3-types/BigintOrd.d.ts +15 -0
  11. package/lib/eql-v3-types/BigintOrd.js +2 -0
  12. package/lib/eql-v3-types/BigintOrdOpe.d.ts +15 -0
  13. package/lib/eql-v3-types/BigintOrdOpe.js +2 -0
  14. package/lib/eql-v3-types/BigintOrdOre.d.ts +15 -0
  15. package/lib/eql-v3-types/BigintOrdOre.js +2 -0
  16. package/lib/eql-v3-types/BloomFilter.d.ts +9 -0
  17. package/lib/eql-v3-types/BloomFilter.js +5 -0
  18. package/lib/eql-v3-types/Boolean.d.ts +13 -0
  19. package/lib/eql-v3-types/Boolean.js +2 -0
  20. package/lib/eql-v3-types/Ciphertext.d.ts +6 -0
  21. package/lib/eql-v3-types/Ciphertext.js +5 -0
  22. package/lib/eql-v3-types/Date.d.ts +13 -0
  23. package/lib/eql-v3-types/Date.js +2 -0
  24. package/lib/eql-v3-types/DateEq.d.ts +15 -0
  25. package/lib/eql-v3-types/DateEq.js +2 -0
  26. package/lib/eql-v3-types/DateOrd.d.ts +15 -0
  27. package/lib/eql-v3-types/DateOrd.js +2 -0
  28. package/lib/eql-v3-types/DateOrdOpe.d.ts +15 -0
  29. package/lib/eql-v3-types/DateOrdOpe.js +2 -0
  30. package/lib/eql-v3-types/DateOrdOre.d.ts +15 -0
  31. package/lib/eql-v3-types/DateOrdOre.js +2 -0
  32. package/lib/eql-v3-types/Double.d.ts +13 -0
  33. package/lib/eql-v3-types/Double.js +2 -0
  34. package/lib/eql-v3-types/DoubleEq.d.ts +15 -0
  35. package/lib/eql-v3-types/DoubleEq.js +2 -0
  36. package/lib/eql-v3-types/DoubleOrd.d.ts +15 -0
  37. package/lib/eql-v3-types/DoubleOrd.js +2 -0
  38. package/lib/eql-v3-types/DoubleOrdOpe.d.ts +15 -0
  39. package/lib/eql-v3-types/DoubleOrdOpe.js +2 -0
  40. package/lib/eql-v3-types/DoubleOrdOre.d.ts +15 -0
  41. package/lib/eql-v3-types/DoubleOrdOre.js +2 -0
  42. package/lib/eql-v3-types/Hmac256.d.ts +5 -0
  43. package/lib/eql-v3-types/Hmac256.js +5 -0
  44. package/lib/eql-v3-types/Identifier.d.ts +15 -0
  45. package/lib/eql-v3-types/Identifier.js +5 -0
  46. package/lib/eql-v3-types/Integer.d.ts +13 -0
  47. package/lib/eql-v3-types/Integer.js +2 -0
  48. package/lib/eql-v3-types/IntegerEq.d.ts +15 -0
  49. package/lib/eql-v3-types/IntegerEq.js +2 -0
  50. package/lib/eql-v3-types/IntegerOrd.d.ts +15 -0
  51. package/lib/eql-v3-types/IntegerOrd.js +2 -0
  52. package/lib/eql-v3-types/IntegerOrdOpe.d.ts +15 -0
  53. package/lib/eql-v3-types/IntegerOrdOpe.js +2 -0
  54. package/lib/eql-v3-types/IntegerOrdOre.d.ts +15 -0
  55. package/lib/eql-v3-types/IntegerOrdOre.js +2 -0
  56. package/lib/eql-v3-types/Numeric.d.ts +13 -0
  57. package/lib/eql-v3-types/Numeric.js +2 -0
  58. package/lib/eql-v3-types/NumericEq.d.ts +15 -0
  59. package/lib/eql-v3-types/NumericEq.js +2 -0
  60. package/lib/eql-v3-types/NumericOrd.d.ts +15 -0
  61. package/lib/eql-v3-types/NumericOrd.js +2 -0
  62. package/lib/eql-v3-types/NumericOrdOpe.d.ts +15 -0
  63. package/lib/eql-v3-types/NumericOrdOpe.js +2 -0
  64. package/lib/eql-v3-types/NumericOrdOre.d.ts +15 -0
  65. package/lib/eql-v3-types/NumericOrdOre.js +2 -0
  66. package/lib/eql-v3-types/OpeCllw.d.ts +9 -0
  67. package/lib/eql-v3-types/OpeCllw.js +5 -0
  68. package/lib/eql-v3-types/OreBlock256.d.ts +9 -0
  69. package/lib/eql-v3-types/OreBlock256.js +5 -0
  70. package/lib/eql-v3-types/OreCllw.d.ts +7 -0
  71. package/lib/eql-v3-types/OreCllw.js +5 -0
  72. package/lib/eql-v3-types/Real.d.ts +13 -0
  73. package/lib/eql-v3-types/Real.js +2 -0
  74. package/lib/eql-v3-types/RealEq.d.ts +15 -0
  75. package/lib/eql-v3-types/RealEq.js +2 -0
  76. package/lib/eql-v3-types/RealOrd.d.ts +15 -0
  77. package/lib/eql-v3-types/RealOrd.js +2 -0
  78. package/lib/eql-v3-types/RealOrdOpe.d.ts +15 -0
  79. package/lib/eql-v3-types/RealOrdOpe.js +2 -0
  80. package/lib/eql-v3-types/RealOrdOre.d.ts +15 -0
  81. package/lib/eql-v3-types/RealOrdOre.js +2 -0
  82. package/lib/eql-v3-types/SchemaVersion.d.ts +10 -0
  83. package/lib/eql-v3-types/SchemaVersion.js +5 -0
  84. package/lib/eql-v3-types/Selector.d.ts +5 -0
  85. package/lib/eql-v3-types/Selector.js +5 -0
  86. package/lib/eql-v3-types/Smallint.d.ts +13 -0
  87. package/lib/eql-v3-types/Smallint.js +2 -0
  88. package/lib/eql-v3-types/SmallintEq.d.ts +15 -0
  89. package/lib/eql-v3-types/SmallintEq.js +2 -0
  90. package/lib/eql-v3-types/SmallintOrd.d.ts +15 -0
  91. package/lib/eql-v3-types/SmallintOrd.js +2 -0
  92. package/lib/eql-v3-types/SmallintOrdOpe.d.ts +15 -0
  93. package/lib/eql-v3-types/SmallintOrdOpe.js +2 -0
  94. package/lib/eql-v3-types/SmallintOrdOre.d.ts +15 -0
  95. package/lib/eql-v3-types/SmallintOrdOre.js +2 -0
  96. package/lib/eql-v3-types/SteVecDocument.d.ts +15 -0
  97. package/lib/eql-v3-types/SteVecDocument.js +2 -0
  98. package/lib/eql-v3-types/SteVecEntry.d.ts +19 -0
  99. package/lib/eql-v3-types/SteVecEntry.js +2 -0
  100. package/lib/eql-v3-types/SteVecForm.d.ts +18 -0
  101. package/lib/eql-v3-types/SteVecForm.js +5 -0
  102. package/lib/eql-v3-types/SteVecQuery.d.ts +7 -0
  103. package/lib/eql-v3-types/SteVecQuery.js +2 -0
  104. package/lib/eql-v3-types/SteVecQueryEntry.d.ts +15 -0
  105. package/lib/eql-v3-types/SteVecQueryEntry.js +2 -0
  106. package/lib/eql-v3-types/SteVecTerm.d.ts +11 -0
  107. package/lib/eql-v3-types/SteVecTerm.js +2 -0
  108. package/lib/eql-v3-types/Text.d.ts +13 -0
  109. package/lib/eql-v3-types/Text.js +2 -0
  110. package/lib/eql-v3-types/TextEq.d.ts +15 -0
  111. package/lib/eql-v3-types/TextEq.js +2 -0
  112. package/lib/eql-v3-types/TextMatch.d.ts +15 -0
  113. package/lib/eql-v3-types/TextMatch.js +2 -0
  114. package/lib/eql-v3-types/TextOrd.d.ts +17 -0
  115. package/lib/eql-v3-types/TextOrd.js +2 -0
  116. package/lib/eql-v3-types/TextOrdOpe.d.ts +17 -0
  117. package/lib/eql-v3-types/TextOrdOpe.js +2 -0
  118. package/lib/eql-v3-types/TextOrdOre.d.ts +17 -0
  119. package/lib/eql-v3-types/TextOrdOre.js +2 -0
  120. package/lib/eql-v3-types/TextSearch.d.ts +19 -0
  121. package/lib/eql-v3-types/TextSearch.js +2 -0
  122. package/lib/eql-v3-types/Timestamp.d.ts +13 -0
  123. package/lib/eql-v3-types/Timestamp.js +2 -0
  124. package/lib/eql-v3-types/TimestampEq.d.ts +15 -0
  125. package/lib/eql-v3-types/TimestampEq.js +2 -0
  126. package/lib/eql-v3-types/TimestampOrd.d.ts +15 -0
  127. package/lib/eql-v3-types/TimestampOrd.js +2 -0
  128. package/lib/eql-v3-types/TimestampOrdOpe.d.ts +15 -0
  129. package/lib/eql-v3-types/TimestampOrdOpe.js +2 -0
  130. package/lib/eql-v3-types/TimestampOrdOre.d.ts +15 -0
  131. package/lib/eql-v3-types/TimestampOrdOre.js +2 -0
  132. package/lib/eql-v3.d.ts +90 -0
  133. package/lib/eql-v3.js +6 -0
  134. package/lib/errors.d.ts +14 -0
  135. package/lib/errors.js +77 -0
  136. package/lib/index.cjs +32 -59
  137. package/lib/index.d.cts +63 -24
  138. package/lib/normalizeEncryptConfig.d.ts +1 -1
  139. package/package.json +17 -9
@@ -0,0 +1,90 @@
1
+ import type { Bigint } from './eql-v3-types/Bigint.js';
2
+ import type { BigintEq } from './eql-v3-types/BigintEq.js';
3
+ import type { BigintOrd } from './eql-v3-types/BigintOrd.js';
4
+ import type { BigintOrdOpe } from './eql-v3-types/BigintOrdOpe.js';
5
+ import type { BigintOrdOre } from './eql-v3-types/BigintOrdOre.js';
6
+ import type { Boolean as EqlV3Boolean } from './eql-v3-types/Boolean.js';
7
+ import type { Date as EqlV3Date } from './eql-v3-types/Date.js';
8
+ import type { DateEq } from './eql-v3-types/DateEq.js';
9
+ import type { DateOrd } from './eql-v3-types/DateOrd.js';
10
+ import type { DateOrdOpe } from './eql-v3-types/DateOrdOpe.js';
11
+ import type { DateOrdOre } from './eql-v3-types/DateOrdOre.js';
12
+ import type { Double } from './eql-v3-types/Double.js';
13
+ import type { DoubleEq } from './eql-v3-types/DoubleEq.js';
14
+ import type { DoubleOrd } from './eql-v3-types/DoubleOrd.js';
15
+ import type { DoubleOrdOpe } from './eql-v3-types/DoubleOrdOpe.js';
16
+ import type { DoubleOrdOre } from './eql-v3-types/DoubleOrdOre.js';
17
+ import type { Integer } from './eql-v3-types/Integer.js';
18
+ import type { IntegerEq } from './eql-v3-types/IntegerEq.js';
19
+ import type { IntegerOrd } from './eql-v3-types/IntegerOrd.js';
20
+ import type { IntegerOrdOpe } from './eql-v3-types/IntegerOrdOpe.js';
21
+ import type { IntegerOrdOre } from './eql-v3-types/IntegerOrdOre.js';
22
+ import type { Numeric } from './eql-v3-types/Numeric.js';
23
+ import type { NumericEq } from './eql-v3-types/NumericEq.js';
24
+ import type { NumericOrd } from './eql-v3-types/NumericOrd.js';
25
+ import type { NumericOrdOpe } from './eql-v3-types/NumericOrdOpe.js';
26
+ import type { NumericOrdOre } from './eql-v3-types/NumericOrdOre.js';
27
+ import type { Real } from './eql-v3-types/Real.js';
28
+ import type { RealEq } from './eql-v3-types/RealEq.js';
29
+ import type { RealOrd } from './eql-v3-types/RealOrd.js';
30
+ import type { RealOrdOpe } from './eql-v3-types/RealOrdOpe.js';
31
+ import type { RealOrdOre } from './eql-v3-types/RealOrdOre.js';
32
+ import type { Smallint } from './eql-v3-types/Smallint.js';
33
+ import type { SmallintEq } from './eql-v3-types/SmallintEq.js';
34
+ import type { SmallintOrd } from './eql-v3-types/SmallintOrd.js';
35
+ import type { SmallintOrdOpe } from './eql-v3-types/SmallintOrdOpe.js';
36
+ import type { SmallintOrdOre } from './eql-v3-types/SmallintOrdOre.js';
37
+ import type { SteVecDocument } from './eql-v3-types/SteVecDocument.js';
38
+ import type { SteVecQuery } from './eql-v3-types/SteVecQuery.js';
39
+ import type { Text } from './eql-v3-types/Text.js';
40
+ import type { TextEq } from './eql-v3-types/TextEq.js';
41
+ import type { TextMatch } from './eql-v3-types/TextMatch.js';
42
+ import type { TextOrd } from './eql-v3-types/TextOrd.js';
43
+ import type { TextOrdOpe } from './eql-v3-types/TextOrdOpe.js';
44
+ import type { TextOrdOre } from './eql-v3-types/TextOrdOre.js';
45
+ import type { TextSearch } from './eql-v3-types/TextSearch.js';
46
+ import type { Timestamp } from './eql-v3-types/Timestamp.js';
47
+ import type { TimestampEq } from './eql-v3-types/TimestampEq.js';
48
+ import type { TimestampOrd } from './eql-v3-types/TimestampOrd.js';
49
+ import type { TimestampOrdOpe } from './eql-v3-types/TimestampOrdOpe.js';
50
+ import type { TimestampOrdOre } from './eql-v3-types/TimestampOrdOre.js';
51
+ export type { BloomFilter } from './eql-v3-types/BloomFilter.js';
52
+ export type { Ciphertext } from './eql-v3-types/Ciphertext.js';
53
+ export type { Hmac256 } from './eql-v3-types/Hmac256.js';
54
+ export type { Identifier as EqlV3Identifier } from './eql-v3-types/Identifier.js';
55
+ export type { OpeCllw } from './eql-v3-types/OpeCllw.js';
56
+ export type { OreBlock256 } from './eql-v3-types/OreBlock256.js';
57
+ export type { OreCllw } from './eql-v3-types/OreCllw.js';
58
+ export type { SchemaVersion } from './eql-v3-types/SchemaVersion.js';
59
+ export type { Selector } from './eql-v3-types/Selector.js';
60
+ export type { SteVecDocument } from './eql-v3-types/SteVecDocument.js';
61
+ export type { SteVecEntry as EqlV3SteVecEntry } from './eql-v3-types/SteVecEntry.js';
62
+ export type { SteVecForm } from './eql-v3-types/SteVecForm.js';
63
+ export type { SteVecQuery } from './eql-v3-types/SteVecQuery.js';
64
+ export type { SteVecQueryEntry } from './eql-v3-types/SteVecQueryEntry.js';
65
+ export type { SteVecTerm } from './eql-v3-types/SteVecTerm.js';
66
+ export type { Bigint, BigintEq, BigintOrd, BigintOrdOpe, BigintOrdOre, EqlV3Boolean, EqlV3Date, DateEq, DateOrd, DateOrdOpe, DateOrdOre, Double, DoubleEq, DoubleOrd, DoubleOrdOpe, DoubleOrdOre, Integer, IntegerEq, IntegerOrd, IntegerOrdOpe, IntegerOrdOre, Numeric, NumericEq, NumericOrd, NumericOrdOpe, NumericOrdOre, Real, RealEq, RealOrd, RealOrdOpe, RealOrdOre, Smallint, SmallintEq, SmallintOrd, SmallintOrdOpe, SmallintOrdOre, Text, TextEq, TextMatch, TextOrd, TextOrdOpe, TextOrdOre, TextSearch, Timestamp, TimestampEq, TimestampOrd, TimestampOrdOpe, TimestampOrdOre, };
67
+ /**
68
+ * Every flat scalar EQL v3 storage payload (`{v: 3, i, c, <terms>}`, one
69
+ * struct per `eql_v3` scalar domain).
70
+ */
71
+ export type EncryptedV3Scalar = Bigint | BigintEq | BigintOrd | BigintOrdOpe | BigintOrdOre | EqlV3Boolean | EqlV3Date | DateEq | DateOrd | DateOrdOpe | DateOrdOre | Double | DoubleEq | DoubleOrd | DoubleOrdOpe | DoubleOrdOre | Integer | IntegerEq | IntegerOrd | IntegerOrdOpe | IntegerOrdOre | Numeric | NumericEq | NumericOrd | NumericOrdOpe | NumericOrdOre | Real | RealEq | RealOrd | RealOrdOpe | RealOrdOre | Smallint | SmallintEq | SmallintOrd | SmallintOrdOpe | SmallintOrdOre | Text | TextEq | TextMatch | TextOrd | TextOrdOpe | TextOrdOre | TextSearch | Timestamp | TimestampEq | TimestampOrd | TimestampOrdOpe | TimestampOrdOre;
72
+ /**
73
+ * EQL v3 **storage** payload — returned by `encrypt` / `encryptBulk` when the
74
+ * client was created with `eqlVersion: 3`.
75
+ *
76
+ * Scalars carry no `k` discriminator: they are flat
77
+ * (`{v: 3, i, c, <terms>}`, terms depending on the column's `eql_v3` domain).
78
+ * Encrypted JSONB is a {@link SteVecDocument}, which keeps the `k: "sv"`
79
+ * form discriminator (`{v: 3, k: "sv", i, sv: [...]}`).
80
+ * The record ciphertext lives at `c` on scalars and at `sv[0].c` on SteVec
81
+ * documents (`sv[0]` is always the decryption root).
82
+ */
83
+ export type EncryptedV3 = EncryptedV3Scalar | SteVecDocument;
84
+ /**
85
+ * EQL v3 **query** payload — returned by `encryptQuery` / `encryptQueryBulk`
86
+ * under `eqlVersion: 3`. Only JSONB containment queries are supported (the
87
+ * `eql_v3.jsonb_query` needle); scalar and selector query encryption throws
88
+ * until a v3 scalar query wire shape exists.
89
+ */
90
+ export type EncryptedV3Query = SteVecQuery;
package/lib/eql-v3.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ // Hand-written barrel over the vendored (generated) EQL v3 payload types in
3
+ // src/eql-v3-types/. Assembles the public unions and renames the few types
4
+ // whose names would clash with the v2 exports in index.cts (`Identifier`,
5
+ // `SteVecEntry`) or shadow a global (`Boolean`, `Date`).
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,14 @@
1
+ export type ProtectErrorCode = 'INVARIANT_VIOLATION' | 'UNKNOWN_QUERY_OP' | 'UNKNOWN_COLUMN' | 'MISSING_INDEX' | 'INVALID_QUERY_INPUT' | 'INVALID_JSON_PATH' | 'STE_VEC_REQUIRES_JSON_CAST_AS' | 'MATCH_REQUIRES_TEXT' | 'UNSUPPORTED_CONFIG_VERSION' | 'INVALID_EQL_VERSION' | 'EQL_V3_QUERY_UNSUPPORTED' | 'EQL_V3_UNSUPPORTED_COLUMN' | 'EQL_V3_CONVERSION_FAILED' | 'INVALID_CIPHERTEXT' | 'UNKNOWN';
2
+ export declare class ProtectError extends Error {
3
+ code: ProtectErrorCode;
4
+ details?: unknown;
5
+ cause?: unknown;
6
+ constructor(opts: {
7
+ code: ProtectErrorCode;
8
+ message: string;
9
+ details?: unknown;
10
+ cause?: unknown;
11
+ });
12
+ }
13
+ export declare function inferErrorCode(message: string): ProtectErrorCode;
14
+ export declare function normalizeError(err: unknown): unknown;
package/lib/errors.js ADDED
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProtectError = void 0;
4
+ exports.inferErrorCode = inferErrorCode;
5
+ exports.normalizeError = normalizeError;
6
+ class ProtectError extends Error {
7
+ code;
8
+ details;
9
+ cause;
10
+ constructor(opts) {
11
+ super(opts.message);
12
+ this.name = 'ProtectError';
13
+ this.code = opts.code;
14
+ this.details = opts.details;
15
+ this.cause = opts.cause;
16
+ }
17
+ }
18
+ exports.ProtectError = ProtectError;
19
+ function inferErrorCode(message) {
20
+ if (message.startsWith('protect-ffi invariant violation:')) {
21
+ return 'INVARIANT_VIOLATION';
22
+ }
23
+ if (message.startsWith('Unknown query operation:')) {
24
+ return 'UNKNOWN_QUERY_OP';
25
+ }
26
+ if (message.startsWith('Invalid query input for')) {
27
+ return 'INVALID_QUERY_INPUT';
28
+ }
29
+ if (message.startsWith('Invalid JSON path')) {
30
+ return 'INVALID_JSON_PATH';
31
+ }
32
+ if (message.includes(' not found in Encrypt config')) {
33
+ return 'UNKNOWN_COLUMN';
34
+ }
35
+ if (message.includes(' index configured')) {
36
+ return 'MISSING_INDEX';
37
+ }
38
+ if (message.includes('requires plaintext_type: json')) {
39
+ return 'STE_VEC_REQUIRES_JSON_CAST_AS';
40
+ }
41
+ if (message.includes('requires plaintext_type: text')) {
42
+ return 'MATCH_REQUIRES_TEXT';
43
+ }
44
+ if (message.includes('unsupported config version')) {
45
+ return 'UNSUPPORTED_CONFIG_VERSION';
46
+ }
47
+ if (message.startsWith('Invalid eqlVersion')) {
48
+ return 'INVALID_EQL_VERSION';
49
+ }
50
+ if (message.startsWith('EQL v3 scalar query') ||
51
+ message.startsWith('EQL v3 selector query')) {
52
+ return 'EQL_V3_QUERY_UNSUPPORTED';
53
+ }
54
+ if (message.includes('cannot be represented in EQL v3')) {
55
+ return 'EQL_V3_UNSUPPORTED_COLUMN';
56
+ }
57
+ if (message.startsWith('EQL v3 conversion failed')) {
58
+ return 'EQL_V3_CONVERSION_FAILED';
59
+ }
60
+ if (message.startsWith('Invalid EQL ciphertext:')) {
61
+ return 'INVALID_CIPHERTEXT';
62
+ }
63
+ return 'UNKNOWN';
64
+ }
65
+ function normalizeError(err) {
66
+ if (err instanceof ProtectError) {
67
+ return err;
68
+ }
69
+ if (err && typeof err === 'object' && 'message' in err) {
70
+ const message = String(err.message ?? 'Unknown error');
71
+ const code = inferErrorCode(message);
72
+ if (code !== 'UNKNOWN') {
73
+ return new ProtectError({ code, message, cause: err });
74
+ }
75
+ }
76
+ return err;
77
+ }
package/lib/index.cjs CHANGED
@@ -33,6 +33,9 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  return result;
34
34
  };
35
35
  })();
36
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
37
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
38
+ };
36
39
  Object.defineProperty(exports, "__esModule", { value: true });
37
40
  exports.ProtectError = exports.withEnvCredentials = void 0;
38
41
  exports.newClient = newClient;
@@ -50,68 +53,16 @@ const native = __importStar(require("./load.cjs"));
50
53
  const normalizeEncryptConfig_js_1 = require("./normalizeEncryptConfig.js");
51
54
  var credentials_js_2 = require("./credentials.js");
52
55
  Object.defineProperty(exports, "withEnvCredentials", { enumerable: true, get: function () { return credentials_js_2.withEnvCredentials; } });
53
- class ProtectError extends Error {
54
- code;
55
- details;
56
- cause;
57
- constructor(opts) {
58
- super(opts.message);
59
- this.name = 'ProtectError';
60
- this.code = opts.code;
61
- this.details = opts.details;
62
- this.cause = opts.cause;
63
- }
64
- }
65
- exports.ProtectError = ProtectError;
66
- function inferErrorCode(message) {
67
- if (message.startsWith('protect-ffi invariant violation:')) {
68
- return 'INVARIANT_VIOLATION';
69
- }
70
- if (message.startsWith('Unknown query operation:')) {
71
- return 'UNKNOWN_QUERY_OP';
72
- }
73
- if (message.startsWith('Invalid query input for')) {
74
- return 'INVALID_QUERY_INPUT';
75
- }
76
- if (message.startsWith('Invalid JSON path')) {
77
- return 'INVALID_JSON_PATH';
78
- }
79
- if (message.includes(' not found in Encrypt config')) {
80
- return 'UNKNOWN_COLUMN';
81
- }
82
- if (message.includes(' index configured')) {
83
- return 'MISSING_INDEX';
84
- }
85
- if (message.includes('requires plaintext_type: json')) {
86
- return 'STE_VEC_REQUIRES_JSON_CAST_AS';
87
- }
88
- if (message.includes('requires plaintext_type: text')) {
89
- return 'MATCH_REQUIRES_TEXT';
90
- }
91
- if (message.includes('unsupported config version')) {
92
- return 'UNSUPPORTED_CONFIG_VERSION';
93
- }
94
- return 'UNKNOWN';
95
- }
96
- function normalizeError(err) {
97
- if (err instanceof ProtectError) {
98
- return err;
99
- }
100
- if (err && typeof err === 'object' && 'message' in err) {
101
- const message = String(err.message ?? 'Unknown error');
102
- const code = inferErrorCode(message);
103
- if (code !== 'UNKNOWN') {
104
- return new ProtectError({ code, message, cause: err });
105
- }
106
- }
107
- return err;
108
- }
56
+ __exportStar(require("./eql-v3.js"), exports);
57
+ const errors_js_1 = require("./errors.js");
58
+ var errors_js_2 = require("./errors.js");
59
+ Object.defineProperty(exports, "ProtectError", { enumerable: true, get: function () { return errors_js_2.ProtectError; } });
109
60
  async function wrapAsync(fn) {
110
61
  try {
111
62
  return await fn();
112
63
  }
113
64
  catch (err) {
114
- throw normalizeError(err);
65
+ throw (0, errors_js_1.normalizeError)(err);
115
66
  }
116
67
  }
117
68
  function wrapSync(fn) {
@@ -119,13 +70,14 @@ function wrapSync(fn) {
119
70
  return fn();
120
71
  }
121
72
  catch (err) {
122
- throw normalizeError(err);
73
+ throw (0, errors_js_1.normalizeError)(err);
123
74
  }
124
75
  }
125
76
  function newClient(opts) {
126
77
  return wrapAsync(() => native.newClient({
127
78
  encryptConfig: (0, normalizeEncryptConfig_js_1.normalizeEncryptConfig)(opts.encryptConfig),
128
79
  clientOpts: (0, credentials_js_1.withEnvCredentials)(opts.clientOpts),
80
+ eqlVersion: opts.eqlVersion,
129
81
  }, opts.strategy));
130
82
  }
131
83
  function encrypt(client, opts) {
@@ -134,6 +86,13 @@ function encrypt(client, opts) {
134
86
  function decrypt(client, opts) {
135
87
  return wrapAsync(() => native.decrypt(client, opts));
136
88
  }
89
+ /**
90
+ * True when `encrypted` is a stored EQL payload in EITHER wire format:
91
+ * an EQL v2.3 payload (`k: "ct"` / `k: "sv"`) or an EQL v3 payload
92
+ * (`{v: 3, i, c}` scalar or `{v: 3, k: "sv", i, sv}` SteVec document).
93
+ * Query payloads (including the v3 containment needle) are not stored
94
+ * payloads and return false.
95
+ */
137
96
  function isEncrypted(encrypted) {
138
97
  return wrapSync(() => native.isEncrypted(encrypted));
139
98
  }
@@ -147,14 +106,28 @@ async function decryptBulkFallible(client, opts) {
147
106
  const results = await wrapAsync(() => native.decryptBulkFallible(client, opts));
148
107
  return results.map((item) => {
149
108
  if ('error' in item && typeof item.error === 'string') {
150
- return { ...item, code: inferErrorCode(item.error) };
109
+ return { ...item, code: (0, errors_js_1.inferErrorCode)(item.error) };
151
110
  }
152
111
  return item;
153
112
  });
154
113
  }
114
+ /**
115
+ * Encrypt a query term.
116
+ *
117
+ * Under `eqlVersion: 2` (default) this returns the v2 shapes ({@link
118
+ * Encrypted} for JSON containment, {@link EncryptedQuery} otherwise).
119
+ *
120
+ * Under `eqlVersion: 3` only JSON containment queries are supported and
121
+ * return the `eql_v3.jsonb_query` needle ({@link EncryptedV3Query}). Scalar
122
+ * index queries (`unique` / `ore` / `ope` / `match`) and `ste_vec_selector`
123
+ * queries
124
+ * throw `EQL_V3_QUERY_UNSUPPORTED` — no EQL v3 scalar/selector query wire
125
+ * shape exists yet, so those queries require an `eqlVersion: 2` client.
126
+ */
155
127
  function encryptQuery(client, opts) {
156
128
  return wrapAsync(() => native.encryptQuery(client, opts));
157
129
  }
130
+ /** Bulk variant of {@link encryptQuery} — same EQL v3 restrictions apply. */
158
131
  function encryptQueryBulk(client, opts) {
159
132
  return wrapAsync(() => native.encryptQueryBulk(client, opts));
160
133
  }
package/lib/index.d.cts CHANGED
@@ -1,34 +1,26 @@
1
1
  import { type CredentialOpts } from './credentials.js';
2
2
  import { type NativeEncryptConfig } from './normalizeEncryptConfig.js';
3
3
  export { withEnvCredentials, type EnvReader, type CredentialOpts, } from './credentials.js';
4
+ export * from './eql-v3.js';
5
+ import type { EncryptedV3, EncryptedV3Query } from './eql-v3.js';
6
+ import { type ProtectErrorCode } from './errors.js';
7
+ export { ProtectError, type ProtectErrorCode } from './errors.js';
4
8
  declare const sym: unique symbol;
5
9
  export type Client = {
6
10
  readonly [sym]: unknown;
7
11
  };
8
12
  declare module './load.cjs' {
9
13
  function newClient(opts: NativeNewClientOptions, strategy?: AuthStrategy): Promise<Client>;
10
- function encrypt(client: Client, opts: EncryptOptions): Promise<Encrypted>;
14
+ function encrypt(client: Client, opts: EncryptOptions): Promise<EncryptedPayload>;
11
15
  function decrypt(client: Client, opts: DecryptOptions): Promise<JsPlaintext>;
12
16
  function isEncrypted(encrypted: unknown): boolean;
13
- function encryptBulk(client: Client, opts: EncryptBulkOptions): Promise<Encrypted[]>;
17
+ function encryptBulk(client: Client, opts: EncryptBulkOptions): Promise<EncryptedPayload[]>;
14
18
  function decryptBulk(client: Client, opts: DecryptBulkOptions): Promise<JsPlaintext[]>;
15
19
  function decryptBulkFallible(client: Client, opts: DecryptBulkOptions): Promise<DecryptResult[]>;
16
- function encryptQuery(client: Client, opts: EncryptQueryOptions): Promise<Encrypted | EncryptedQuery>;
17
- function encryptQueryBulk(client: Client, opts: EncryptQueryBulkOptions): Promise<(Encrypted | EncryptedQuery)[]>;
20
+ function encryptQuery(client: Client, opts: EncryptQueryOptions): Promise<Encrypted | EncryptedQuery | EncryptedV3Query>;
21
+ function encryptQueryBulk(client: Client, opts: EncryptQueryBulkOptions): Promise<(Encrypted | EncryptedQuery | EncryptedV3Query)[]>;
18
22
  function ensureKeyset(opts: EnsureKeysetOpts): Promise<EnsureKeysetResult>;
19
23
  }
20
- export type ProtectErrorCode = 'INVARIANT_VIOLATION' | 'UNKNOWN_QUERY_OP' | 'UNKNOWN_COLUMN' | 'MISSING_INDEX' | 'INVALID_QUERY_INPUT' | 'INVALID_JSON_PATH' | 'STE_VEC_REQUIRES_JSON_CAST_AS' | 'MATCH_REQUIRES_TEXT' | 'UNSUPPORTED_CONFIG_VERSION' | 'UNKNOWN';
21
- export declare class ProtectError extends Error {
22
- code: ProtectErrorCode;
23
- details?: unknown;
24
- cause?: unknown;
25
- constructor(opts: {
26
- code: ProtectErrorCode;
27
- message: string;
28
- details?: unknown;
29
- cause?: unknown;
30
- });
31
- }
32
24
  export type DecryptResult = {
33
25
  data: JsPlaintext;
34
26
  } | {
@@ -36,14 +28,35 @@ export type DecryptResult = {
36
28
  code?: ProtectErrorCode;
37
29
  };
38
30
  export declare function newClient(opts: NewClientOptions): Promise<Client>;
39
- export declare function encrypt(client: Client, opts: EncryptOptions): Promise<Encrypted>;
31
+ export declare function encrypt(client: Client, opts: EncryptOptions): Promise<EncryptedPayload>;
40
32
  export declare function decrypt(client: Client, opts: DecryptOptions): Promise<JsPlaintext>;
33
+ /**
34
+ * True when `encrypted` is a stored EQL payload in EITHER wire format:
35
+ * an EQL v2.3 payload (`k: "ct"` / `k: "sv"`) or an EQL v3 payload
36
+ * (`{v: 3, i, c}` scalar or `{v: 3, k: "sv", i, sv}` SteVec document).
37
+ * Query payloads (including the v3 containment needle) are not stored
38
+ * payloads and return false.
39
+ */
41
40
  export declare function isEncrypted(encrypted: unknown): boolean;
42
- export declare function encryptBulk(client: Client, opts: EncryptBulkOptions): Promise<Encrypted[]>;
41
+ export declare function encryptBulk(client: Client, opts: EncryptBulkOptions): Promise<EncryptedPayload[]>;
43
42
  export declare function decryptBulk(client: Client, opts: DecryptBulkOptions): Promise<JsPlaintext[]>;
44
43
  export declare function decryptBulkFallible(client: Client, opts: DecryptBulkOptions): Promise<DecryptResult[]>;
45
- export declare function encryptQuery(client: Client, opts: EncryptQueryOptions): Promise<Encrypted | EncryptedQuery>;
46
- export declare function encryptQueryBulk(client: Client, opts: EncryptQueryBulkOptions): Promise<(Encrypted | EncryptedQuery)[]>;
44
+ /**
45
+ * Encrypt a query term.
46
+ *
47
+ * Under `eqlVersion: 2` (default) this returns the v2 shapes ({@link
48
+ * Encrypted} for JSON containment, {@link EncryptedQuery} otherwise).
49
+ *
50
+ * Under `eqlVersion: 3` only JSON containment queries are supported and
51
+ * return the `eql_v3.jsonb_query` needle ({@link EncryptedV3Query}). Scalar
52
+ * index queries (`unique` / `ore` / `ope` / `match`) and `ste_vec_selector`
53
+ * queries
54
+ * throw `EQL_V3_QUERY_UNSUPPORTED` — no EQL v3 scalar/selector query wire
55
+ * shape exists yet, so those queries require an `eqlVersion: 2` client.
56
+ */
57
+ export declare function encryptQuery(client: Client, opts: EncryptQueryOptions): Promise<Encrypted | EncryptedQuery | EncryptedV3Query>;
58
+ /** Bulk variant of {@link encryptQuery} — same EQL v3 restrictions apply. */
59
+ export declare function encryptQueryBulk(client: Client, opts: EncryptQueryBulkOptions): Promise<(Encrypted | EncryptedQuery | EncryptedV3Query)[]>;
47
60
  /**
48
61
  * Test-only helper: ensures a keyset with the given name exists, creating it if necessary,
49
62
  * and grants the current client access. Not safe for concurrent use — intended for
@@ -57,7 +70,7 @@ export type EncryptPayload = {
57
70
  lockContext?: Context;
58
71
  };
59
72
  export type BulkDecryptPayload = {
60
- ciphertext: Encrypted;
73
+ ciphertext: EncryptedPayload;
61
74
  lockContext?: Context;
62
75
  };
63
76
  export type Context = {
@@ -79,6 +92,13 @@ export type Context = {
79
92
  * ```
80
93
  */
81
94
  export type Encrypted = EncryptedScalar | EncryptedSteVec;
95
+ /**
96
+ * A stored payload in EITHER wire format: EQL v2.3 ({@link Encrypted}) or
97
+ * EQL v3 ({@link EncryptedV3}). {@link encrypt} / {@link encryptBulk} return
98
+ * the format selected by the client's `eqlVersion`; {@link decrypt} accepts
99
+ * both regardless of `eqlVersion` (data-migration scenarios).
100
+ */
101
+ export type EncryptedPayload = Encrypted | EncryptedV3;
82
102
  /** Scalar EQL v2.3 storage payload (`k: "ct"`). */
83
103
  export type EncryptedScalar = {
84
104
  k: 'ct';
@@ -192,7 +212,7 @@ export type Column = {
192
212
  cast_as?: CastAs;
193
213
  indexes?: Indexes;
194
214
  };
195
- export type CastAs = 'bigint' | 'boolean' | 'date' | 'number' | 'string' | 'text' | 'timestamp' | 'json';
215
+ export type CastAs = 'bigint' | 'boolean' | 'date' | 'decimal' | 'int' | 'number' | 'small_int' | 'string' | 'text' | 'timestamp' | 'json';
196
216
  type TablesOf<C extends EncryptConfig> = C['tables'];
197
217
  export type Identifier<C extends EncryptConfig> = {
198
218
  [T in keyof TablesOf<C>]: {
@@ -204,11 +224,13 @@ export type Identifier<C extends EncryptConfig> = {
204
224
  }[keyof TablesOf<C>];
205
225
  export type Indexes = {
206
226
  ore?: OreIndexOpts;
227
+ ope?: OpeIndexOpts;
207
228
  unique?: UniqueIndexOpts;
208
229
  match?: MatchIndexOpts;
209
230
  ste_vec?: SteVecIndexOpts;
210
231
  };
211
232
  export type OreIndexOpts = Record<string, never>;
233
+ export type OpeIndexOpts = Record<string, never>;
212
234
  export type UniqueIndexOpts = {
213
235
  token_filters?: TokenFilter[];
214
236
  };
@@ -257,6 +279,21 @@ export type NewClientOptions = {
257
279
  * AutoStrategy from env / profile / `clientOpts.creds`.
258
280
  */
259
281
  strategy?: AuthStrategy;
282
+ /**
283
+ * EQL wire version this client emits. Defaults to `2` (the
284
+ * `eql_v2_encrypted` payload format).
285
+ *
286
+ * With `3`, {@link encrypt} / {@link encryptBulk} return {@link
287
+ * EncryptedV3} payloads for the `eql_v3` per-capability domains
288
+ * (`eql_v3.text_eq`, `eql_v3.integer_ord_ore`, `eql_v3.json`, …), derived
289
+ * from each column's `cast_as` + indexes. {@link decrypt} accepts BOTH
290
+ * formats regardless of this setting.
291
+ *
292
+ * v3 limitation: {@link encryptQuery} supports only JSON containment
293
+ * queries — scalar-index and selector queries throw
294
+ * `EQL_V3_QUERY_UNSUPPORTED` until a v3 scalar query wire shape exists.
295
+ */
296
+ eqlVersion?: 2 | 3;
260
297
  };
261
298
  /**
262
299
  * Auth strategy shape compatible with `@cipherstash/auth` strategies (e.g.
@@ -271,6 +308,7 @@ export type AuthStrategy = {
271
308
  type NativeNewClientOptions = {
272
309
  encryptConfig: NativeEncryptConfig;
273
310
  clientOpts?: ClientOpts;
311
+ eqlVersion?: 2 | 3;
274
312
  };
275
313
  export type ClientOpts = CredentialOpts & {
276
314
  keyset?: KeysetIdentifier;
@@ -300,7 +338,8 @@ export type EncryptBulkOptions = {
300
338
  unverifiedContext?: Record<string, unknown>;
301
339
  };
302
340
  export type DecryptOptions = {
303
- ciphertext: Encrypted;
341
+ /** A stored payload in either wire format (EQL v2.3 or EQL v3). */
342
+ ciphertext: EncryptedPayload;
304
343
  lockContext?: Context;
305
344
  unverifiedContext?: Record<string, unknown>;
306
345
  };
@@ -308,7 +347,7 @@ export type DecryptBulkOptions = {
308
347
  ciphertexts: BulkDecryptPayload[];
309
348
  unverifiedContext?: Record<string, unknown>;
310
349
  };
311
- export type IndexTypeName = 'ste_vec' | 'match' | 'ore' | 'unique';
350
+ export type IndexTypeName = 'ste_vec' | 'match' | 'ore' | 'ope' | 'unique';
312
351
  export type QueryOpName = 'default' | 'ste_vec_selector' | 'ste_vec_term';
313
352
  export type EncryptQueryOptions = {
314
353
  plaintext: JsPlaintext;
@@ -6,7 +6,7 @@ import type { Column, EncryptConfig } from './index.cjs';
6
6
  * their canonical equivalents (`text`, `float`, `big_int`) before being
7
7
  * handed to the native side.
8
8
  */
9
- export type NativeCastAs = 'text' | 'float' | 'big_int' | 'boolean' | 'date' | 'json' | 'timestamp';
9
+ export type NativeCastAs = 'text' | 'float' | 'big_int' | 'boolean' | 'date' | 'decimal' | 'int' | 'json' | 'small_int' | 'timestamp';
10
10
  /** A column after normalization — `cast_as` is in the canonical vocabulary. */
11
11
  export type NativeColumn = Omit<Column, 'cast_as'> & {
12
12
  cast_as?: NativeCastAs;
package/package.json CHANGED
@@ -1,11 +1,19 @@
1
1
  {
2
2
  "name": "@cipherstash/protect-ffi",
3
- "version": "0.25.0",
3
+ "version": "0.27.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/cipherstash/protectjs-ffi.git"
7
+ },
8
+ "bugs": {
9
+ "url": "https://github.com/cipherstash/protectjs-ffi/issues"
10
+ },
11
+ "homepage": "https://github.com/cipherstash/protectjs-ffi#readme",
4
12
  "description": "",
5
13
  "main": "./lib/index.cjs",
6
14
  "scripts": {
7
15
  "test": "npm run test:typecheck && npm run test:unit && npm run test:lint && npm run test:format && npm run test:rust",
8
- "test:typecheck": "tsc",
16
+ "test:typecheck": "tsc && tsc -p tsconfig.test.json",
9
17
  "test:unit": "vitest run",
10
18
  "test:rust": "cargo test",
11
19
  "test:lint": "npm run test:lint:ts",
@@ -26,7 +34,7 @@
26
34
  "prepack": "tsc &&neon update",
27
35
  "version": "neon bump --binaries platforms && git add .",
28
36
  "release": "gh workflow run release.yml -f dryrun=false -f version=patch",
29
- "dryrun": "gh workflow run publish.yml -f dryrun=true",
37
+ "dryrun": "gh workflow run release.yml -f dryrun=true -f version=patch",
30
38
  "build:wasm": "wasm-pack build crates/protect-ffi --target bundler --out-dir ../../dist/wasm --no-pack",
31
39
  "postbuild:wasm": "node scripts/inline-wasm.mjs"
32
40
  },
@@ -95,11 +103,11 @@
95
103
  "vite": "^8.0.5"
96
104
  },
97
105
  "optionalDependencies": {
98
- "@cipherstash/protect-ffi-darwin-x64": "0.25.0",
99
- "@cipherstash/protect-ffi-darwin-arm64": "0.25.0",
100
- "@cipherstash/protect-ffi-win32-x64-msvc": "0.25.0",
101
- "@cipherstash/protect-ffi-linux-x64-gnu": "0.25.0",
102
- "@cipherstash/protect-ffi-linux-arm64-gnu": "0.25.0",
103
- "@cipherstash/protect-ffi-linux-x64-musl": "0.25.0"
106
+ "@cipherstash/protect-ffi-darwin-x64": "0.27.0",
107
+ "@cipherstash/protect-ffi-darwin-arm64": "0.27.0",
108
+ "@cipherstash/protect-ffi-win32-x64-msvc": "0.27.0",
109
+ "@cipherstash/protect-ffi-linux-x64-gnu": "0.27.0",
110
+ "@cipherstash/protect-ffi-linux-arm64-gnu": "0.27.0",
111
+ "@cipherstash/protect-ffi-linux-x64-musl": "0.27.0"
104
112
  }
105
113
  }