@cipherstash/stack 0.19.0 → 1.0.0-rc.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 (90) hide show
  1. package/CHANGELOG.md +531 -0
  2. package/README.md +95 -77
  3. package/dist/adapter-kit.cjs +923 -0
  4. package/dist/adapter-kit.cjs.map +1 -0
  5. package/dist/adapter-kit.d.cts +82 -0
  6. package/dist/adapter-kit.d.ts +82 -0
  7. package/dist/adapter-kit.js +47 -0
  8. package/dist/adapter-kit.js.map +1 -0
  9. package/dist/base-operation-AOAIvsSB.d.cts +32 -0
  10. package/dist/base-operation-FXEzUXIq.d.ts +32 -0
  11. package/dist/{chunk-4AVL4VZD.js → chunk-3B5ZX3IS.js} +3 -1
  12. package/dist/chunk-3B5ZX3IS.js.map +1 -0
  13. package/dist/chunk-7333ZC6L.js +48 -0
  14. package/dist/chunk-7333ZC6L.js.map +1 -0
  15. package/dist/{chunk-MP3SSDNN.js → chunk-CLM7E4I6.js} +15 -15
  16. package/dist/{chunk-MP3SSDNN.js.map → chunk-CLM7E4I6.js.map} +1 -1
  17. package/dist/{chunk-U66S7VIF.js → chunk-V2Q3NYIH.js} +166 -107
  18. package/dist/chunk-V2Q3NYIH.js.map +1 -0
  19. package/dist/chunk-X3JRXEIB.js +98 -0
  20. package/dist/chunk-X3JRXEIB.js.map +1 -0
  21. package/dist/{chunk-36AA7IBJ.js → chunk-ZTP5QJ27.js} +51 -18
  22. package/dist/chunk-ZTP5QJ27.js.map +1 -0
  23. package/dist/client.cjs +29 -12
  24. package/dist/client.cjs.map +1 -1
  25. package/dist/client.d.cts +3 -2
  26. package/dist/client.d.ts +3 -2
  27. package/dist/client.js +2 -2
  28. package/dist/{table-DihEAlxG.d.cts → columns-D2_YzrCX.d.cts} +155 -136
  29. package/dist/{table-CIH7jZ2h.d.ts → columns-rZc7fQHI.d.ts} +155 -136
  30. package/dist/dynamodb/index.d.cts +3 -2
  31. package/dist/dynamodb/index.d.ts +3 -2
  32. package/dist/encryption/index.cjs +54 -16
  33. package/dist/encryption/index.cjs.map +1 -1
  34. package/dist/encryption/index.d.cts +807 -6
  35. package/dist/encryption/index.d.ts +807 -6
  36. package/dist/encryption/index.js +4 -4
  37. package/dist/encryption/v3.cjs +1078 -973
  38. package/dist/encryption/v3.cjs.map +1 -1
  39. package/dist/encryption/v3.d.cts +15 -12
  40. package/dist/encryption/v3.d.ts +15 -12
  41. package/dist/encryption/v3.js +49 -21
  42. package/dist/encryption/v3.js.map +1 -1
  43. package/dist/eql/v3/index.cjs +130 -79
  44. package/dist/eql/v3/index.cjs.map +1 -1
  45. package/dist/eql/v3/index.d.cts +115 -13
  46. package/dist/eql/v3/index.d.ts +115 -13
  47. package/dist/eql/v3/index.js +16 -6
  48. package/dist/index-BquA71_Y.d.ts +24 -0
  49. package/dist/index-fhWTOV0K.d.cts +24 -0
  50. package/dist/index.cjs +79 -27
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.d.cts +5 -17
  53. package/dist/index.d.ts +5 -17
  54. package/dist/index.js +4 -4
  55. package/dist/schema/index.cjs +29 -12
  56. package/dist/schema/index.cjs.map +1 -1
  57. package/dist/schema/index.d.cts +1 -1
  58. package/dist/schema/index.d.ts +1 -1
  59. package/dist/schema/index.js +2 -2
  60. package/dist/{types-public-CpS5KjwX.d.ts → types-public-QMjYNfQO.d.cts} +765 -726
  61. package/dist/{types-public-CpS5KjwX.d.cts → types-public-QMjYNfQO.d.ts} +765 -726
  62. package/dist/types-public.cjs.map +1 -1
  63. package/dist/types-public.d.cts +1 -1
  64. package/dist/types-public.d.ts +1 -1
  65. package/dist/types-public.js +1 -1
  66. package/dist/wasm-inline.d.ts +779 -405
  67. package/dist/wasm-inline.js +606 -299
  68. package/dist/wasm-inline.js.map +1 -1
  69. package/package.json +25 -53
  70. package/dist/chunk-36AA7IBJ.js.map +0 -1
  71. package/dist/chunk-4AVL4VZD.js.map +0 -1
  72. package/dist/chunk-IADZCZEA.js +0 -23
  73. package/dist/chunk-IADZCZEA.js.map +0 -1
  74. package/dist/chunk-IBSK6P33.js +0 -209
  75. package/dist/chunk-IBSK6P33.js.map +0 -1
  76. package/dist/chunk-U66S7VIF.js.map +0 -1
  77. package/dist/client-DSGHBN-g.d.cts +0 -834
  78. package/dist/client-DfCrlHXh.d.ts +0 -834
  79. package/dist/drizzle/index.cjs +0 -5617
  80. package/dist/drizzle/index.cjs.map +0 -1
  81. package/dist/drizzle/index.d.cts +0 -358
  82. package/dist/drizzle/index.d.ts +0 -358
  83. package/dist/drizzle/index.js +0 -1220
  84. package/dist/drizzle/index.js.map +0 -1
  85. package/dist/supabase/index.cjs +0 -5951
  86. package/dist/supabase/index.cjs.map +0 -1
  87. package/dist/supabase/index.d.cts +0 -223
  88. package/dist/supabase/index.d.ts +0 -223
  89. package/dist/supabase/index.js +0 -1217
  90. package/dist/supabase/index.js.map +0 -1
@@ -52,123 +52,11 @@ type EncryptOptions = {
52
52
  table: BuildableTable;
53
53
  };
54
54
 
55
- /**
56
- * SDK-facing data types — developer-friendly aliases accepted by `dataType()`.
57
- */
58
- declare const castAsEnum: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "timestamp", "number", "string", "json", "text"]>>;
59
- declare const tokenFilterSchema: z.ZodObject<{
60
- kind: z.ZodLiteral<"downcase">;
61
- }, "strip", z.ZodTypeAny, {
62
- kind: "downcase";
63
- }, {
64
- kind: "downcase";
65
- }>;
66
- declare const oreIndexOptsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
67
- declare const uniqueIndexOptsSchema: z.ZodObject<{
68
- token_filters: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
69
- kind: z.ZodLiteral<"downcase">;
70
- }, "strip", z.ZodTypeAny, {
71
- kind: "downcase";
72
- }, {
73
- kind: "downcase";
74
- }>, "many">>>;
75
- }, "strip", z.ZodTypeAny, {
76
- token_filters?: {
77
- kind: "downcase";
78
- }[] | undefined;
79
- }, {
80
- token_filters?: {
81
- kind: "downcase";
82
- }[] | undefined;
83
- }>;
84
- declare const matchIndexOptsSchema: z.ZodObject<{
85
- tokenizer: z.ZodOptional<z.ZodDefault<z.ZodUnion<[z.ZodObject<{
86
- kind: z.ZodLiteral<"standard">;
87
- }, "strip", z.ZodTypeAny, {
88
- kind: "standard";
89
- }, {
90
- kind: "standard";
91
- }>, z.ZodObject<{
92
- kind: z.ZodLiteral<"ngram">;
93
- token_length: z.ZodNumber;
94
- }, "strip", z.ZodTypeAny, {
95
- kind: "ngram";
96
- token_length: number;
97
- }, {
98
- kind: "ngram";
99
- token_length: number;
100
- }>]>>>;
101
- token_filters: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
102
- kind: z.ZodLiteral<"downcase">;
103
- }, "strip", z.ZodTypeAny, {
104
- kind: "downcase";
105
- }, {
106
- kind: "downcase";
107
- }>, "many">>>;
108
- k: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
109
- m: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
110
- include_original: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
111
- }, "strip", z.ZodTypeAny, {
112
- token_filters?: {
113
- kind: "downcase";
114
- }[] | undefined;
115
- tokenizer?: {
116
- kind: "standard";
117
- } | {
118
- kind: "ngram";
119
- token_length: number;
120
- } | undefined;
121
- k?: number | undefined;
122
- m?: number | undefined;
123
- include_original?: boolean | undefined;
124
- }, {
125
- token_filters?: {
126
- kind: "downcase";
127
- }[] | undefined;
128
- tokenizer?: {
129
- kind: "standard";
130
- } | {
131
- kind: "ngram";
132
- token_length: number;
133
- } | undefined;
134
- k?: number | undefined;
135
- m?: number | undefined;
136
- include_original?: boolean | undefined;
137
- }>;
138
- declare const steVecIndexOptsSchema: z.ZodObject<{
139
- prefix: z.ZodString;
140
- array_index_mode: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"all">, z.ZodLiteral<"none">, z.ZodObject<{
141
- item: z.ZodOptional<z.ZodBoolean>;
142
- wildcard: z.ZodOptional<z.ZodBoolean>;
143
- position: z.ZodOptional<z.ZodBoolean>;
144
- }, "strip", z.ZodTypeAny, {
145
- item?: boolean | undefined;
146
- wildcard?: boolean | undefined;
147
- position?: boolean | undefined;
148
- }, {
149
- item?: boolean | undefined;
150
- wildcard?: boolean | undefined;
151
- position?: boolean | undefined;
152
- }>]>>;
153
- }, "strip", z.ZodTypeAny, {
154
- prefix: string;
155
- array_index_mode?: "all" | "none" | {
156
- item?: boolean | undefined;
157
- wildcard?: boolean | undefined;
158
- position?: boolean | undefined;
159
- } | undefined;
160
- }, {
161
- prefix: string;
162
- array_index_mode?: "all" | "none" | {
163
- item?: boolean | undefined;
164
- wildcard?: boolean | undefined;
165
- position?: boolean | undefined;
166
- } | undefined;
167
- }>;
168
55
  declare const columnSchema: z.ZodDefault<z.ZodObject<{
169
56
  cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "timestamp", "number", "string", "json", "text"]>>;
170
57
  indexes: z.ZodDefault<z.ZodObject<{
171
58
  ore: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
59
+ ope: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
172
60
  unique: z.ZodOptional<z.ZodObject<{
173
61
  token_filters: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
174
62
  kind: z.ZodLiteral<"downcase">;
@@ -255,6 +143,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
255
143
  wildcard?: boolean | undefined;
256
144
  position?: boolean | undefined;
257
145
  }>]>>;
146
+ mode: z.ZodOptional<z.ZodEnum<["compat", "standard"]>>;
258
147
  }, "strip", z.ZodTypeAny, {
259
148
  prefix: string;
260
149
  array_index_mode?: "all" | "none" | {
@@ -262,6 +151,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
262
151
  wildcard?: boolean | undefined;
263
152
  position?: boolean | undefined;
264
153
  } | undefined;
154
+ mode?: "standard" | "compat" | undefined;
265
155
  }, {
266
156
  prefix: string;
267
157
  array_index_mode?: "all" | "none" | {
@@ -269,9 +159,11 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
269
159
  wildcard?: boolean | undefined;
270
160
  position?: boolean | undefined;
271
161
  } | undefined;
162
+ mode?: "standard" | "compat" | undefined;
272
163
  }>>;
273
164
  }, "strip", z.ZodTypeAny, {
274
165
  ore?: {} | undefined;
166
+ ope?: {} | undefined;
275
167
  unique?: {
276
168
  token_filters?: {
277
169
  kind: "downcase";
@@ -298,9 +190,11 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
298
190
  wildcard?: boolean | undefined;
299
191
  position?: boolean | undefined;
300
192
  } | undefined;
193
+ mode?: "standard" | "compat" | undefined;
301
194
  } | undefined;
302
195
  }, {
303
196
  ore?: {} | undefined;
197
+ ope?: {} | undefined;
304
198
  unique?: {
305
199
  token_filters?: {
306
200
  kind: "downcase";
@@ -327,12 +221,14 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
327
221
  wildcard?: boolean | undefined;
328
222
  position?: boolean | undefined;
329
223
  } | undefined;
224
+ mode?: "standard" | "compat" | undefined;
330
225
  } | undefined;
331
226
  }>>;
332
227
  }, "strip", z.ZodTypeAny, {
333
228
  cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "timestamp" | "json" | "text";
334
229
  indexes: {
335
230
  ore?: {} | undefined;
231
+ ope?: {} | undefined;
336
232
  unique?: {
337
233
  token_filters?: {
338
234
  kind: "downcase";
@@ -359,12 +255,14 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
359
255
  wildcard?: boolean | undefined;
360
256
  position?: boolean | undefined;
361
257
  } | undefined;
258
+ mode?: "standard" | "compat" | undefined;
362
259
  } | undefined;
363
260
  };
364
261
  }, {
365
262
  cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "timestamp" | "json" | "text" | undefined;
366
263
  indexes?: {
367
264
  ore?: {} | undefined;
265
+ ope?: {} | undefined;
368
266
  unique?: {
369
267
  token_filters?: {
370
268
  kind: "downcase";
@@ -391,6 +289,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
391
289
  wildcard?: boolean | undefined;
392
290
  position?: boolean | undefined;
393
291
  } | undefined;
292
+ mode?: "standard" | "compat" | undefined;
394
293
  } | undefined;
395
294
  } | undefined;
396
295
  }>>;
@@ -401,6 +300,7 @@ declare const encryptConfigSchema: z.ZodObject<{
401
300
  cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "timestamp", "number", "string", "json", "text"]>>;
402
301
  indexes: z.ZodDefault<z.ZodObject<{
403
302
  ore: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
303
+ ope: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
404
304
  unique: z.ZodOptional<z.ZodObject<{
405
305
  token_filters: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
406
306
  kind: z.ZodLiteral<"downcase">;
@@ -487,6 +387,7 @@ declare const encryptConfigSchema: z.ZodObject<{
487
387
  wildcard?: boolean | undefined;
488
388
  position?: boolean | undefined;
489
389
  }>]>>;
390
+ mode: z.ZodOptional<z.ZodEnum<["compat", "standard"]>>;
490
391
  }, "strip", z.ZodTypeAny, {
491
392
  prefix: string;
492
393
  array_index_mode?: "all" | "none" | {
@@ -494,6 +395,7 @@ declare const encryptConfigSchema: z.ZodObject<{
494
395
  wildcard?: boolean | undefined;
495
396
  position?: boolean | undefined;
496
397
  } | undefined;
398
+ mode?: "standard" | "compat" | undefined;
497
399
  }, {
498
400
  prefix: string;
499
401
  array_index_mode?: "all" | "none" | {
@@ -501,9 +403,11 @@ declare const encryptConfigSchema: z.ZodObject<{
501
403
  wildcard?: boolean | undefined;
502
404
  position?: boolean | undefined;
503
405
  } | undefined;
406
+ mode?: "standard" | "compat" | undefined;
504
407
  }>>;
505
408
  }, "strip", z.ZodTypeAny, {
506
409
  ore?: {} | undefined;
410
+ ope?: {} | undefined;
507
411
  unique?: {
508
412
  token_filters?: {
509
413
  kind: "downcase";
@@ -530,9 +434,11 @@ declare const encryptConfigSchema: z.ZodObject<{
530
434
  wildcard?: boolean | undefined;
531
435
  position?: boolean | undefined;
532
436
  } | undefined;
437
+ mode?: "standard" | "compat" | undefined;
533
438
  } | undefined;
534
439
  }, {
535
440
  ore?: {} | undefined;
441
+ ope?: {} | undefined;
536
442
  unique?: {
537
443
  token_filters?: {
538
444
  kind: "downcase";
@@ -559,12 +465,14 @@ declare const encryptConfigSchema: z.ZodObject<{
559
465
  wildcard?: boolean | undefined;
560
466
  position?: boolean | undefined;
561
467
  } | undefined;
468
+ mode?: "standard" | "compat" | undefined;
562
469
  } | undefined;
563
470
  }>>;
564
471
  }, "strip", z.ZodTypeAny, {
565
472
  cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "timestamp" | "json" | "text";
566
473
  indexes: {
567
474
  ore?: {} | undefined;
475
+ ope?: {} | undefined;
568
476
  unique?: {
569
477
  token_filters?: {
570
478
  kind: "downcase";
@@ -591,12 +499,14 @@ declare const encryptConfigSchema: z.ZodObject<{
591
499
  wildcard?: boolean | undefined;
592
500
  position?: boolean | undefined;
593
501
  } | undefined;
502
+ mode?: "standard" | "compat" | undefined;
594
503
  } | undefined;
595
504
  };
596
505
  }, {
597
506
  cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "timestamp" | "json" | "text" | undefined;
598
507
  indexes?: {
599
508
  ore?: {} | undefined;
509
+ ope?: {} | undefined;
600
510
  unique?: {
601
511
  token_filters?: {
602
512
  kind: "downcase";
@@ -623,6 +533,7 @@ declare const encryptConfigSchema: z.ZodObject<{
623
533
  wildcard?: boolean | undefined;
624
534
  position?: boolean | undefined;
625
535
  } | undefined;
536
+ mode?: "standard" | "compat" | undefined;
626
537
  } | undefined;
627
538
  } | undefined;
628
539
  }>>>>>>;
@@ -632,6 +543,7 @@ declare const encryptConfigSchema: z.ZodObject<{
632
543
  cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "timestamp" | "json" | "text";
633
544
  indexes: {
634
545
  ore?: {} | undefined;
546
+ ope?: {} | undefined;
635
547
  unique?: {
636
548
  token_filters?: {
637
549
  kind: "downcase";
@@ -658,6 +570,7 @@ declare const encryptConfigSchema: z.ZodObject<{
658
570
  wildcard?: boolean | undefined;
659
571
  position?: boolean | undefined;
660
572
  } | undefined;
573
+ mode?: "standard" | "compat" | undefined;
661
574
  } | undefined;
662
575
  };
663
576
  }>>;
@@ -667,6 +580,7 @@ declare const encryptConfigSchema: z.ZodObject<{
667
580
  cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "timestamp" | "json" | "text" | undefined;
668
581
  indexes?: {
669
582
  ore?: {} | undefined;
583
+ ope?: {} | undefined;
670
584
  unique?: {
671
585
  token_filters?: {
672
586
  kind: "downcase";
@@ -693,337 +607,790 @@ declare const encryptConfigSchema: z.ZodObject<{
693
607
  wildcard?: boolean | undefined;
694
608
  position?: boolean | undefined;
695
609
  } | undefined;
610
+ mode?: "standard" | "compat" | undefined;
696
611
  } | undefined;
697
612
  } | undefined;
698
613
  } | undefined> | undefined> | undefined;
699
614
  }>;
615
+ type ColumnSchema = z.infer<typeof columnSchema>;
616
+ type EncryptConfig = z.infer<typeof encryptConfigSchema>;
617
+
700
618
  /**
701
- * Type-safe alias for {@link castAsEnum} used to specify the *unencrypted* data type of a column or value.
702
- * This is important because once encrypted, all data is stored as binary blobs.
619
+ * The query capabilities a v3 concrete domain exposes. These are SDK-facing
620
+ * semantic flags describing what kinds of query terms a column can produce
621
+ * NOT the raw EQL index keys. They are metadata only and never emitted by
622
+ * `build()`.
703
623
  *
704
- * @see {@link castAsEnum} for possible values.
624
+ * - `equality`: exact-match lookups (EQL `hm`, or comparison via `ob`).
625
+ * - `orderAndRange`: comparison / range lookups (EQL `op`, or `ob` on `_ord_ore` domains).
626
+ * - `freeTextSearch`: tokenised substring match (EQL `bf`).
627
+ * - `searchableJson`: encrypted-JSONB containment / selector lookups (EQL
628
+ * `ste_vec`). Optional and mutually exclusive with the scalar flags — a
629
+ * `public.eql_v3_json` document is queried by structure, not by scalar term.
705
630
  */
706
- type CastAs = z.infer<typeof castAsEnum>;
707
- type TokenFilter = z.infer<typeof tokenFilterSchema>;
708
- type MatchIndexOpts = z.infer<typeof matchIndexOptsSchema>;
709
- type SteVecIndexOpts = z.infer<typeof steVecIndexOptsSchema>;
710
- type UniqueIndexOpts = z.infer<typeof uniqueIndexOptsSchema>;
711
- type OreIndexOpts = z.infer<typeof oreIndexOptsSchema>;
712
- type ColumnSchema = z.infer<typeof columnSchema>;
631
+ type QueryCapabilities = Readonly<{
632
+ equality: boolean;
633
+ orderAndRange: boolean;
634
+ freeTextSearch: boolean;
635
+ searchableJson?: boolean;
636
+ }>;
713
637
  /**
714
- * Shape of table columns: either top-level {@link EncryptedColumn} or nested
715
- * objects whose leaves are {@link EncryptedField}. Used with {@link encryptedTable}.
638
+ * The `cast_as` kinds whose decrypted plaintext reconstructs to a JS `Date`.
639
+ *
640
+ * SINGLE SOURCE OF TRUTH for the date-like set. Both the type-level
641
+ * {@link PlaintextFromKind} and the runtime `rowReconstructor` (encryption/v3.ts)
642
+ * derive their "reconstructs to `Date`" decision from this array, so the next
643
+ * `Date`-backed cast is added in exactly one place — never hand-synced across a
644
+ * type and a runtime guard that could silently drift.
645
+ *
646
+ * (`timestamp` reconstructs to `Date` just like `date`, but its `cast_as` tells
647
+ * the FFI not to truncate the time-of-day.)
716
648
  */
717
- type EncryptedTableColumn = {
718
- [key: string]: EncryptedColumn | {
719
- [key: string]: EncryptedField | {
720
- [key: string]: EncryptedField | {
721
- [key: string]: EncryptedField;
722
- };
723
- };
649
+ declare const DATE_LIKE_CASTS: readonly ["date", "timestamp"];
650
+ /** A `cast_as` kind that reconstructs to `Date` — see {@link DATE_LIKE_CASTS}. */
651
+ type DateLikeCast = (typeof DATE_LIKE_CASTS)[number];
652
+ /** The plaintext (TypeScript) kind a v3 domain decrypts to. A subset of the
653
+ * SDK `CastAs` enum, restricted to the scalar kinds v3 domains actually use. */
654
+ type PlaintextKind = 'string' | 'number' | 'bigint' | 'boolean' | 'json' | DateLikeCast;
655
+ /**
656
+ * The full, literal definition of a v3 domain. This is the LOAD-BEARING type:
657
+ * the base column class carries a private field of this type so that every
658
+ * concrete (otherwise-empty) subclass is discriminated by its literal
659
+ * `eqlType`/`castAs`/`capabilities` — TypeScript empty subclasses are NOT
660
+ * nominal, so without this a storage-only `boolean` column would be assignable to
661
+ * a storage-only `date` column and plaintext inference would collapse.
662
+ */
663
+ type V3DomainDefinition = Readonly<{
664
+ eqlType: `public.${string}`;
665
+ castAs: PlaintextKind;
666
+ capabilities: QueryCapabilities;
667
+ }>;
668
+ /** Type-level mirror of {@link isQueryableCapabilities}: `false` for a
669
+ * storage-only domain (all capability flags `false`), `true` otherwise. */
670
+ type QueryableFlag<D extends V3DomainDefinition> = D['capabilities'] extends {
671
+ equality: false;
672
+ orderAndRange: false;
673
+ freeTextSearch: false;
674
+ searchableJson?: false | undefined;
675
+ } ? false : true;
676
+ /**
677
+ * The concrete EQL v3 domain name for a full-capability text column.
678
+ * Recorded as metadata for future DDL / query-dialect increments; it is
679
+ * intentionally absent from the emitted encrypt config.
680
+ */
681
+ declare const TEXT_SEARCH_EQL_TYPE = "public.eql_v3_text_search";
682
+ declare const INTEGER: {
683
+ readonly eqlType: "public.eql_v3_integer";
684
+ readonly castAs: "number";
685
+ readonly capabilities: {
686
+ readonly equality: false;
687
+ readonly orderAndRange: false;
688
+ readonly freeTextSearch: false;
689
+ };
690
+ };
691
+ declare const INTEGER_EQ: {
692
+ readonly eqlType: "public.eql_v3_integer_eq";
693
+ readonly castAs: "number";
694
+ readonly capabilities: {
695
+ readonly equality: true;
696
+ readonly orderAndRange: false;
697
+ readonly freeTextSearch: false;
698
+ };
699
+ };
700
+ declare const INTEGER_ORD_ORE: {
701
+ readonly eqlType: "public.eql_v3_integer_ord_ore";
702
+ readonly castAs: "number";
703
+ readonly capabilities: {
704
+ readonly equality: true;
705
+ readonly orderAndRange: true;
706
+ readonly freeTextSearch: false;
707
+ };
708
+ };
709
+ declare const INTEGER_ORD: {
710
+ readonly eqlType: "public.eql_v3_integer_ord";
711
+ readonly castAs: "number";
712
+ readonly capabilities: {
713
+ readonly equality: true;
714
+ readonly orderAndRange: true;
715
+ readonly freeTextSearch: false;
716
+ };
717
+ };
718
+ declare const SMALLINT: {
719
+ readonly eqlType: "public.eql_v3_smallint";
720
+ readonly castAs: "number";
721
+ readonly capabilities: {
722
+ readonly equality: false;
723
+ readonly orderAndRange: false;
724
+ readonly freeTextSearch: false;
725
+ };
726
+ };
727
+ declare const SMALLINT_EQ: {
728
+ readonly eqlType: "public.eql_v3_smallint_eq";
729
+ readonly castAs: "number";
730
+ readonly capabilities: {
731
+ readonly equality: true;
732
+ readonly orderAndRange: false;
733
+ readonly freeTextSearch: false;
734
+ };
735
+ };
736
+ declare const SMALLINT_ORD_ORE: {
737
+ readonly eqlType: "public.eql_v3_smallint_ord_ore";
738
+ readonly castAs: "number";
739
+ readonly capabilities: {
740
+ readonly equality: true;
741
+ readonly orderAndRange: true;
742
+ readonly freeTextSearch: false;
743
+ };
744
+ };
745
+ declare const SMALLINT_ORD: {
746
+ readonly eqlType: "public.eql_v3_smallint_ord";
747
+ readonly castAs: "number";
748
+ readonly capabilities: {
749
+ readonly equality: true;
750
+ readonly orderAndRange: true;
751
+ readonly freeTextSearch: false;
752
+ };
753
+ };
754
+ declare const BIGINT: {
755
+ readonly eqlType: "public.eql_v3_bigint";
756
+ readonly castAs: "bigint";
757
+ readonly capabilities: {
758
+ readonly equality: false;
759
+ readonly orderAndRange: false;
760
+ readonly freeTextSearch: false;
761
+ };
762
+ };
763
+ declare const BIGINT_EQ: {
764
+ readonly eqlType: "public.eql_v3_bigint_eq";
765
+ readonly castAs: "bigint";
766
+ readonly capabilities: {
767
+ readonly equality: true;
768
+ readonly orderAndRange: false;
769
+ readonly freeTextSearch: false;
770
+ };
771
+ };
772
+ declare const BIGINT_ORD_ORE: {
773
+ readonly eqlType: "public.eql_v3_bigint_ord_ore";
774
+ readonly castAs: "bigint";
775
+ readonly capabilities: {
776
+ readonly equality: true;
777
+ readonly orderAndRange: true;
778
+ readonly freeTextSearch: false;
779
+ };
780
+ };
781
+ declare const BIGINT_ORD: {
782
+ readonly eqlType: "public.eql_v3_bigint_ord";
783
+ readonly castAs: "bigint";
784
+ readonly capabilities: {
785
+ readonly equality: true;
786
+ readonly orderAndRange: true;
787
+ readonly freeTextSearch: false;
788
+ };
789
+ };
790
+ declare const DATE: {
791
+ readonly eqlType: "public.eql_v3_date";
792
+ readonly castAs: "date";
793
+ readonly capabilities: {
794
+ readonly equality: false;
795
+ readonly orderAndRange: false;
796
+ readonly freeTextSearch: false;
797
+ };
798
+ };
799
+ declare const DATE_EQ: {
800
+ readonly eqlType: "public.eql_v3_date_eq";
801
+ readonly castAs: "date";
802
+ readonly capabilities: {
803
+ readonly equality: true;
804
+ readonly orderAndRange: false;
805
+ readonly freeTextSearch: false;
806
+ };
807
+ };
808
+ declare const DATE_ORD_ORE: {
809
+ readonly eqlType: "public.eql_v3_date_ord_ore";
810
+ readonly castAs: "date";
811
+ readonly capabilities: {
812
+ readonly equality: true;
813
+ readonly orderAndRange: true;
814
+ readonly freeTextSearch: false;
815
+ };
816
+ };
817
+ declare const DATE_ORD: {
818
+ readonly eqlType: "public.eql_v3_date_ord";
819
+ readonly castAs: "date";
820
+ readonly capabilities: {
821
+ readonly equality: true;
822
+ readonly orderAndRange: true;
823
+ readonly freeTextSearch: false;
824
+ };
825
+ };
826
+ declare const TIMESTAMP: {
827
+ readonly eqlType: "public.eql_v3_timestamp";
828
+ readonly castAs: "timestamp";
829
+ readonly capabilities: {
830
+ readonly equality: false;
831
+ readonly orderAndRange: false;
832
+ readonly freeTextSearch: false;
833
+ };
834
+ };
835
+ declare const TIMESTAMP_EQ: {
836
+ readonly eqlType: "public.eql_v3_timestamp_eq";
837
+ readonly castAs: "timestamp";
838
+ readonly capabilities: {
839
+ readonly equality: true;
840
+ readonly orderAndRange: false;
841
+ readonly freeTextSearch: false;
842
+ };
843
+ };
844
+ declare const TIMESTAMP_ORD_ORE: {
845
+ readonly eqlType: "public.eql_v3_timestamp_ord_ore";
846
+ readonly castAs: "timestamp";
847
+ readonly capabilities: {
848
+ readonly equality: true;
849
+ readonly orderAndRange: true;
850
+ readonly freeTextSearch: false;
851
+ };
852
+ };
853
+ declare const TIMESTAMP_ORD: {
854
+ readonly eqlType: "public.eql_v3_timestamp_ord";
855
+ readonly castAs: "timestamp";
856
+ readonly capabilities: {
857
+ readonly equality: true;
858
+ readonly orderAndRange: true;
859
+ readonly freeTextSearch: false;
860
+ };
861
+ };
862
+ declare const NUMERIC: {
863
+ readonly eqlType: "public.eql_v3_numeric";
864
+ readonly castAs: "number";
865
+ readonly capabilities: {
866
+ readonly equality: false;
867
+ readonly orderAndRange: false;
868
+ readonly freeTextSearch: false;
869
+ };
870
+ };
871
+ declare const NUMERIC_EQ: {
872
+ readonly eqlType: "public.eql_v3_numeric_eq";
873
+ readonly castAs: "number";
874
+ readonly capabilities: {
875
+ readonly equality: true;
876
+ readonly orderAndRange: false;
877
+ readonly freeTextSearch: false;
878
+ };
879
+ };
880
+ declare const NUMERIC_ORD_ORE: {
881
+ readonly eqlType: "public.eql_v3_numeric_ord_ore";
882
+ readonly castAs: "number";
883
+ readonly capabilities: {
884
+ readonly equality: true;
885
+ readonly orderAndRange: true;
886
+ readonly freeTextSearch: false;
887
+ };
888
+ };
889
+ declare const NUMERIC_ORD: {
890
+ readonly eqlType: "public.eql_v3_numeric_ord";
891
+ readonly castAs: "number";
892
+ readonly capabilities: {
893
+ readonly equality: true;
894
+ readonly orderAndRange: true;
895
+ readonly freeTextSearch: false;
896
+ };
897
+ };
898
+ declare const TEXT: {
899
+ readonly eqlType: "public.eql_v3_text";
900
+ readonly castAs: "string";
901
+ readonly capabilities: {
902
+ readonly equality: false;
903
+ readonly orderAndRange: false;
904
+ readonly freeTextSearch: false;
905
+ };
906
+ };
907
+ declare const TEXT_EQ: {
908
+ readonly eqlType: "public.eql_v3_text_eq";
909
+ readonly castAs: "string";
910
+ readonly capabilities: {
911
+ readonly equality: true;
912
+ readonly orderAndRange: false;
913
+ readonly freeTextSearch: false;
914
+ };
915
+ };
916
+ declare const TEXT_MATCH: {
917
+ readonly eqlType: "public.eql_v3_text_match";
918
+ readonly castAs: "string";
919
+ readonly capabilities: {
920
+ readonly equality: false;
921
+ readonly orderAndRange: false;
922
+ readonly freeTextSearch: true;
923
+ };
924
+ };
925
+ declare const TEXT_ORD_ORE: {
926
+ readonly eqlType: "public.eql_v3_text_ord_ore";
927
+ readonly castAs: "string";
928
+ readonly capabilities: {
929
+ readonly equality: true;
930
+ readonly orderAndRange: true;
931
+ readonly freeTextSearch: false;
932
+ };
933
+ };
934
+ declare const TEXT_ORD: {
935
+ readonly eqlType: "public.eql_v3_text_ord";
936
+ readonly castAs: "string";
937
+ readonly capabilities: {
938
+ readonly equality: true;
939
+ readonly orderAndRange: true;
940
+ readonly freeTextSearch: false;
941
+ };
942
+ };
943
+ declare const BOOLEAN: {
944
+ readonly eqlType: "public.eql_v3_boolean";
945
+ readonly castAs: "boolean";
946
+ readonly capabilities: {
947
+ readonly equality: false;
948
+ readonly orderAndRange: false;
949
+ readonly freeTextSearch: false;
950
+ };
951
+ };
952
+ declare const REAL: {
953
+ readonly eqlType: "public.eql_v3_real";
954
+ readonly castAs: "number";
955
+ readonly capabilities: {
956
+ readonly equality: false;
957
+ readonly orderAndRange: false;
958
+ readonly freeTextSearch: false;
959
+ };
960
+ };
961
+ declare const REAL_EQ: {
962
+ readonly eqlType: "public.eql_v3_real_eq";
963
+ readonly castAs: "number";
964
+ readonly capabilities: {
965
+ readonly equality: true;
966
+ readonly orderAndRange: false;
967
+ readonly freeTextSearch: false;
968
+ };
969
+ };
970
+ declare const REAL_ORD_ORE: {
971
+ readonly eqlType: "public.eql_v3_real_ord_ore";
972
+ readonly castAs: "number";
973
+ readonly capabilities: {
974
+ readonly equality: true;
975
+ readonly orderAndRange: true;
976
+ readonly freeTextSearch: false;
977
+ };
978
+ };
979
+ declare const REAL_ORD: {
980
+ readonly eqlType: "public.eql_v3_real_ord";
981
+ readonly castAs: "number";
982
+ readonly capabilities: {
983
+ readonly equality: true;
984
+ readonly orderAndRange: true;
985
+ readonly freeTextSearch: false;
986
+ };
987
+ };
988
+ declare const DOUBLE: {
989
+ readonly eqlType: "public.eql_v3_double";
990
+ readonly castAs: "number";
991
+ readonly capabilities: {
992
+ readonly equality: false;
993
+ readonly orderAndRange: false;
994
+ readonly freeTextSearch: false;
995
+ };
996
+ };
997
+ declare const DOUBLE_EQ: {
998
+ readonly eqlType: "public.eql_v3_double_eq";
999
+ readonly castAs: "number";
1000
+ readonly capabilities: {
1001
+ readonly equality: true;
1002
+ readonly orderAndRange: false;
1003
+ readonly freeTextSearch: false;
1004
+ };
1005
+ };
1006
+ declare const DOUBLE_ORD_ORE: {
1007
+ readonly eqlType: "public.eql_v3_double_ord_ore";
1008
+ readonly castAs: "number";
1009
+ readonly capabilities: {
1010
+ readonly equality: true;
1011
+ readonly orderAndRange: true;
1012
+ readonly freeTextSearch: false;
1013
+ };
1014
+ };
1015
+ declare const DOUBLE_ORD: {
1016
+ readonly eqlType: "public.eql_v3_double_ord";
1017
+ readonly castAs: "number";
1018
+ readonly capabilities: {
1019
+ readonly equality: true;
1020
+ readonly orderAndRange: true;
1021
+ readonly freeTextSearch: false;
724
1022
  };
725
1023
  };
726
- type EncryptConfig = z.infer<typeof encryptConfigSchema>;
727
1024
  /**
728
- * Builder for a nested encrypted field (encrypted but not searchable).
729
- * Create with {@link encryptedField}. Use inside nested objects in {@link encryptedTable};
730
- * supports `.dataType()` for plaintext type. No index methods (equality, orderAndRange, etc.).
1025
+ * Shared base for every v3 concrete domain column. Parameterised by the FULL
1026
+ * literal {@link V3DomainDefinition} (not by capabilities alone): the private
1027
+ * `definition` field carries the literal `eqlType`/`castAs`/`capabilities`, so
1028
+ * two otherwise-empty subclasses (e.g. `EncryptedBooleanColumn` and
1029
+ * `EncryptedDateColumn`, both storage-only) are NOT mutually assignable. This
1030
+ * nominality is what keeps plaintext inference precise.
731
1031
  */
732
- declare class EncryptedField {
733
- private valueName;
734
- private castAsValue;
735
- constructor(valueName: string);
736
- /**
737
- * Set or override the plaintext data type for this field.
738
- *
739
- * By default all values are treated as `'string'`. Use this method to specify
740
- * a different type so the encryption layer knows how to encode the plaintext
741
- * before encrypting.
742
- *
743
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'text'`, `'bigint'`, or `'json'`.
744
- * @returns This `EncryptedField` instance for method chaining.
745
- *
746
- * @example
747
- * ```typescript
748
- * import { encryptedField } from "@cipherstash/stack/schema"
749
- *
750
- * const age = encryptedField("age").dataType("number")
751
- * ```
752
- */
753
- dataType(castAs: CastAs): this;
754
- build(): {
755
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "timestamp" | "json" | "text";
756
- indexes: {};
757
- };
1032
+ declare class EncryptedV3Column<D extends V3DomainDefinition> {
1033
+ private readonly columnName;
1034
+ private readonly definition;
1035
+ constructor(columnName: string, definition: D);
758
1036
  getName(): string;
1037
+ /** The concrete EQL v3 domain name. Metadata only; not emitted by `build()`. */
1038
+ getEqlType(): D['eqlType'];
1039
+ /** The semantic query capabilities this domain exposes. Metadata only. */
1040
+ getQueryCapabilities(): D['capabilities'];
1041
+ /** `true` when this domain can produce at least one kind of query term. */
1042
+ isQueryable(): QueryableFlag<D>;
1043
+ /** Emit the encrypt-config column: `cast_as` plus capability-derived indexes. */
1044
+ build(): ColumnSchema;
759
1045
  }
760
- declare class EncryptedColumn {
761
- private columnName;
762
- private castAsValue;
763
- private indexesValue;
1046
+ declare const TEXT_SEARCH_DOMAIN: {
1047
+ readonly eqlType: "public.eql_v3_text_search";
1048
+ readonly castAs: "string";
1049
+ readonly capabilities: {
1050
+ readonly equality: true;
1051
+ readonly orderAndRange: true;
1052
+ readonly freeTextSearch: true;
1053
+ };
1054
+ };
1055
+ /**
1056
+ * Builder for a `public.eql_v3_text_search` column.
1057
+ *
1058
+ * The concrete type inherently enables equality + order/range + free-text
1059
+ * match — there are no capability-enabling or tuning methods. The match index
1060
+ * is always emitted with the default configuration.
1061
+ *
1062
+ * NOTE — querying: a `text_search` column emits all three indexes (`unique`,
1063
+ * `ope`, `match`), and the shared index-inference picks them by fixed priority
1064
+ * `unique > match > ordering`. So `encryptQuery(value, { column, table })` with NO
1065
+ * explicit `queryType` builds an EQUALITY term (via `unique`), NOT a free-text
1066
+ * match — a substring like `'joh'` then matches nothing. To run a free-text
1067
+ * match query you MUST pass `queryType: 'freeTextSearch'`:
1068
+ *
1069
+ * ```typescript
1070
+ * // equality (default): exact value only
1071
+ * client.encryptQuery('john@example.com', { column: users.email, table: users })
1072
+ * // free-text match: substring/token search
1073
+ * client.encryptQuery('joh', { column: users.email, table: users, queryType: 'freeTextSearch' })
1074
+ * ```
1075
+ */
1076
+ declare class EncryptedTextSearchColumn extends EncryptedV3Column<typeof TEXT_SEARCH_DOMAIN> {
764
1077
  constructor(columnName: string);
765
- /**
766
- * Set or override the plaintext data type for this column.
767
- *
768
- * By default all columns are treated as `'string'`. Use this method to specify
769
- * a different type so the encryption layer knows how to encode the plaintext
770
- * before encrypting.
771
- *
772
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
773
- * @returns This `EncryptedColumn` instance for method chaining.
774
- *
775
- * @example
776
- * ```typescript
777
- * import { encryptedColumn } from "@cipherstash/stack/schema"
778
- *
779
- * const dateOfBirth = encryptedColumn("date_of_birth").dataType("date")
780
- * ```
781
- */
782
- dataType(castAs: CastAs): this;
783
- /**
784
- * Enable Order-Revealing Encryption (ORE) indexing on this column.
785
- *
786
- * ORE allows sorting, comparison, and range queries on encrypted data.
787
- * Use with `encryptQuery` and `queryType: 'orderAndRange'`.
788
- *
789
- * @returns This `EncryptedColumn` instance for method chaining.
790
- *
791
- * @example
792
- * ```typescript
793
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
794
- *
795
- * const users = encryptedTable("users", {
796
- * email: encryptedColumn("email").orderAndRange(),
797
- * })
798
- * ```
799
- */
800
- orderAndRange(): this;
801
- /**
802
- * Enable an exact-match (unique) index on this column.
803
- *
804
- * Allows equality queries on encrypted data. Use with `encryptQuery`
805
- * and `queryType: 'equality'`.
806
- *
807
- * @param tokenFilters - Optional array of token filters (e.g. `[{ kind: 'downcase' }]`).
808
- * When omitted, no token filters are applied.
809
- * @returns This `EncryptedColumn` instance for method chaining.
810
- *
811
- * @example
812
- * ```typescript
813
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
814
- *
815
- * const users = encryptedTable("users", {
816
- * email: encryptedColumn("email").equality(),
817
- * })
818
- * ```
819
- */
820
- equality(tokenFilters?: TokenFilter[]): this;
821
- /**
822
- * Enable a full-text / fuzzy search (match) index on this column.
823
- *
824
- * Uses n-gram tokenization by default for substring and fuzzy matching.
825
- * Use with `encryptQuery` and `queryType: 'freeTextSearch'`.
826
- *
827
- * @param opts - Optional match index configuration. Defaults to 3-character ngram
828
- * tokenization with a downcase filter, `k=6`, `m=2048`, and `include_original=true`.
829
- * @returns This `EncryptedColumn` instance for method chaining.
830
- *
831
- * @example
832
- * ```typescript
833
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
834
- *
835
- * const users = encryptedTable("users", {
836
- * email: encryptedColumn("email").freeTextSearch(),
837
- * })
838
- *
839
- * // With custom options
840
- * const posts = encryptedTable("posts", {
841
- * body: encryptedColumn("body").freeTextSearch({
842
- * tokenizer: { kind: "ngram", token_length: 4 },
843
- * k: 8,
844
- * m: 4096,
845
- * }),
846
- * })
847
- * ```
848
- */
849
- freeTextSearch(opts?: MatchIndexOpts): this;
850
- /**
851
- * Configure this column for searchable encrypted JSON (STE-Vec).
852
- *
853
- * Enables encrypted JSONPath selector queries (e.g. `'$.user.email'`) and
854
- * containment queries (e.g. `{ role: 'admin' }`). Automatically sets the
855
- * data type to `'json'`.
856
- *
857
- * When used with `encryptQuery`, the query operation is auto-inferred from
858
- * the plaintext type: strings become selector queries, objects/arrays become
859
- * containment queries.
860
- *
861
- * @returns This `EncryptedColumn` instance for method chaining.
862
- *
863
- * @example
864
- * ```typescript
865
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
866
- *
867
- * const documents = encryptedTable("documents", {
868
- * metadata: encryptedColumn("metadata").searchableJson(),
869
- * })
870
- * ```
871
- */
872
- searchableJson(): this;
873
- build(): {
874
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "timestamp" | "json" | "text";
875
- indexes: {
876
- ore?: OreIndexOpts;
877
- unique?: UniqueIndexOpts;
878
- match?: Required<MatchIndexOpts>;
879
- ste_vec?: SteVecIndexOpts;
880
- };
1078
+ }
1079
+ declare class EncryptedIntegerColumn extends EncryptedV3Column<typeof INTEGER> {
1080
+ }
1081
+ declare class EncryptedIntegerEqColumn extends EncryptedV3Column<typeof INTEGER_EQ> {
1082
+ }
1083
+ declare class EncryptedIntegerOrdOreColumn extends EncryptedV3Column<typeof INTEGER_ORD_ORE> {
1084
+ }
1085
+ declare class EncryptedIntegerOrdColumn extends EncryptedV3Column<typeof INTEGER_ORD> {
1086
+ }
1087
+ declare class EncryptedSmallintColumn extends EncryptedV3Column<typeof SMALLINT> {
1088
+ }
1089
+ declare class EncryptedSmallintEqColumn extends EncryptedV3Column<typeof SMALLINT_EQ> {
1090
+ }
1091
+ declare class EncryptedSmallintOrdOreColumn extends EncryptedV3Column<typeof SMALLINT_ORD_ORE> {
1092
+ }
1093
+ declare class EncryptedSmallintOrdColumn extends EncryptedV3Column<typeof SMALLINT_ORD> {
1094
+ }
1095
+ declare class EncryptedBigintColumn extends EncryptedV3Column<typeof BIGINT> {
1096
+ }
1097
+ declare class EncryptedBigintEqColumn extends EncryptedV3Column<typeof BIGINT_EQ> {
1098
+ }
1099
+ declare class EncryptedBigintOrdOreColumn extends EncryptedV3Column<typeof BIGINT_ORD_ORE> {
1100
+ }
1101
+ declare class EncryptedBigintOrdColumn extends EncryptedV3Column<typeof BIGINT_ORD> {
1102
+ }
1103
+ declare class EncryptedDateColumn extends EncryptedV3Column<typeof DATE> {
1104
+ }
1105
+ declare class EncryptedDateEqColumn extends EncryptedV3Column<typeof DATE_EQ> {
1106
+ }
1107
+ declare class EncryptedDateOrdOreColumn extends EncryptedV3Column<typeof DATE_ORD_ORE> {
1108
+ }
1109
+ declare class EncryptedDateOrdColumn extends EncryptedV3Column<typeof DATE_ORD> {
1110
+ }
1111
+ declare class EncryptedTimestampColumn extends EncryptedV3Column<typeof TIMESTAMP> {
1112
+ }
1113
+ declare class EncryptedTimestampEqColumn extends EncryptedV3Column<typeof TIMESTAMP_EQ> {
1114
+ }
1115
+ declare class EncryptedTimestampOrdOreColumn extends EncryptedV3Column<typeof TIMESTAMP_ORD_ORE> {
1116
+ }
1117
+ declare class EncryptedTimestampOrdColumn extends EncryptedV3Column<typeof TIMESTAMP_ORD> {
1118
+ }
1119
+ declare class EncryptedNumericColumn extends EncryptedV3Column<typeof NUMERIC> {
1120
+ }
1121
+ declare class EncryptedNumericEqColumn extends EncryptedV3Column<typeof NUMERIC_EQ> {
1122
+ }
1123
+ declare class EncryptedNumericOrdOreColumn extends EncryptedV3Column<typeof NUMERIC_ORD_ORE> {
1124
+ }
1125
+ declare class EncryptedNumericOrdColumn extends EncryptedV3Column<typeof NUMERIC_ORD> {
1126
+ }
1127
+ declare class EncryptedTextColumn extends EncryptedV3Column<typeof TEXT> {
1128
+ }
1129
+ declare class EncryptedTextEqColumn extends EncryptedV3Column<typeof TEXT_EQ> {
1130
+ }
1131
+ declare class EncryptedTextMatchColumn extends EncryptedV3Column<typeof TEXT_MATCH> {
1132
+ }
1133
+ declare class EncryptedTextOrdOreColumn extends EncryptedV3Column<typeof TEXT_ORD_ORE> {
1134
+ }
1135
+ declare class EncryptedTextOrdColumn extends EncryptedV3Column<typeof TEXT_ORD> {
1136
+ }
1137
+ declare class EncryptedBooleanColumn extends EncryptedV3Column<typeof BOOLEAN> {
1138
+ }
1139
+ declare class EncryptedRealColumn extends EncryptedV3Column<typeof REAL> {
1140
+ }
1141
+ declare class EncryptedRealEqColumn extends EncryptedV3Column<typeof REAL_EQ> {
1142
+ }
1143
+ declare class EncryptedRealOrdOreColumn extends EncryptedV3Column<typeof REAL_ORD_ORE> {
1144
+ }
1145
+ declare class EncryptedRealOrdColumn extends EncryptedV3Column<typeof REAL_ORD> {
1146
+ }
1147
+ declare class EncryptedDoubleColumn extends EncryptedV3Column<typeof DOUBLE> {
1148
+ }
1149
+ declare class EncryptedDoubleEqColumn extends EncryptedV3Column<typeof DOUBLE_EQ> {
1150
+ }
1151
+ declare class EncryptedDoubleOrdOreColumn extends EncryptedV3Column<typeof DOUBLE_ORD_ORE> {
1152
+ }
1153
+ declare class EncryptedDoubleOrdColumn extends EncryptedV3Column<typeof DOUBLE_ORD> {
1154
+ }
1155
+ declare const JSON_DOMAIN: {
1156
+ readonly eqlType: "public.eql_v3_json";
1157
+ readonly castAs: "json";
1158
+ readonly capabilities: {
1159
+ readonly equality: false;
1160
+ readonly orderAndRange: false;
1161
+ readonly freeTextSearch: false;
1162
+ readonly searchableJson: true;
881
1163
  };
882
- getName(): string;
1164
+ };
1165
+ /**
1166
+ * Builder for a `public.eql_v3_json` column — an encrypted JSONB document
1167
+ * (a {@link JsonDocument}: object, array, or null). It round-trips through
1168
+ * `encrypt`/`decrypt`, and containment queries use the encrypted-JSONB index
1169
+ * emitted by `build()`. (The stored payload is protect-ffi's `SteVecDocument`,
1170
+ * and the config index kind is `ste_vec` — both protect-ffi names.)
1171
+ */
1172
+ declare class EncryptedJsonColumn extends EncryptedV3Column<typeof JSON_DOMAIN> {
1173
+ constructor(columnName: string);
883
1174
  }
1175
+ /**
1176
+ * Union of every v3 concrete column type. Used as the value type for v3 table
1177
+ * columns so a table may mix any generated domains.
1178
+ */
1179
+ type AnyEncryptedV3Column = EncryptedIntegerColumn | EncryptedIntegerEqColumn | EncryptedIntegerOrdOreColumn | EncryptedIntegerOrdColumn | EncryptedSmallintColumn | EncryptedSmallintEqColumn | EncryptedSmallintOrdOreColumn | EncryptedSmallintOrdColumn | EncryptedBigintColumn | EncryptedBigintEqColumn | EncryptedBigintOrdOreColumn | EncryptedBigintOrdColumn | EncryptedDateColumn | EncryptedDateEqColumn | EncryptedDateOrdOreColumn | EncryptedDateOrdColumn | EncryptedTimestampColumn | EncryptedTimestampEqColumn | EncryptedTimestampOrdOreColumn | EncryptedTimestampOrdColumn | EncryptedNumericColumn | EncryptedNumericEqColumn | EncryptedNumericOrdOreColumn | EncryptedNumericOrdColumn | EncryptedTextColumn | EncryptedTextEqColumn | EncryptedTextMatchColumn | EncryptedTextOrdOreColumn | EncryptedTextOrdColumn | EncryptedTextSearchColumn | EncryptedBooleanColumn | EncryptedRealColumn | EncryptedRealEqColumn | EncryptedRealOrdOreColumn | EncryptedRealOrdColumn | EncryptedDoubleColumn | EncryptedDoubleEqColumn | EncryptedDoubleOrdOreColumn | EncryptedDoubleOrdColumn | EncryptedJsonColumn;
1180
+ /**
1181
+ * Shape of v3 table columns: every value is a v3 concrete column builder.
1182
+ * (Nested fields are deferred to later increments.)
1183
+ */
1184
+ type EncryptedV3TableColumn = {
1185
+ [key: string]: AnyEncryptedV3Column;
1186
+ };
1187
+ /** A JSON value at any depth. Used for the values NESTED inside a document. */
1188
+ type JsonValue = string | number | boolean | null | JsonValue[] | {
1189
+ [key: string]: JsonValue;
1190
+ };
1191
+ /**
1192
+ * The plaintext a `public.eql_v3_json` column encrypts and reconstructs: a JSON
1193
+ * DOCUMENT — an object, an array, or `null`. NOT a bare top-level scalar:
1194
+ * protect-ffi's `json` cast rejects a top-level string/number/boolean
1195
+ * ("Cannot convert … to Json"), because a scalar belongs in a scalar domain
1196
+ * (`types.TextEq`, `types.IntegerEq`, …). Nested scalars are ordinary
1197
+ * {@link JsonValue}s and are fully supported.
1198
+ */
1199
+ type JsonDocument = null | JsonValue[] | {
1200
+ [key: string]: JsonValue;
1201
+ };
1202
+ /** Map a domain's {@link PlaintextKind} to its TypeScript plaintext type. */
1203
+ type PlaintextFromKind<K extends PlaintextKind> = K extends 'string' ? string : K extends 'number' ? number : K extends 'bigint' ? bigint : K extends 'boolean' ? boolean : K extends DateLikeCast ? Date : K extends 'json' ? JsonDocument : never;
1204
+ /**
1205
+ * The plaintext type for a single v3 column, read from the literal domain
1206
+ * definition carried on the base class's private field. This is stable across
1207
+ * empty subclasses that share the same base generic — a subclass-name
1208
+ * conditional would collapse because those subclasses are structurally
1209
+ * assignable to one another.
1210
+ */
1211
+ type PlaintextForColumn<C> = C extends EncryptedV3Column<infer D> ? PlaintextFromKind<D['castAs']> : never;
1212
+ /**
1213
+ * The user-facing `queryType` names a v3 column supports, derived 1:1 from its
1214
+ * capability flags. Resolves to `never` for a storage-only column (all flags
1215
+ * `false`) and for any non-v3 value. The names mirror the {@link QueryCapabilities}
1216
+ * keys and the first three {@link import('@/types').QueryTypeName} members.
1217
+ */
1218
+ type QueryTypesForColumn<C> = C extends EncryptedV3Column<infer D> ? (D['capabilities']['equality'] extends true ? 'equality' : never) | (D['capabilities']['orderAndRange'] extends true ? 'orderAndRange' : never) | (D['capabilities']['freeTextSearch'] extends true ? 'freeTextSearch' : never) : never;
1219
+ /**
1220
+ * The concrete EQL v3 type string for a single column, read from the literal
1221
+ * domain definition carried on the base class's private field (mirrors
1222
+ * {@link PlaintextForColumn}). Distributes over a union of columns, so
1223
+ * `EqlTypeForColumn<AnyEncryptedV3Column>` yields the union of every domain's
1224
+ * `eqlType` — the canonical, source-of-truth key set for a type-driven test
1225
+ * matrix keyed by domain.
1226
+ */
1227
+ type EqlTypeForColumn<C> = C extends EncryptedV3Column<infer D> ? D['eqlType'] : never;
1228
+
884
1229
  interface TableDefinition {
885
1230
  tableName: string;
886
1231
  columns: Record<string, ColumnSchema>;
887
1232
  }
888
- declare class EncryptedTable<T extends EncryptedTableColumn> {
1233
+ /**
1234
+ * A v3 encrypted table. Mirrors the v2 `EncryptedTable` but only accepts v3
1235
+ * column builders. Emits the same `{ tableName, columns }` definition shape.
1236
+ */
1237
+ declare class EncryptedTable<T extends EncryptedV3TableColumn> {
889
1238
  readonly tableName: string;
890
1239
  readonly columnBuilders: T;
891
1240
  /** @internal Type-level brand so TypeScript can infer `T` from `EncryptedTable<T>`. */
892
1241
  readonly _columnType: T;
893
1242
  constructor(tableName: string, columnBuilders: T);
1243
+ build(): TableDefinition;
894
1244
  /**
895
- * Compile this table schema into a `TableDefinition` used internally by the encryption client.
896
- *
897
- * Iterates over all column builders, calls `.build()` on each, and assembles
898
- * the final `{ tableName, columns }` structure. For `searchableJson()` columns,
899
- * the STE-Vec prefix is automatically set to `"<tableName>/<columnName>"`.
900
- *
901
- * @returns A `TableDefinition` containing the table name and built column configs.
1245
+ * Map each column's JS property name to its DB column name (`getName()`).
1246
+ * The model path matches user models by property name but must address the
1247
+ * encrypt config and FFI by DB name — `build()` keys columns by DB name, so
1248
+ * the two only agree when property == name. This recovers the mapping that
1249
+ * `build()` discards.
902
1250
  *
903
- * @example
904
- * ```typescript
905
- * const users = encryptedTable("users", {
906
- * email: encryptedColumn("email").equality(),
907
- * })
908
- *
909
- * const definition = users.build()
910
- * // { tableName: "users", columns: { email: { cast_as: "string", indexes: { unique: ... } } } }
911
- * ```
1251
+ * NULL PROTOTYPE — load-bearing. Callers index this map by a column name that
1252
+ * ultimately comes from the database (`addJsonbCastsV3`, `filterColumnName`,
1253
+ * the mutation transform). On a plain object literal, a column named
1254
+ * `constructor` / `toString` / `valueOf` / `__proto__` resolves to an
1255
+ * inherited `Object.prototype` member, which is truthy — so a *plaintext*
1256
+ * column with such a name would be mistaken for a mapped encrypted column and
1257
+ * its `Object.prototype` value interpolated into the emitted select string.
1258
+ * `encryptedTable()` rejects such names as JS *properties*, but nothing
1259
+ * constrains the DB column names a table may contain.
912
1260
  */
913
- build(): TableDefinition;
1261
+ buildColumnKeyMap(): Record<string, string>;
914
1262
  }
915
1263
  /**
916
- * Infer the plaintext (decrypted) type from a EncryptedTable schema.
917
- *
918
- * @example
919
- * ```typescript
920
- * const users = encryptedTable("users", {
921
- * email: encryptedColumn("email").equality(),
922
- * name: encryptedColumn("name"),
923
- * })
924
- *
925
- * type UserPlaintext = InferPlaintext<typeof users>
926
- * // => { email: string; name: string }
927
- * ```
1264
+ * Define a v3 encrypted table. Intentionally shadows the v2 `encryptedTable`
1265
+ * name but lives on the `/eql/v3` subpath — the importer picks the model by
1266
+ * import path. The returned object is also a column accessor (`users.email`).
928
1267
  */
929
- type InferPlaintext<T extends EncryptedTable<any>> = T extends EncryptedTable<infer C> ? {
930
- [K in keyof C as C[K] extends EncryptedColumn | EncryptedField ? K : never]: string;
1268
+ declare function encryptedTable<T extends EncryptedV3TableColumn>(tableName: string, columns: T): EncryptedTable<T> & T;
1269
+ /**
1270
+ * Build an `EncryptConfig` (`v: 1`) from one or more v3 tables. Emits the same
1271
+ * shape as v2's `buildEncryptConfig`.
1272
+ */
1273
+ declare function buildEncryptConfig(...tables: Array<EncryptedTable<EncryptedV3TableColumn>>): EncryptConfig;
1274
+ /**
1275
+ * Infer the plaintext (decrypted) shape from a v3 table schema. Each column maps
1276
+ * to the TypeScript type of its domain's `castAs` kind.
1277
+ */
1278
+ type InferPlaintext<T extends EncryptedTable<EncryptedV3TableColumn>> = T extends EncryptedTable<infer C> ? {
1279
+ [K in keyof C]: PlaintextForColumn<C[K]>;
931
1280
  } : never;
932
1281
  /**
933
- * Infer the encrypted type from a EncryptedTable schema.
934
- *
935
- * @example
936
- * ```typescript
937
- * const users = encryptedTable("users", {
938
- * email: encryptedColumn("email").equality(),
939
- * })
940
- *
941
- * type UserEncrypted = InferEncrypted<typeof users>
942
- * // => { email: Encrypted }
943
- * ```
1282
+ * Infer the encrypted shape from a v3 table schema. See {@link InferPlaintext}
1283
+ * for why no key-remap filter is needed in the flat single-type model.
944
1284
  */
945
- type InferEncrypted<T extends EncryptedTable<any>> = T extends EncryptedTable<infer C> ? {
946
- [K in keyof C as C[K] extends EncryptedColumn | EncryptedField ? K : never]: Encrypted;
1285
+ type InferEncrypted<T extends EncryptedTable<EncryptedV3TableColumn>> = T extends EncryptedTable<infer C> ? {
1286
+ [K in keyof C]: Encrypted;
947
1287
  } : never;
1288
+ /** Any v3 table, regardless of its column map. */
1289
+ type AnyV3Table = EncryptedTable<EncryptedV3TableColumn>;
1290
+ /** Union of the concrete column builders declared on a v3 table. */
1291
+ type ColumnsOf<T extends AnyV3Table> = T extends EncryptedTable<infer C> ? C[keyof C] : never;
948
1292
  /**
949
- * Define an encrypted table schema.
950
- *
951
- * Creates a `EncryptedTable` that maps a database table name to a set of encrypted
952
- * column definitions. Pass the resulting object to `Encryption({ schemas: [...] })`
953
- * when initializing the client.
954
- *
955
- * The returned object is also a proxy that exposes each column builder directly,
956
- * so you can reference columns as `users.email` when calling `encrypt`, `decrypt`,
957
- * and `encryptQuery`.
958
- *
959
- * @param tableName - The name of the database table this schema represents.
960
- * @param columns - An object whose keys are logical column names and values are
961
- * {@link EncryptedColumn} from {@link encryptedColumn}, or nested objects whose
962
- * leaves are {@link EncryptedField} from {@link encryptedField}.
963
- * @returns A `EncryptedTable<T> & T` that can be used as both a schema definition
964
- * and a column accessor.
965
- *
966
- * @example
967
- * ```typescript
968
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
969
- *
970
- * const users = encryptedTable("users", {
971
- * email: encryptedColumn("email").equality().freeTextSearch(),
972
- * address: encryptedColumn("address"),
973
- * })
974
- *
975
- * // Use as schema
976
- * const client = await Encryption({ schemas: [users] })
977
- *
978
- * // Use as column accessor
979
- * await client.encrypt("hello@example.com", { column: users.email, table: users })
980
- * ```
1293
+ * Union of the *queryable* column builders on a v3 table. Storage-only columns
1294
+ * (whose {@link QueryTypesForColumn} is `never`) are filtered out, so they can't
1295
+ * be passed to a query method.
981
1296
  */
982
- declare function encryptedTable<T extends EncryptedTableColumn>(tableName: string, columns: T): EncryptedTable<T> & T;
1297
+ type QueryableColumnsOf<T extends AnyV3Table> = T extends EncryptedTable<infer C> ? {
1298
+ [K in keyof C]: [QueryTypesForColumn<C[K]>] extends [never] ? never : C[K];
1299
+ }[keyof C] : never;
983
1300
  /**
984
- * Define an encrypted column within a table schema.
985
- *
986
- * Creates a `EncryptedColumn` builder for the given column name. Chain index
987
- * methods (`.equality()`, `.freeTextSearch()`, `.orderAndRange()`,
988
- * `.searchableJson()`) and/or `.dataType()` to configure searchable encryption
989
- * and the plaintext data type.
990
- *
991
- * @param columnName - The name of the database column to encrypt.
992
- * @returns A new `EncryptedColumn` builder.
993
- *
994
- * @example
995
- * ```typescript
996
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
997
- *
998
- * const users = encryptedTable("users", {
999
- * email: encryptedColumn("email").equality().freeTextSearch().orderAndRange(),
1000
- * })
1001
- * ```
1301
+ * The accepted input model for {@link import('@/encryption/v3').TypedEncryptionClient.encryptModel}.
1302
+ * `T` is inferred from the argument: keys that name a schema column are pinned to
1303
+ * the column's plaintext type (nullable if the field is nullable), so a wrong-typed
1304
+ * field fails assignability; all other keys pass through unchanged.
1002
1305
  */
1003
- declare function encryptedColumn(columnName: string): EncryptedColumn;
1306
+ type V3ModelInput<Table extends AnyV3Table, T> = {
1307
+ [K in keyof T]: K extends keyof InferPlaintext<Table> ? null extends T[K] ? InferPlaintext<Table>[K] | null : InferPlaintext<Table>[K] : T[K];
1308
+ };
1309
+ /** The encrypted result model: schema columns become `Encrypted`, others pass through. */
1310
+ type V3EncryptedModel<Table extends AnyV3Table, T> = {
1311
+ [K in keyof T]: K extends keyof InferPlaintext<Table> ? null extends T[K] ? Encrypted | null : Encrypted : T[K];
1312
+ };
1313
+ /**
1314
+ * The decrypted result model: schema columns become their plaintext type, others
1315
+ * pass through. Structurally identical to {@link V3ModelInput} — decrypt yields
1316
+ * the same plaintext shape encrypt accepts — so it is aliased rather than
1317
+ * re-declared to keep the input and output shapes from silently drifting when
1318
+ * one copy is edited. The distinct name is kept for call-site readability.
1319
+ */
1320
+ type V3DecryptedModel<Table extends AnyV3Table, T> = V3ModelInput<Table, T>;
1321
+
1004
1322
  /**
1005
- * Define an encrypted field for use in nested or structured schemas.
1323
+ * The v3 column-type namespace. Each member is a public, semantic factory name
1324
+ * for a concrete EQL v3 column. Most members mirror the underlying domain name;
1325
+ * JS-friendly scalar names map to Postgres concrete domains, e.g.
1326
+ * `types.IntegerOrd` builds a `public.eql_v3_integer_ord` column and `types.Boolean`
1327
+ * builds a `public.eql_v3_boolean` column.
1006
1328
  *
1007
- * `encryptedField` is similar to {@link encryptedColumn} but creates an {@link EncryptedField}
1008
- * for nested fields that are encrypted but not searchable (no indexes). Use `.dataType()`
1009
- * to specify the plaintext type.
1329
+ * If these factory names stop matching the emitted capability/domain surface,
1330
+ * the stack package is out of sync with the underlying EQL build. That is a
1331
+ * version mismatch, not a harmless naming drift.
1010
1332
  *
1011
- * @param valueName - The name of the value field.
1012
- * @returns A new `EncryptedField` builder.
1333
+ * Each factory returns the CONCRETE column class instance (never the widened
1334
+ * `AnyEncryptedV3Column`) so per-column plaintext / query-capability inference
1335
+ * stays precise.
1013
1336
  *
1014
- * @example
1015
- * ```typescript
1016
- * import { encryptedTable, encryptedField } from "@cipherstash/stack/schema"
1337
+ * ```ts
1338
+ * import { encryptedTable, types } from '@cipherstash/stack/eql/v3'
1017
1339
  *
1018
- * const orders = encryptedTable("orders", {
1019
- * details: {
1020
- * amount: encryptedField("amount").dataType("number"),
1021
- * currency: encryptedField("currency"),
1022
- * },
1340
+ * const events = encryptedTable('events', {
1341
+ * actor: types.TextEq('actor'), // equality
1342
+ * weight: types.IntegerOrd('weight'), // order + range
1343
+ * createdAt: types.Timestamp('created_at'), // storage only
1023
1344
  * })
1024
1345
  * ```
1346
+ *
1347
+ * `types.TextSearch` is fully described by its type — like every other domain,
1348
+ * it has no capability-bearing or tuning chain. Its match index is always
1349
+ * emitted with the default configuration; run a free-text query by passing
1350
+ * `queryType: 'freeTextSearch'` to `encryptQuery`.
1025
1351
  */
1026
- declare function encryptedField(valueName: string): EncryptedField;
1352
+ declare const types: {
1353
+ readonly Integer: (name: string) => EncryptedIntegerColumn;
1354
+ readonly IntegerEq: (name: string) => EncryptedIntegerEqColumn;
1355
+ readonly IntegerOrdOre: (name: string) => EncryptedIntegerOrdOreColumn;
1356
+ readonly IntegerOrd: (name: string) => EncryptedIntegerOrdColumn;
1357
+ readonly Smallint: (name: string) => EncryptedSmallintColumn;
1358
+ readonly SmallintEq: (name: string) => EncryptedSmallintEqColumn;
1359
+ readonly SmallintOrdOre: (name: string) => EncryptedSmallintOrdOreColumn;
1360
+ readonly SmallintOrd: (name: string) => EncryptedSmallintOrdColumn;
1361
+ readonly Bigint: (name: string) => EncryptedBigintColumn;
1362
+ readonly BigintEq: (name: string) => EncryptedBigintEqColumn;
1363
+ readonly BigintOrdOre: (name: string) => EncryptedBigintOrdOreColumn;
1364
+ readonly BigintOrd: (name: string) => EncryptedBigintOrdColumn;
1365
+ readonly Date: (name: string) => EncryptedDateColumn;
1366
+ readonly DateEq: (name: string) => EncryptedDateEqColumn;
1367
+ readonly DateOrdOre: (name: string) => EncryptedDateOrdOreColumn;
1368
+ readonly DateOrd: (name: string) => EncryptedDateOrdColumn;
1369
+ readonly Timestamp: (name: string) => EncryptedTimestampColumn;
1370
+ readonly TimestampEq: (name: string) => EncryptedTimestampEqColumn;
1371
+ readonly TimestampOrdOre: (name: string) => EncryptedTimestampOrdOreColumn;
1372
+ readonly TimestampOrd: (name: string) => EncryptedTimestampOrdColumn;
1373
+ readonly Numeric: (name: string) => EncryptedNumericColumn;
1374
+ readonly NumericEq: (name: string) => EncryptedNumericEqColumn;
1375
+ readonly NumericOrdOre: (name: string) => EncryptedNumericOrdOreColumn;
1376
+ readonly NumericOrd: (name: string) => EncryptedNumericOrdColumn;
1377
+ readonly Text: (name: string) => EncryptedTextColumn;
1378
+ readonly TextEq: (name: string) => EncryptedTextEqColumn;
1379
+ readonly TextMatch: (name: string) => EncryptedTextMatchColumn;
1380
+ readonly TextOrdOre: (name: string) => EncryptedTextOrdOreColumn;
1381
+ readonly TextOrd: (name: string) => EncryptedTextOrdColumn;
1382
+ readonly TextSearch: (name: string) => EncryptedTextSearchColumn;
1383
+ readonly Boolean: (name: string) => EncryptedBooleanColumn;
1384
+ readonly Real: (name: string) => EncryptedRealColumn;
1385
+ readonly RealEq: (name: string) => EncryptedRealEqColumn;
1386
+ readonly RealOrdOre: (name: string) => EncryptedRealOrdOreColumn;
1387
+ readonly RealOrd: (name: string) => EncryptedRealOrdColumn;
1388
+ readonly Double: (name: string) => EncryptedDoubleColumn;
1389
+ readonly DoubleEq: (name: string) => EncryptedDoubleEqColumn;
1390
+ readonly DoubleOrdOre: (name: string) => EncryptedDoubleOrdOreColumn;
1391
+ readonly DoubleOrd: (name: string) => EncryptedDoubleOrdColumn;
1392
+ readonly Json: (name: string) => EncryptedJsonColumn;
1393
+ };
1027
1394
 
1028
1395
  /**
1029
1396
  * WASM-inline entry for `@cipherstash/stack` — for Deno, Bun, Cloudflare
@@ -1037,13 +1404,16 @@ declare function encryptedField(valueName: string): EncryptedField;
1037
1404
  *
1038
1405
  * Use this import path: `@cipherstash/stack/wasm-inline`
1039
1406
  *
1407
+ * This entry is EQL v3: author schemas with the `types` DSL / `encryptedTable`
1408
+ * re-exported here (the same authoring surface as `@cipherstash/stack/eql/v3`).
1409
+ *
1040
1410
  * @example
1041
1411
  * ```ts
1042
1412
  * import {
1043
- * Encryption, encryptedTable, encryptedColumn,
1413
+ * Encryption, encryptedTable, types,
1044
1414
  * } from "@cipherstash/stack/wasm-inline"
1045
1415
  *
1046
- * const users = encryptedTable("users", { email: encryptedColumn("email") })
1416
+ * const users = encryptedTable("users", { email: types.TextSearch("email") })
1047
1417
  *
1048
1418
  * const client = await Encryption({
1049
1419
  * schemas: [users],
@@ -1089,10 +1459,15 @@ declare function isEncrypted(value: unknown): boolean;
1089
1459
  /**
1090
1460
  * The plaintext shape accepted by `encrypt` and returned by `decrypt`.
1091
1461
  * Mirrors protect-ffi's `JsPlaintext` (recursive: arrays of any of
1092
- * these are valid). Re-defined here so the wasm-inline `.d.ts` doesn't
1093
- * pull in the Node-only protect-ffi types.
1462
+ * these are valid), plus `bigint` for `int8` columns. Re-defined here so
1463
+ * the wasm-inline `.d.ts` doesn't pull in the Node-only protect-ffi types.
1464
+ *
1465
+ * `bigint` is carried natively across the wasm boundary by protect-ffi
1466
+ * 0.28's Rust `encode_plaintext` (which i64-bounds-checks on encrypt and
1467
+ * builds a `js_sys::BigInt` on decrypt), so widening the type here is all
1468
+ * the SDK needs to accept/return `bigint` on the wasm entry point.
1094
1469
  */
1095
- type WasmPlaintext = string | number | boolean | null | Record<string, unknown> | WasmPlaintext[];
1470
+ type WasmPlaintext = string | number | bigint | boolean | null | Record<string, unknown> | WasmPlaintext[];
1096
1471
  /**
1097
1472
  * Config for {@link Encryption} on the WASM entry point.
1098
1473
  *
@@ -1172,10 +1547,9 @@ type WasmClientConfig = {
1172
1547
  */
1173
1548
  type WasmAuthStrategy = AccessKeyStrategy | OidcFederationStrategy;
1174
1549
  type WasmEncryptionConfig = {
1175
- schemas: [
1176
- EncryptedTable<EncryptedTableColumn>,
1177
- ...EncryptedTable<EncryptedTableColumn>[]
1178
- ];
1550
+ /** One or more EQL v3 tables, authored with `types` / `encryptedTable` from
1551
+ * this entry. The WASM entry is EQL v3 only. */
1552
+ schemas: [AnyV3Table, ...AnyV3Table[]];
1179
1553
  config: WasmClientConfig;
1180
1554
  };
1181
1555
  /**
@@ -1266,4 +1640,4 @@ declare function __resetStrategyDeprecationWarningForTests(): void;
1266
1640
  */
1267
1641
  declare function resolveStrategy(cfg: WasmClientConfig): WasmAuthStrategy;
1268
1642
 
1269
- export { type Encrypted, EncryptedColumn, EncryptedField, EncryptedTable, type EncryptedTableColumn, Encryption, type InferEncrypted, type InferPlaintext, type WasmAuthStrategy, type WasmClientConfig, WasmEncryptionClient, type WasmEncryptionConfig, type WasmPlaintext, __resetStrategyDeprecationWarningForTests, encryptedColumn, encryptedField, encryptedTable, getColumnName, isEncrypted, normalizeCastAs, resolveStrategy };
1643
+ export { type AnyEncryptedV3Column, type AnyV3Table, type ColumnsOf, type Encrypted, EncryptedBigintColumn, EncryptedBigintEqColumn, EncryptedBigintOrdColumn, EncryptedBigintOrdOreColumn, EncryptedBooleanColumn, EncryptedDateColumn, EncryptedDateEqColumn, EncryptedDateOrdColumn, EncryptedDateOrdOreColumn, EncryptedDoubleColumn, EncryptedDoubleEqColumn, EncryptedDoubleOrdColumn, EncryptedDoubleOrdOreColumn, EncryptedIntegerColumn, EncryptedIntegerEqColumn, EncryptedIntegerOrdColumn, EncryptedIntegerOrdOreColumn, EncryptedJsonColumn, EncryptedNumericColumn, EncryptedNumericEqColumn, EncryptedNumericOrdColumn, EncryptedNumericOrdOreColumn, EncryptedRealColumn, EncryptedRealEqColumn, EncryptedRealOrdColumn, EncryptedRealOrdOreColumn, EncryptedSmallintColumn, EncryptedSmallintEqColumn, EncryptedSmallintOrdColumn, EncryptedSmallintOrdOreColumn, EncryptedTable, EncryptedTextColumn, EncryptedTextEqColumn, EncryptedTextMatchColumn, EncryptedTextOrdColumn, EncryptedTextOrdOreColumn, EncryptedTextSearchColumn, EncryptedTimestampColumn, EncryptedTimestampEqColumn, EncryptedTimestampOrdColumn, EncryptedTimestampOrdOreColumn, type EncryptedV3TableColumn, Encryption, type EqlTypeForColumn, type InferEncrypted, type InferPlaintext, type JsonDocument, type JsonValue, type PlaintextForColumn, type QueryCapabilities, type QueryTypesForColumn, type QueryableColumnsOf, TEXT_SEARCH_EQL_TYPE, type V3DecryptedModel, type V3EncryptedModel, type V3ModelInput, type WasmAuthStrategy, type WasmClientConfig, WasmEncryptionClient, type WasmEncryptionConfig, type WasmPlaintext, __resetStrategyDeprecationWarningForTests, buildEncryptConfig, encryptedTable, getColumnName, isEncrypted, normalizeCastAs, resolveStrategy, types };