@cipherstash/stack 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/dist/bin/stash.js +46 -141
  4. package/dist/bin/stash.js.map +1 -1
  5. package/dist/{chunk-SUYMGQBY.js → chunk-4RNBI3UH.js} +1 -7
  6. package/dist/chunk-4RNBI3UH.js.map +1 -0
  7. package/dist/{chunk-JLI27P46.js → chunk-KOU2MHXJ.js} +1 -1
  8. package/dist/chunk-KOU2MHXJ.js.map +1 -0
  9. package/dist/{chunk-MW6D52V2.js → chunk-WUZGKTMG.js} +45 -134
  10. package/dist/chunk-WUZGKTMG.js.map +1 -0
  11. package/dist/{chunk-TBAIVO6T.js → chunk-Y35W4WFN.js} +6 -6
  12. package/dist/chunk-Y35W4WFN.js.map +1 -0
  13. package/dist/{client-Bf0Xw2xo.d.cts → client-CUGXheRq.d.cts} +15 -16
  14. package/dist/{client-Kfp8OsPB.d.ts → client-CrGQnSlk.d.ts} +15 -16
  15. package/dist/client.cjs +5 -5
  16. package/dist/client.cjs.map +1 -1
  17. package/dist/client.d.cts +2 -2
  18. package/dist/client.d.ts +2 -2
  19. package/dist/client.js +1 -1
  20. package/dist/drizzle/index.cjs +5 -5
  21. package/dist/drizzle/index.cjs.map +1 -1
  22. package/dist/drizzle/index.d.cts +2 -2
  23. package/dist/drizzle/index.d.ts +2 -2
  24. package/dist/drizzle/index.js +2 -2
  25. package/dist/dynamodb/index.d.cts +2 -2
  26. package/dist/dynamodb/index.d.ts +2 -2
  27. package/dist/index.cjs +46 -141
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +3 -3
  30. package/dist/index.d.ts +3 -3
  31. package/dist/index.js +4 -4
  32. package/dist/schema/index.cjs +5 -5
  33. package/dist/schema/index.cjs.map +1 -1
  34. package/dist/schema/index.d.cts +1 -1
  35. package/dist/schema/index.d.ts +1 -1
  36. package/dist/schema/index.js +1 -1
  37. package/dist/secrets/index.cjs +46 -141
  38. package/dist/secrets/index.cjs.map +1 -1
  39. package/dist/secrets/index.d.cts +1 -1
  40. package/dist/secrets/index.d.ts +1 -1
  41. package/dist/secrets/index.js +4 -4
  42. package/dist/supabase/index.cjs +2 -2
  43. package/dist/supabase/index.cjs.map +1 -1
  44. package/dist/supabase/index.d.cts +2 -2
  45. package/dist/supabase/index.d.ts +2 -2
  46. package/dist/supabase/index.js +2 -2
  47. package/dist/{types-public-0CzBV45X.d.cts → types-public-Wj6tB_ux.d.cts} +47 -26
  48. package/dist/{types-public-0CzBV45X.d.ts → types-public-Wj6tB_ux.d.ts} +47 -26
  49. package/dist/types-public.cjs.map +1 -1
  50. package/dist/types-public.d.cts +1 -1
  51. package/dist/types-public.d.ts +1 -1
  52. package/dist/types-public.js +1 -1
  53. package/package.json +2 -2
  54. package/dist/chunk-JLI27P46.js.map +0 -1
  55. package/dist/chunk-MW6D52V2.js.map +0 -1
  56. package/dist/chunk-SUYMGQBY.js.map +0 -1
  57. package/dist/chunk-TBAIVO6T.js.map +0 -1
@@ -16,10 +16,9 @@ type Brand<T, B extends string> = T & {
16
16
  };
17
17
  type Client = Awaited<ReturnType<typeof newClient>> | undefined;
18
18
  /** A branded type representing encrypted data. Cannot be accidentally used as plaintext. */
19
- type EncryptedValue = Brand<Encrypted$1, 'encrypted'> | null;
19
+ type EncryptedValue = Brand<Encrypted$1, 'encrypted'>;
20
20
  /** Structural type representing encrypted data. See also `EncryptedValue` for branded nominal typing. */
21
- type Encrypted = Encrypted$1 | null;
22
- type EncryptPayload = JsPlaintext | null;
21
+ type Encrypted = Encrypted$1;
23
22
  type KeysetIdentifier = {
24
23
  name: string;
25
24
  } | {
@@ -85,16 +84,16 @@ type SearchTerm = {
85
84
  };
86
85
  /** Encrypted search term result: EQL object or composite literal string */
87
86
  type EncryptedSearchTerm = Encrypted | string;
88
- /** Result of encryptQuery (single or batch): EQL, composite literal string, or null */
89
- type EncryptedQueryResult = Encrypted | string | null;
87
+ /** Result of encryptQuery (single or batch): EQL or composite literal string */
88
+ type EncryptedQueryResult = Encrypted | string;
90
89
  type EncryptedFields<T> = {
91
- [K in keyof T as T[K] extends Encrypted ? K : never]: T[K];
90
+ [K in keyof T as NonNullable<T[K]> extends Encrypted ? K : never]: T[K];
92
91
  };
93
92
  type OtherFields<T> = {
94
- [K in keyof T as T[K] extends Encrypted ? never : K]: T[K];
93
+ [K in keyof T as NonNullable<T[K]> extends Encrypted ? never : K]: T[K];
95
94
  };
96
95
  type DecryptedFields<T> = {
97
- [K in keyof T as T[K] extends Encrypted ? K : never]: string;
96
+ [K in keyof T as NonNullable<T[K]> extends Encrypted ? K : never]: null extends T[K] ? string | null : string;
98
97
  };
99
98
  /** Model with encrypted fields replaced by plaintext (decrypted) values */
100
99
  type Decrypted<T> = OtherFields<T> & DecryptedFields<T>;
@@ -120,11 +119,11 @@ type Decrypted<T> = OtherFields<T> & DecryptedFields<T>;
120
119
  * ```
121
120
  */
122
121
  type EncryptedFromSchema<T, S extends EncryptedTableColumn> = {
123
- [K in keyof T]: [K] extends [keyof S] ? [S[K & keyof S]] extends [EncryptedColumn | EncryptedField] ? Encrypted : T[K] : T[K];
122
+ [K in keyof T]: [K] extends [keyof S] ? [S[K & keyof S]] extends [EncryptedColumn | EncryptedField] ? null extends T[K] ? Encrypted | null : Encrypted : T[K] : T[K];
124
123
  };
125
124
  type BulkEncryptPayload = Array<{
126
125
  id?: string;
127
- plaintext: JsPlaintext | null;
126
+ plaintext: JsPlaintext;
128
127
  }>;
129
128
  type BulkEncryptedData = Array<{
130
129
  id?: string;
@@ -134,7 +133,7 @@ type BulkDecryptPayload = Array<{
134
133
  id?: string;
135
134
  data: Encrypted;
136
135
  }>;
137
- type BulkDecryptedData = Array<DecryptionResult<JsPlaintext | null>>;
136
+ type BulkDecryptedData = Array<DecryptionResult<JsPlaintext>>;
138
137
  type DecryptionSuccess<T> = {
139
138
  error?: never;
140
139
  data: T;
@@ -179,7 +178,7 @@ type QueryTermBase = {
179
178
  };
180
179
  type EncryptQueryOptions = QueryTermBase;
181
180
  type ScalarQueryTerm = QueryTermBase & {
182
- value: JsPlaintext | null;
181
+ value: JsPlaintext;
183
182
  };
184
183
 
185
184
  /**
@@ -192,6 +191,7 @@ type ScalarQueryTerm = QueryTermBase & {
192
191
  * - `"number"`
193
192
  * - `"string"`
194
193
  * - `"json"`
194
+ * - `"text"`
195
195
  *
196
196
  * @remarks
197
197
  * This is a Zod enum used at runtime to validate schema definitions.
@@ -199,7 +199,7 @@ type ScalarQueryTerm = QueryTermBase & {
199
199
  *
200
200
  * @internal
201
201
  */
202
- declare const castAsEnum: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json"]>>;
202
+ declare const castAsEnum: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json", "text"]>>;
203
203
  declare const tokenFilterSchema: z.ZodObject<{
204
204
  kind: z.ZodLiteral<"downcase">;
205
205
  }, "strip", z.ZodTypeAny, {
@@ -287,7 +287,7 @@ declare const steVecIndexOptsSchema: z.ZodObject<{
287
287
  prefix: string;
288
288
  }>;
289
289
  declare const columnSchema: z.ZodDefault<z.ZodObject<{
290
- cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json"]>>;
290
+ cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json", "text"]>>;
291
291
  indexes: z.ZodDefault<z.ZodObject<{
292
292
  ore: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
293
293
  unique: z.ZodOptional<z.ZodObject<{
@@ -418,7 +418,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
418
418
  } | undefined;
419
419
  }>>;
420
420
  }, "strip", z.ZodTypeAny, {
421
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json";
421
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
422
422
  indexes: {
423
423
  match?: {
424
424
  token_filters?: {
@@ -445,7 +445,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
445
445
  } | undefined;
446
446
  };
447
447
  }, {
448
- cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | undefined;
448
+ cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text" | undefined;
449
449
  indexes?: {
450
450
  match?: {
451
451
  token_filters?: {
@@ -476,7 +476,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
476
476
  declare const encryptConfigSchema: z.ZodObject<{
477
477
  v: z.ZodNumber;
478
478
  tables: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodDefault<z.ZodObject<{
479
- cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json"]>>;
479
+ cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json", "text"]>>;
480
480
  indexes: z.ZodDefault<z.ZodObject<{
481
481
  ore: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
482
482
  unique: z.ZodOptional<z.ZodObject<{
@@ -607,7 +607,7 @@ declare const encryptConfigSchema: z.ZodObject<{
607
607
  } | undefined;
608
608
  }>>;
609
609
  }, "strip", z.ZodTypeAny, {
610
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json";
610
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
611
611
  indexes: {
612
612
  match?: {
613
613
  token_filters?: {
@@ -634,7 +634,7 @@ declare const encryptConfigSchema: z.ZodObject<{
634
634
  } | undefined;
635
635
  };
636
636
  }, {
637
- cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | undefined;
637
+ cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text" | undefined;
638
638
  indexes?: {
639
639
  match?: {
640
640
  token_filters?: {
@@ -664,7 +664,7 @@ declare const encryptConfigSchema: z.ZodObject<{
664
664
  }, "strip", z.ZodTypeAny, {
665
665
  v: number;
666
666
  tables: Record<string, Record<string, {
667
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json";
667
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
668
668
  indexes: {
669
669
  match?: {
670
670
  token_filters?: {
@@ -694,7 +694,7 @@ declare const encryptConfigSchema: z.ZodObject<{
694
694
  }, {
695
695
  v: number;
696
696
  tables?: Record<string, Record<string, {
697
- cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | undefined;
697
+ cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text" | undefined;
698
698
  indexes?: {
699
699
  match?: {
700
700
  token_filters?: {
@@ -765,7 +765,7 @@ declare class EncryptedField {
765
765
  * a different type so the encryption layer knows how to encode the plaintext
766
766
  * before encrypting.
767
767
  *
768
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
768
+ * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'text'`, `'bigint'`, or `'json'`.
769
769
  * @returns This `EncryptedField` instance for method chaining.
770
770
  *
771
771
  * @example
@@ -777,7 +777,7 @@ declare class EncryptedField {
777
777
  */
778
778
  dataType(castAs: CastAs): this;
779
779
  build(): {
780
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json";
780
+ cast_as: "number" | "bigint" | "boolean" | "date" | "json" | "text";
781
781
  indexes: {};
782
782
  };
783
783
  getName(): string;
@@ -896,7 +896,7 @@ declare class EncryptedColumn {
896
896
  */
897
897
  searchableJson(): this;
898
898
  build(): {
899
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json";
899
+ cast_as: "number" | "bigint" | "boolean" | "date" | "json" | "text";
900
900
  indexes: {
901
901
  ore?: OreIndexOpts;
902
902
  unique?: UniqueIndexOpts;
@@ -1049,7 +1049,28 @@ declare function encryptedColumn(columnName: string): EncryptedColumn;
1049
1049
  * ```
1050
1050
  */
1051
1051
  declare function encryptedField(valueName: string): EncryptedField;
1052
- /** @internal */
1052
+ /**
1053
+ * Build an encrypt config from a list of encrypted tables.
1054
+ *
1055
+ * @param ...tables - The list of encrypted tables to build the config from.
1056
+ * @returns An encrypt config object.
1057
+ *
1058
+ * @example
1059
+ * ```typescript
1060
+ * import { buildEncryptConfig } from "@cipherstash/stack/schema"
1061
+ *
1062
+ * const users = encryptedTable("users", {
1063
+ * email: encryptedColumn("email").equality(),
1064
+ * })
1065
+ *
1066
+ * const orders = encryptedTable("orders", {
1067
+ * amount: encryptedColumn("amount").dataType("number"),
1068
+ * })
1069
+ *
1070
+ * const config = buildEncryptConfig(users, orders)
1071
+ * console.log(config)
1072
+ * ```
1073
+ */
1053
1074
  declare function buildEncryptConfig(...protectTables: Array<EncryptedTable<EncryptedTableColumn>>): EncryptConfig;
1054
1075
 
1055
- export { type ClientConfig as A, type BulkDecryptedData as B, type CastAs as C, type Decrypted as D, type EncryptionClientConfig as E, type SearchTerm as F, type EncryptedSearchTerm as G, type EncryptedFields as H, type InferPlaintext as I, type OtherFields as J, type KeysetIdentifier as K, type DecryptedFields as L, type MatchIndexOpts as M, type DecryptionResult as N, type OreIndexOpts as O, type LoggingConfig as P, type QueryTypeName as Q, queryTypes as R, type ScalarQueryTerm as S, type TokenFilter as T, type UniqueIndexOpts as U, encryptedColumn as a, encryptedField as b, type InferEncrypted as c, EncryptedColumn as d, encryptedTable as e, EncryptedTable as f, type EncryptedTableColumn as g, EncryptedField as h, type EncryptedFromSchema as i, type Encrypted as j, type EncryptedValue as k, type EncryptedQueryResult as l, type Client as m, type BulkDecryptPayload as n, type BulkEncryptedData as o, type BulkEncryptPayload as p, type EncryptOptions as q, type EncryptQueryOptions as r, type EncryptedReturnType as s, type EncryptConfig as t, castAsEnum as u, encryptConfigSchema as v, type SteVecIndexOpts as w, type ColumnSchema as x, buildEncryptConfig as y, type EncryptPayload as z };
1076
+ export { type SearchTerm as A, type BulkDecryptedData as B, type CastAs as C, type Decrypted as D, type EncryptionClientConfig as E, type EncryptedSearchTerm as F, type EncryptedFields as G, type OtherFields as H, type InferPlaintext as I, type DecryptedFields as J, type KeysetIdentifier as K, type DecryptionResult as L, type MatchIndexOpts as M, type LoggingConfig as N, type OreIndexOpts as O, queryTypes as P, type QueryTypeName as Q, type ScalarQueryTerm as S, type TokenFilter as T, type UniqueIndexOpts as U, encryptedColumn as a, encryptedField as b, type InferEncrypted as c, EncryptedColumn as d, encryptedTable as e, EncryptedTable as f, type EncryptedTableColumn as g, EncryptedField as h, type EncryptedFromSchema as i, type Encrypted as j, type EncryptedValue as k, type EncryptedQueryResult as l, type Client as m, type BulkDecryptPayload as n, type BulkEncryptedData as o, type BulkEncryptPayload as p, type EncryptOptions as q, type EncryptQueryOptions as r, type EncryptedReturnType as s, type EncryptConfig as t, castAsEnum as u, encryptConfigSchema as v, type SteVecIndexOpts as w, type ColumnSchema as x, buildEncryptConfig as y, type ClientConfig as z };
@@ -16,10 +16,9 @@ type Brand<T, B extends string> = T & {
16
16
  };
17
17
  type Client = Awaited<ReturnType<typeof newClient>> | undefined;
18
18
  /** A branded type representing encrypted data. Cannot be accidentally used as plaintext. */
19
- type EncryptedValue = Brand<Encrypted$1, 'encrypted'> | null;
19
+ type EncryptedValue = Brand<Encrypted$1, 'encrypted'>;
20
20
  /** Structural type representing encrypted data. See also `EncryptedValue` for branded nominal typing. */
21
- type Encrypted = Encrypted$1 | null;
22
- type EncryptPayload = JsPlaintext | null;
21
+ type Encrypted = Encrypted$1;
23
22
  type KeysetIdentifier = {
24
23
  name: string;
25
24
  } | {
@@ -85,16 +84,16 @@ type SearchTerm = {
85
84
  };
86
85
  /** Encrypted search term result: EQL object or composite literal string */
87
86
  type EncryptedSearchTerm = Encrypted | string;
88
- /** Result of encryptQuery (single or batch): EQL, composite literal string, or null */
89
- type EncryptedQueryResult = Encrypted | string | null;
87
+ /** Result of encryptQuery (single or batch): EQL or composite literal string */
88
+ type EncryptedQueryResult = Encrypted | string;
90
89
  type EncryptedFields<T> = {
91
- [K in keyof T as T[K] extends Encrypted ? K : never]: T[K];
90
+ [K in keyof T as NonNullable<T[K]> extends Encrypted ? K : never]: T[K];
92
91
  };
93
92
  type OtherFields<T> = {
94
- [K in keyof T as T[K] extends Encrypted ? never : K]: T[K];
93
+ [K in keyof T as NonNullable<T[K]> extends Encrypted ? never : K]: T[K];
95
94
  };
96
95
  type DecryptedFields<T> = {
97
- [K in keyof T as T[K] extends Encrypted ? K : never]: string;
96
+ [K in keyof T as NonNullable<T[K]> extends Encrypted ? K : never]: null extends T[K] ? string | null : string;
98
97
  };
99
98
  /** Model with encrypted fields replaced by plaintext (decrypted) values */
100
99
  type Decrypted<T> = OtherFields<T> & DecryptedFields<T>;
@@ -120,11 +119,11 @@ type Decrypted<T> = OtherFields<T> & DecryptedFields<T>;
120
119
  * ```
121
120
  */
122
121
  type EncryptedFromSchema<T, S extends EncryptedTableColumn> = {
123
- [K in keyof T]: [K] extends [keyof S] ? [S[K & keyof S]] extends [EncryptedColumn | EncryptedField] ? Encrypted : T[K] : T[K];
122
+ [K in keyof T]: [K] extends [keyof S] ? [S[K & keyof S]] extends [EncryptedColumn | EncryptedField] ? null extends T[K] ? Encrypted | null : Encrypted : T[K] : T[K];
124
123
  };
125
124
  type BulkEncryptPayload = Array<{
126
125
  id?: string;
127
- plaintext: JsPlaintext | null;
126
+ plaintext: JsPlaintext;
128
127
  }>;
129
128
  type BulkEncryptedData = Array<{
130
129
  id?: string;
@@ -134,7 +133,7 @@ type BulkDecryptPayload = Array<{
134
133
  id?: string;
135
134
  data: Encrypted;
136
135
  }>;
137
- type BulkDecryptedData = Array<DecryptionResult<JsPlaintext | null>>;
136
+ type BulkDecryptedData = Array<DecryptionResult<JsPlaintext>>;
138
137
  type DecryptionSuccess<T> = {
139
138
  error?: never;
140
139
  data: T;
@@ -179,7 +178,7 @@ type QueryTermBase = {
179
178
  };
180
179
  type EncryptQueryOptions = QueryTermBase;
181
180
  type ScalarQueryTerm = QueryTermBase & {
182
- value: JsPlaintext | null;
181
+ value: JsPlaintext;
183
182
  };
184
183
 
185
184
  /**
@@ -192,6 +191,7 @@ type ScalarQueryTerm = QueryTermBase & {
192
191
  * - `"number"`
193
192
  * - `"string"`
194
193
  * - `"json"`
194
+ * - `"text"`
195
195
  *
196
196
  * @remarks
197
197
  * This is a Zod enum used at runtime to validate schema definitions.
@@ -199,7 +199,7 @@ type ScalarQueryTerm = QueryTermBase & {
199
199
  *
200
200
  * @internal
201
201
  */
202
- declare const castAsEnum: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json"]>>;
202
+ declare const castAsEnum: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json", "text"]>>;
203
203
  declare const tokenFilterSchema: z.ZodObject<{
204
204
  kind: z.ZodLiteral<"downcase">;
205
205
  }, "strip", z.ZodTypeAny, {
@@ -287,7 +287,7 @@ declare const steVecIndexOptsSchema: z.ZodObject<{
287
287
  prefix: string;
288
288
  }>;
289
289
  declare const columnSchema: z.ZodDefault<z.ZodObject<{
290
- cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json"]>>;
290
+ cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json", "text"]>>;
291
291
  indexes: z.ZodDefault<z.ZodObject<{
292
292
  ore: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
293
293
  unique: z.ZodOptional<z.ZodObject<{
@@ -418,7 +418,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
418
418
  } | undefined;
419
419
  }>>;
420
420
  }, "strip", z.ZodTypeAny, {
421
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json";
421
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
422
422
  indexes: {
423
423
  match?: {
424
424
  token_filters?: {
@@ -445,7 +445,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
445
445
  } | undefined;
446
446
  };
447
447
  }, {
448
- cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | undefined;
448
+ cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text" | undefined;
449
449
  indexes?: {
450
450
  match?: {
451
451
  token_filters?: {
@@ -476,7 +476,7 @@ declare const columnSchema: z.ZodDefault<z.ZodObject<{
476
476
  declare const encryptConfigSchema: z.ZodObject<{
477
477
  v: z.ZodNumber;
478
478
  tables: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodDefault<z.ZodObject<{
479
- cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json"]>>;
479
+ cast_as: z.ZodDefault<z.ZodEnum<["bigint", "boolean", "date", "number", "string", "json", "text"]>>;
480
480
  indexes: z.ZodDefault<z.ZodObject<{
481
481
  ore: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
482
482
  unique: z.ZodOptional<z.ZodObject<{
@@ -607,7 +607,7 @@ declare const encryptConfigSchema: z.ZodObject<{
607
607
  } | undefined;
608
608
  }>>;
609
609
  }, "strip", z.ZodTypeAny, {
610
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json";
610
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
611
611
  indexes: {
612
612
  match?: {
613
613
  token_filters?: {
@@ -634,7 +634,7 @@ declare const encryptConfigSchema: z.ZodObject<{
634
634
  } | undefined;
635
635
  };
636
636
  }, {
637
- cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | undefined;
637
+ cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text" | undefined;
638
638
  indexes?: {
639
639
  match?: {
640
640
  token_filters?: {
@@ -664,7 +664,7 @@ declare const encryptConfigSchema: z.ZodObject<{
664
664
  }, "strip", z.ZodTypeAny, {
665
665
  v: number;
666
666
  tables: Record<string, Record<string, {
667
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json";
667
+ cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text";
668
668
  indexes: {
669
669
  match?: {
670
670
  token_filters?: {
@@ -694,7 +694,7 @@ declare const encryptConfigSchema: z.ZodObject<{
694
694
  }, {
695
695
  v: number;
696
696
  tables?: Record<string, Record<string, {
697
- cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | undefined;
697
+ cast_as?: "string" | "number" | "bigint" | "boolean" | "date" | "json" | "text" | undefined;
698
698
  indexes?: {
699
699
  match?: {
700
700
  token_filters?: {
@@ -765,7 +765,7 @@ declare class EncryptedField {
765
765
  * a different type so the encryption layer knows how to encode the plaintext
766
766
  * before encrypting.
767
767
  *
768
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
768
+ * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'text'`, `'bigint'`, or `'json'`.
769
769
  * @returns This `EncryptedField` instance for method chaining.
770
770
  *
771
771
  * @example
@@ -777,7 +777,7 @@ declare class EncryptedField {
777
777
  */
778
778
  dataType(castAs: CastAs): this;
779
779
  build(): {
780
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json";
780
+ cast_as: "number" | "bigint" | "boolean" | "date" | "json" | "text";
781
781
  indexes: {};
782
782
  };
783
783
  getName(): string;
@@ -896,7 +896,7 @@ declare class EncryptedColumn {
896
896
  */
897
897
  searchableJson(): this;
898
898
  build(): {
899
- cast_as: "string" | "number" | "bigint" | "boolean" | "date" | "json";
899
+ cast_as: "number" | "bigint" | "boolean" | "date" | "json" | "text";
900
900
  indexes: {
901
901
  ore?: OreIndexOpts;
902
902
  unique?: UniqueIndexOpts;
@@ -1049,7 +1049,28 @@ declare function encryptedColumn(columnName: string): EncryptedColumn;
1049
1049
  * ```
1050
1050
  */
1051
1051
  declare function encryptedField(valueName: string): EncryptedField;
1052
- /** @internal */
1052
+ /**
1053
+ * Build an encrypt config from a list of encrypted tables.
1054
+ *
1055
+ * @param ...tables - The list of encrypted tables to build the config from.
1056
+ * @returns An encrypt config object.
1057
+ *
1058
+ * @example
1059
+ * ```typescript
1060
+ * import { buildEncryptConfig } from "@cipherstash/stack/schema"
1061
+ *
1062
+ * const users = encryptedTable("users", {
1063
+ * email: encryptedColumn("email").equality(),
1064
+ * })
1065
+ *
1066
+ * const orders = encryptedTable("orders", {
1067
+ * amount: encryptedColumn("amount").dataType("number"),
1068
+ * })
1069
+ *
1070
+ * const config = buildEncryptConfig(users, orders)
1071
+ * console.log(config)
1072
+ * ```
1073
+ */
1053
1074
  declare function buildEncryptConfig(...protectTables: Array<EncryptedTable<EncryptedTableColumn>>): EncryptConfig;
1054
1075
 
1055
- export { type ClientConfig as A, type BulkDecryptedData as B, type CastAs as C, type Decrypted as D, type EncryptionClientConfig as E, type SearchTerm as F, type EncryptedSearchTerm as G, type EncryptedFields as H, type InferPlaintext as I, type OtherFields as J, type KeysetIdentifier as K, type DecryptedFields as L, type MatchIndexOpts as M, type DecryptionResult as N, type OreIndexOpts as O, type LoggingConfig as P, type QueryTypeName as Q, queryTypes as R, type ScalarQueryTerm as S, type TokenFilter as T, type UniqueIndexOpts as U, encryptedColumn as a, encryptedField as b, type InferEncrypted as c, EncryptedColumn as d, encryptedTable as e, EncryptedTable as f, type EncryptedTableColumn as g, EncryptedField as h, type EncryptedFromSchema as i, type Encrypted as j, type EncryptedValue as k, type EncryptedQueryResult as l, type Client as m, type BulkDecryptPayload as n, type BulkEncryptedData as o, type BulkEncryptPayload as p, type EncryptOptions as q, type EncryptQueryOptions as r, type EncryptedReturnType as s, type EncryptConfig as t, castAsEnum as u, encryptConfigSchema as v, type SteVecIndexOpts as w, type ColumnSchema as x, buildEncryptConfig as y, type EncryptPayload as z };
1076
+ export { type SearchTerm as A, type BulkDecryptedData as B, type CastAs as C, type Decrypted as D, type EncryptionClientConfig as E, type EncryptedSearchTerm as F, type EncryptedFields as G, type OtherFields as H, type InferPlaintext as I, type DecryptedFields as J, type KeysetIdentifier as K, type DecryptionResult as L, type MatchIndexOpts as M, type LoggingConfig as N, type OreIndexOpts as O, queryTypes as P, type QueryTypeName as Q, type ScalarQueryTerm as S, type TokenFilter as T, type UniqueIndexOpts as U, encryptedColumn as a, encryptedField as b, type InferEncrypted as c, EncryptedColumn as d, encryptedTable as e, EncryptedTable as f, type EncryptedTableColumn as g, EncryptedField as h, type EncryptedFromSchema as i, type Encrypted as j, type EncryptedValue as k, type EncryptedQueryResult as l, type Client as m, type BulkDecryptPayload as n, type BulkEncryptedData as o, type BulkEncryptPayload as p, type EncryptOptions as q, type EncryptQueryOptions as r, type EncryptedReturnType as s, type EncryptConfig as t, castAsEnum as u, encryptConfigSchema as v, type SteVecIndexOpts as w, type ColumnSchema as x, buildEncryptConfig as y, type ClientConfig as z };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types-public.ts","../src/types.ts"],"sourcesContent":["/**\n * Public type re-exports for `@cipherstash/stack/types`.\n *\n * This module exposes only the public types from the internal types module.\n * Internal helpers (`queryTypeToFfi`, `queryTypeToQueryOp`, `FfiIndexTypeName`,\n * `QueryTermBase`) are excluded.\n */\n\n// Core types\nexport type {\n Client,\n EncryptedValue,\n Encrypted,\n EncryptPayload,\n} from '@/types'\n\n// Client configuration\nexport type {\n KeysetIdentifier,\n ClientConfig,\n EncryptionClientConfig,\n} from '@/types'\n\n// Encrypt / decrypt operation options and results\nexport type {\n EncryptOptions,\n EncryptedReturnType,\n SearchTerm,\n EncryptedSearchTerm,\n EncryptedQueryResult,\n} from '@/types'\n\n// Model field types\nexport type {\n EncryptedFields,\n OtherFields,\n DecryptedFields,\n Decrypted,\n} from '@/types'\n\n// Bulk operations\nexport type {\n BulkEncryptPayload,\n BulkEncryptedData,\n BulkDecryptPayload,\n BulkDecryptedData,\n DecryptionResult,\n} from '@/types'\n\n// Query types (public only)\nexport type {\n QueryTypeName,\n EncryptQueryOptions,\n ScalarQueryTerm,\n} from '@/types'\n\n// Logging\nexport type { LoggingConfig } from '@/utils/logger'\n\n// Runtime values\nexport { queryTypes } from '@/types'\n","import type {\n EncryptedColumn,\n EncryptedTable,\n EncryptedTableColumn,\n EncryptedField,\n} from '@/schema'\nimport type { LoggingConfig } from '@/utils/logger'\nimport type {\n Encrypted as CipherStashEncrypted,\n JsPlaintext,\n QueryOpName,\n newClient,\n} from '@cipherstash/protect-ffi'\n\n// ---------------------------------------------------------------------------\n// Branded type utilities\n// ---------------------------------------------------------------------------\n\n/** Brand symbol for nominal typing */\ndeclare const __brand: unique symbol\n\n/** Creates a branded type that is structurally incompatible with the base type */\ntype Brand<T, B extends string> = T & { readonly [__brand]: B }\n\n// ---------------------------------------------------------------------------\n// Core types\n// ---------------------------------------------------------------------------\n\nexport type Client = Awaited<ReturnType<typeof newClient>> | undefined\n\n/** A branded type representing encrypted data. Cannot be accidentally used as plaintext. */\nexport type EncryptedValue = Brand<CipherStashEncrypted, 'encrypted'> | null\n\n/** Structural type representing encrypted data. See also `EncryptedValue` for branded nominal typing. */\nexport type Encrypted = CipherStashEncrypted | null\n\nexport type EncryptPayload = JsPlaintext | null\n\n// ---------------------------------------------------------------------------\n// Client configuration\n// ---------------------------------------------------------------------------\n\nexport type KeysetIdentifier = { name: string } | { id: string }\n\nexport type ClientConfig = {\n /**\n * The CipherStash workspace CRN (Cloud Resource Name).\n * Format: `crn:<region>.aws:<workspace-id>`.\n * Can also be set via the `CS_WORKSPACE_CRN` environment variable.\n * If omitted, the SDK reads from the environment or TOML config files.\n */\n workspaceCrn?: string\n\n /**\n * The API access key used for authenticating with the CipherStash API.\n * Can also be set via the `CS_CLIENT_ACCESS_KEY` environment variable.\n * Obtain this from the CipherStash dashboard after creating a workspace.\n */\n accessKey?: string\n\n /**\n * The client identifier used to authenticate with CipherStash services.\n * Can also be set via the `CS_CLIENT_ID` environment variable.\n * Generated during workspace onboarding in the CipherStash dashboard.\n */\n clientId?: string\n\n /**\n * The client key material used in combination with ZeroKMS for encryption operations.\n * Can also be set via the `CS_CLIENT_KEY` environment variable.\n * Generated during workspace onboarding in the CipherStash dashboard.\n */\n clientKey?: string\n\n /**\n * An optional keyset identifier for multi-tenant encryption.\n * Each keyset provides cryptographic isolation, giving each tenant its own keyspace.\n * Specify by name (`{ name: \"tenant-a\" }`) or UUID (`{ id: \"...\" }`).\n * Keysets are created and managed in the CipherStash dashboard.\n */\n keyset?: KeysetIdentifier\n}\n\ntype AtLeastOneCsTable<T> = [T, ...T[]]\n\nexport type EncryptionClientConfig = {\n schemas: AtLeastOneCsTable<EncryptedTable<EncryptedTableColumn>>\n config?: ClientConfig\n logging?: LoggingConfig\n}\n\n// ---------------------------------------------------------------------------\n// Encrypt / decrypt operation options and results\n// ---------------------------------------------------------------------------\n\n/**\n * Options for single-value encrypt operations.\n * Use a column from your table schema (from {@link encryptedColumn}) or a nested\n * field (from {@link encryptedField}) as the target for encryption.\n */\nexport type EncryptOptions = {\n /** The column or nested field to encrypt into. From {@link EncryptedColumn} or {@link EncryptedField}. */\n column: EncryptedColumn | EncryptedField\n table: EncryptedTable<EncryptedTableColumn>\n}\n\n/** Format for encrypted query/search term return values */\nexport type EncryptedReturnType =\n | 'eql'\n | 'composite-literal'\n | 'escaped-composite-literal'\n\nexport type SearchTerm = {\n value: JsPlaintext\n column: EncryptedColumn\n table: EncryptedTable<EncryptedTableColumn>\n returnType?: EncryptedReturnType\n}\n\n/** Encrypted search term result: EQL object or composite literal string */\nexport type EncryptedSearchTerm = Encrypted | string\n\n/** Result of encryptQuery (single or batch): EQL, composite literal string, or null */\nexport type EncryptedQueryResult = Encrypted | string | null\n\n// ---------------------------------------------------------------------------\n// Model field types (encrypted vs decrypted views)\n// ---------------------------------------------------------------------------\n\nexport type EncryptedFields<T> = {\n [K in keyof T as T[K] extends Encrypted ? K : never]: T[K]\n}\n\nexport type OtherFields<T> = {\n [K in keyof T as T[K] extends Encrypted ? never : K]: T[K]\n}\n\nexport type DecryptedFields<T> = {\n [K in keyof T as T[K] extends Encrypted ? K : never]: string\n}\n\n/** Model with encrypted fields replaced by plaintext (decrypted) values */\nexport type Decrypted<T> = OtherFields<T> & DecryptedFields<T>\n\n/**\n * Maps a plaintext model type to its encrypted form using the table schema.\n *\n * Fields whose keys match columns defined in `S` become `Encrypted`;\n * all other fields retain their original types from `T`.\n *\n * When `S` is the widened `EncryptedTableColumn` (e.g. when a user passes an\n * explicit `<User>` type argument without specifying `S`), the type degrades\n * gracefully to `T` — preserving backward compatibility.\n *\n * @typeParam T - The plaintext model type (e.g. `{ id: string; email: string }`)\n * @typeParam S - The table schema column definition, inferred from the `table` argument\n *\n * @example\n * ```typescript\n * type User = { id: string; email: string }\n * // With a schema that defines `email`:\n * type Encrypted = EncryptedFromSchema<User, { email: EncryptedColumn }>\n * // => { id: string; email: Encrypted }\n * ```\n */\nexport type EncryptedFromSchema<T, S extends EncryptedTableColumn> = {\n [K in keyof T]: [K] extends [keyof S]\n ? [S[K & keyof S]] extends [EncryptedColumn | EncryptedField]\n ? Encrypted\n : T[K]\n : T[K]\n}\n\n// ---------------------------------------------------------------------------\n// Bulk operations\n// ---------------------------------------------------------------------------\n\nexport type BulkEncryptPayload = Array<{\n id?: string\n plaintext: JsPlaintext | null\n}>\n\nexport type BulkEncryptedData = Array<{ id?: string; data: Encrypted }>\nexport type BulkDecryptPayload = Array<{ id?: string; data: Encrypted }>\nexport type BulkDecryptedData = Array<DecryptionResult<JsPlaintext | null>>\n\ntype DecryptionSuccess<T> = { error?: never; data: T; id?: string }\ntype DecryptionError<T> = { error: T; id?: string; data?: never }\n\n/**\n * Result type for individual items in bulk decrypt operations.\n * Uses `error`/`data` fields (not `failure`/`data`) since bulk operations\n * can have per-item failures.\n */\nexport type DecryptionResult<T> = DecryptionSuccess<T> | DecryptionError<T>\n\n// ---------------------------------------------------------------------------\n// Query types (for searchable encryption / encryptQuery)\n// ---------------------------------------------------------------------------\n\n/**\n * User-facing query type names for encrypting query values.\n *\n * - `'equality'`: Exact match. [Exact Queries](https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/exact)\n * - `'freeTextSearch'`: Text search. [Match Queries](https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/match)\n * - `'orderAndRange'`: Comparison and range. [Range Queries](https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/range)\n * - `'steVecSelector'`: JSONPath selector (e.g. `'$.user.email'`)\n * - `'steVecTerm'`: Containment (e.g. `{ role: 'admin' }`)\n * - `'searchableJson'`: Auto-infers selector or term from plaintext type (recommended)\n */\nexport type QueryTypeName =\n | 'orderAndRange'\n | 'freeTextSearch'\n | 'equality'\n | 'steVecSelector'\n | 'steVecTerm'\n | 'searchableJson'\n\n/** @internal */\nexport type FfiIndexTypeName = 'ore' | 'match' | 'unique' | 'ste_vec'\n\nexport const queryTypes = {\n orderAndRange: 'orderAndRange',\n freeTextSearch: 'freeTextSearch',\n equality: 'equality',\n steVecSelector: 'steVecSelector',\n steVecTerm: 'steVecTerm',\n searchableJson: 'searchableJson',\n} as const satisfies Record<string, QueryTypeName>\n\n/** @internal */\nexport const queryTypeToFfi: Record<QueryTypeName, FfiIndexTypeName> = {\n orderAndRange: 'ore',\n freeTextSearch: 'match',\n equality: 'unique',\n steVecSelector: 'ste_vec',\n steVecTerm: 'ste_vec',\n searchableJson: 'ste_vec',\n}\n\n/** @internal */\nexport const queryTypeToQueryOp: Partial<Record<QueryTypeName, QueryOpName>> = {\n steVecSelector: 'ste_vec_selector',\n steVecTerm: 'ste_vec_term',\n}\n\n/** @internal */\nexport type QueryTermBase = {\n column: EncryptedColumn\n table: EncryptedTable<EncryptedTableColumn>\n queryType?: QueryTypeName\n returnType?: EncryptedReturnType\n}\n\nexport type EncryptQueryOptions = QueryTermBase\n\nexport type ScalarQueryTerm = QueryTermBase & {\n value: JsPlaintext | null\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC6NO,IAAM,aAAa;AAAA,EACxB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,gBAAgB;AAClB;","names":[]}
1
+ {"version":3,"sources":["../src/types-public.ts","../src/types.ts"],"sourcesContent":["/**\n * Public type re-exports for `@cipherstash/stack/types`.\n *\n * This module exposes only the public types from the internal types module.\n * Internal helpers (`queryTypeToFfi`, `queryTypeToQueryOp`, `FfiIndexTypeName`,\n * `QueryTermBase`) are excluded.\n */\n\n// Core types\nexport type {\n Client,\n EncryptedValue,\n Encrypted,\n} from '@/types'\n\n// Client configuration\nexport type {\n KeysetIdentifier,\n ClientConfig,\n EncryptionClientConfig,\n} from '@/types'\n\n// Encrypt / decrypt operation options and results\nexport type {\n EncryptOptions,\n EncryptedReturnType,\n SearchTerm,\n EncryptedSearchTerm,\n EncryptedQueryResult,\n} from '@/types'\n\n// Model field types\nexport type {\n EncryptedFields,\n OtherFields,\n DecryptedFields,\n Decrypted,\n} from '@/types'\n\n// Bulk operations\nexport type {\n BulkEncryptPayload,\n BulkEncryptedData,\n BulkDecryptPayload,\n BulkDecryptedData,\n DecryptionResult,\n} from '@/types'\n\n// Query types (public only)\nexport type {\n QueryTypeName,\n EncryptQueryOptions,\n ScalarQueryTerm,\n} from '@/types'\n\n// Logging\nexport type { LoggingConfig } from '@/utils/logger'\n\n// Runtime values\nexport { queryTypes } from '@/types'\n","import type {\n EncryptedColumn,\n EncryptedTable,\n EncryptedTableColumn,\n EncryptedField,\n} from '@/schema'\nimport type { LoggingConfig } from '@/utils/logger'\nimport type {\n Encrypted as CipherStashEncrypted,\n JsPlaintext,\n QueryOpName,\n newClient,\n} from '@cipherstash/protect-ffi'\n\n// ---------------------------------------------------------------------------\n// Branded type utilities\n// ---------------------------------------------------------------------------\n\n/** Brand symbol for nominal typing */\ndeclare const __brand: unique symbol\n\n/** Creates a branded type that is structurally incompatible with the base type */\ntype Brand<T, B extends string> = T & { readonly [__brand]: B }\n\n// ---------------------------------------------------------------------------\n// Core types\n// ---------------------------------------------------------------------------\n\nexport type Client = Awaited<ReturnType<typeof newClient>> | undefined\n\n/** A branded type representing encrypted data. Cannot be accidentally used as plaintext. */\nexport type EncryptedValue = Brand<CipherStashEncrypted, 'encrypted'>\n\n/** Structural type representing encrypted data. See also `EncryptedValue` for branded nominal typing. */\nexport type Encrypted = CipherStashEncrypted\n\n// ---------------------------------------------------------------------------\n// Client configuration\n// ---------------------------------------------------------------------------\n\nexport type KeysetIdentifier = { name: string } | { id: string }\n\nexport type ClientConfig = {\n /**\n * The CipherStash workspace CRN (Cloud Resource Name).\n * Format: `crn:<region>.aws:<workspace-id>`.\n * Can also be set via the `CS_WORKSPACE_CRN` environment variable.\n * If omitted, the SDK reads from the environment or TOML config files.\n */\n workspaceCrn?: string\n\n /**\n * The API access key used for authenticating with the CipherStash API.\n * Can also be set via the `CS_CLIENT_ACCESS_KEY` environment variable.\n * Obtain this from the CipherStash dashboard after creating a workspace.\n */\n accessKey?: string\n\n /**\n * The client identifier used to authenticate with CipherStash services.\n * Can also be set via the `CS_CLIENT_ID` environment variable.\n * Generated during workspace onboarding in the CipherStash dashboard.\n */\n clientId?: string\n\n /**\n * The client key material used in combination with ZeroKMS for encryption operations.\n * Can also be set via the `CS_CLIENT_KEY` environment variable.\n * Generated during workspace onboarding in the CipherStash dashboard.\n */\n clientKey?: string\n\n /**\n * An optional keyset identifier for multi-tenant encryption.\n * Each keyset provides cryptographic isolation, giving each tenant its own keyspace.\n * Specify by name (`{ name: \"tenant-a\" }`) or UUID (`{ id: \"...\" }`).\n * Keysets are created and managed in the CipherStash dashboard.\n */\n keyset?: KeysetIdentifier\n}\n\ntype AtLeastOneCsTable<T> = [T, ...T[]]\n\nexport type EncryptionClientConfig = {\n schemas: AtLeastOneCsTable<EncryptedTable<EncryptedTableColumn>>\n config?: ClientConfig\n logging?: LoggingConfig\n}\n\n// ---------------------------------------------------------------------------\n// Encrypt / decrypt operation options and results\n// ---------------------------------------------------------------------------\n\n/**\n * Options for single-value encrypt operations.\n * Use a column from your table schema (from {@link encryptedColumn}) or a nested\n * field (from {@link encryptedField}) as the target for encryption.\n */\nexport type EncryptOptions = {\n /** The column or nested field to encrypt into. From {@link EncryptedColumn} or {@link EncryptedField}. */\n column: EncryptedColumn | EncryptedField\n table: EncryptedTable<EncryptedTableColumn>\n}\n\n/** Format for encrypted query/search term return values */\nexport type EncryptedReturnType =\n | 'eql'\n | 'composite-literal'\n | 'escaped-composite-literal'\n\nexport type SearchTerm = {\n value: JsPlaintext\n column: EncryptedColumn\n table: EncryptedTable<EncryptedTableColumn>\n returnType?: EncryptedReturnType\n}\n\n/** Encrypted search term result: EQL object or composite literal string */\nexport type EncryptedSearchTerm = Encrypted | string\n\n/** Result of encryptQuery (single or batch): EQL or composite literal string */\nexport type EncryptedQueryResult = Encrypted | string\n\n// ---------------------------------------------------------------------------\n// Model field types (encrypted vs decrypted views)\n// ---------------------------------------------------------------------------\n\nexport type EncryptedFields<T> = {\n [K in keyof T as NonNullable<T[K]> extends Encrypted ? K : never]: T[K]\n}\n\nexport type OtherFields<T> = {\n [K in keyof T as NonNullable<T[K]> extends Encrypted ? never : K]: T[K]\n}\n\nexport type DecryptedFields<T> = {\n [K in keyof T as NonNullable<T[K]> extends Encrypted ? K : never]:\n null extends T[K] ? string | null : string\n}\n\n/** Model with encrypted fields replaced by plaintext (decrypted) values */\nexport type Decrypted<T> = OtherFields<T> & DecryptedFields<T>\n\n/**\n * Maps a plaintext model type to its encrypted form using the table schema.\n *\n * Fields whose keys match columns defined in `S` become `Encrypted`;\n * all other fields retain their original types from `T`.\n *\n * When `S` is the widened `EncryptedTableColumn` (e.g. when a user passes an\n * explicit `<User>` type argument without specifying `S`), the type degrades\n * gracefully to `T` — preserving backward compatibility.\n *\n * @typeParam T - The plaintext model type (e.g. `{ id: string; email: string }`)\n * @typeParam S - The table schema column definition, inferred from the `table` argument\n *\n * @example\n * ```typescript\n * type User = { id: string; email: string }\n * // With a schema that defines `email`:\n * type Encrypted = EncryptedFromSchema<User, { email: EncryptedColumn }>\n * // => { id: string; email: Encrypted }\n * ```\n */\nexport type EncryptedFromSchema<T, S extends EncryptedTableColumn> = {\n [K in keyof T]: [K] extends [keyof S]\n ? [S[K & keyof S]] extends [EncryptedColumn | EncryptedField]\n ? null extends T[K] ? Encrypted | null : Encrypted\n : T[K]\n : T[K]\n}\n\n// ---------------------------------------------------------------------------\n// Bulk operations\n// ---------------------------------------------------------------------------\n\nexport type BulkEncryptPayload = Array<{\n id?: string\n plaintext: JsPlaintext\n}>\n\nexport type BulkEncryptedData = Array<{ id?: string; data: Encrypted }>\nexport type BulkDecryptPayload = Array<{ id?: string; data: Encrypted }>\nexport type BulkDecryptedData = Array<DecryptionResult<JsPlaintext>>\n\ntype DecryptionSuccess<T> = { error?: never; data: T; id?: string }\ntype DecryptionError<T> = { error: T; id?: string; data?: never }\n\n/**\n * Result type for individual items in bulk decrypt operations.\n * Uses `error`/`data` fields (not `failure`/`data`) since bulk operations\n * can have per-item failures.\n */\nexport type DecryptionResult<T> = DecryptionSuccess<T> | DecryptionError<T>\n\n// ---------------------------------------------------------------------------\n// Query types (for searchable encryption / encryptQuery)\n// ---------------------------------------------------------------------------\n\n/**\n * User-facing query type names for encrypting query values.\n *\n * - `'equality'`: Exact match. [Exact Queries](https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/exact)\n * - `'freeTextSearch'`: Text search. [Match Queries](https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/match)\n * - `'orderAndRange'`: Comparison and range. [Range Queries](https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/range)\n * - `'steVecSelector'`: JSONPath selector (e.g. `'$.user.email'`)\n * - `'steVecTerm'`: Containment (e.g. `{ role: 'admin' }`)\n * - `'searchableJson'`: Auto-infers selector or term from plaintext type (recommended)\n */\nexport type QueryTypeName =\n | 'orderAndRange'\n | 'freeTextSearch'\n | 'equality'\n | 'steVecSelector'\n | 'steVecTerm'\n | 'searchableJson'\n\n/** @internal */\nexport type FfiIndexTypeName = 'ore' | 'match' | 'unique' | 'ste_vec'\n\nexport const queryTypes = {\n orderAndRange: 'orderAndRange',\n freeTextSearch: 'freeTextSearch',\n equality: 'equality',\n steVecSelector: 'steVecSelector',\n steVecTerm: 'steVecTerm',\n searchableJson: 'searchableJson',\n} as const satisfies Record<string, QueryTypeName>\n\n/** @internal */\nexport const queryTypeToFfi: Record<QueryTypeName, FfiIndexTypeName> = {\n orderAndRange: 'ore',\n freeTextSearch: 'match',\n equality: 'unique',\n steVecSelector: 'ste_vec',\n steVecTerm: 'ste_vec',\n searchableJson: 'ste_vec',\n}\n\n/** @internal */\nexport const queryTypeToQueryOp: Partial<Record<QueryTypeName, QueryOpName>> = {\n steVecSelector: 'ste_vec_selector',\n steVecTerm: 'ste_vec_term',\n}\n\n/** @internal */\nexport type QueryTermBase = {\n column: EncryptedColumn\n table: EncryptedTable<EncryptedTableColumn>\n queryType?: QueryTypeName\n returnType?: EncryptedReturnType\n}\n\nexport type EncryptQueryOptions = QueryTermBase\n\nexport type ScalarQueryTerm = QueryTermBase & {\n value: JsPlaintext\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC4NO,IAAM,aAAa;AAAA,EACxB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,gBAAgB;AAClB;","names":[]}
@@ -1,4 +1,4 @@
1
- export { n as BulkDecryptPayload, B as BulkDecryptedData, p as BulkEncryptPayload, o as BulkEncryptedData, m as Client, A as ClientConfig, D as Decrypted, L as DecryptedFields, N as DecryptionResult, q as EncryptOptions, z as EncryptPayload, r as EncryptQueryOptions, j as Encrypted, H as EncryptedFields, l as EncryptedQueryResult, s as EncryptedReturnType, G as EncryptedSearchTerm, k as EncryptedValue, E as EncryptionClientConfig, K as KeysetIdentifier, P as LoggingConfig, J as OtherFields, Q as QueryTypeName, S as ScalarQueryTerm, F as SearchTerm, R as queryTypes } from './types-public-0CzBV45X.cjs';
1
+ export { n as BulkDecryptPayload, B as BulkDecryptedData, p as BulkEncryptPayload, o as BulkEncryptedData, m as Client, z as ClientConfig, D as Decrypted, J as DecryptedFields, L as DecryptionResult, q as EncryptOptions, r as EncryptQueryOptions, j as Encrypted, G as EncryptedFields, l as EncryptedQueryResult, s as EncryptedReturnType, F as EncryptedSearchTerm, k as EncryptedValue, E as EncryptionClientConfig, K as KeysetIdentifier, N as LoggingConfig, H as OtherFields, Q as QueryTypeName, S as ScalarQueryTerm, A as SearchTerm, P as queryTypes } from './types-public-Wj6tB_ux.cjs';
2
2
  import 'zod';
3
3
  import 'evlog';
4
4
  import '@cipherstash/protect-ffi';
@@ -1,4 +1,4 @@
1
- export { n as BulkDecryptPayload, B as BulkDecryptedData, p as BulkEncryptPayload, o as BulkEncryptedData, m as Client, A as ClientConfig, D as Decrypted, L as DecryptedFields, N as DecryptionResult, q as EncryptOptions, z as EncryptPayload, r as EncryptQueryOptions, j as Encrypted, H as EncryptedFields, l as EncryptedQueryResult, s as EncryptedReturnType, G as EncryptedSearchTerm, k as EncryptedValue, E as EncryptionClientConfig, K as KeysetIdentifier, P as LoggingConfig, J as OtherFields, Q as QueryTypeName, S as ScalarQueryTerm, F as SearchTerm, R as queryTypes } from './types-public-0CzBV45X.js';
1
+ export { n as BulkDecryptPayload, B as BulkDecryptedData, p as BulkEncryptPayload, o as BulkEncryptedData, m as Client, z as ClientConfig, D as Decrypted, J as DecryptedFields, L as DecryptionResult, q as EncryptOptions, r as EncryptQueryOptions, j as Encrypted, G as EncryptedFields, l as EncryptedQueryResult, s as EncryptedReturnType, F as EncryptedSearchTerm, k as EncryptedValue, E as EncryptionClientConfig, K as KeysetIdentifier, N as LoggingConfig, H as OtherFields, Q as QueryTypeName, S as ScalarQueryTerm, A as SearchTerm, P as queryTypes } from './types-public-Wj6tB_ux.js';
2
2
  import 'zod';
3
3
  import 'evlog';
4
4
  import '@cipherstash/protect-ffi';
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  queryTypes
3
- } from "./chunk-JLI27P46.js";
3
+ } from "./chunk-KOU2MHXJ.js";
4
4
  export {
5
5
  queryTypes
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cipherstash/stack",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "CipherStash Stack for TypeScript and JavaScript",
5
5
  "keywords": [
6
6
  "encrypted",
@@ -173,7 +173,7 @@
173
173
  },
174
174
  "dependencies": {
175
175
  "@byteslice/result": "^0.2.0",
176
- "@cipherstash/protect-ffi": "0.20.1",
176
+ "@cipherstash/protect-ffi": "0.20.2",
177
177
  "evlog": "^1.9.0",
178
178
  "zod": "3.24.2"
179
179
  },
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n EncryptedColumn,\n EncryptedTable,\n EncryptedTableColumn,\n EncryptedField,\n} from '@/schema'\nimport type { LoggingConfig } from '@/utils/logger'\nimport type {\n Encrypted as CipherStashEncrypted,\n JsPlaintext,\n QueryOpName,\n newClient,\n} from '@cipherstash/protect-ffi'\n\n// ---------------------------------------------------------------------------\n// Branded type utilities\n// ---------------------------------------------------------------------------\n\n/** Brand symbol for nominal typing */\ndeclare const __brand: unique symbol\n\n/** Creates a branded type that is structurally incompatible with the base type */\ntype Brand<T, B extends string> = T & { readonly [__brand]: B }\n\n// ---------------------------------------------------------------------------\n// Core types\n// ---------------------------------------------------------------------------\n\nexport type Client = Awaited<ReturnType<typeof newClient>> | undefined\n\n/** A branded type representing encrypted data. Cannot be accidentally used as plaintext. */\nexport type EncryptedValue = Brand<CipherStashEncrypted, 'encrypted'> | null\n\n/** Structural type representing encrypted data. See also `EncryptedValue` for branded nominal typing. */\nexport type Encrypted = CipherStashEncrypted | null\n\nexport type EncryptPayload = JsPlaintext | null\n\n// ---------------------------------------------------------------------------\n// Client configuration\n// ---------------------------------------------------------------------------\n\nexport type KeysetIdentifier = { name: string } | { id: string }\n\nexport type ClientConfig = {\n /**\n * The CipherStash workspace CRN (Cloud Resource Name).\n * Format: `crn:<region>.aws:<workspace-id>`.\n * Can also be set via the `CS_WORKSPACE_CRN` environment variable.\n * If omitted, the SDK reads from the environment or TOML config files.\n */\n workspaceCrn?: string\n\n /**\n * The API access key used for authenticating with the CipherStash API.\n * Can also be set via the `CS_CLIENT_ACCESS_KEY` environment variable.\n * Obtain this from the CipherStash dashboard after creating a workspace.\n */\n accessKey?: string\n\n /**\n * The client identifier used to authenticate with CipherStash services.\n * Can also be set via the `CS_CLIENT_ID` environment variable.\n * Generated during workspace onboarding in the CipherStash dashboard.\n */\n clientId?: string\n\n /**\n * The client key material used in combination with ZeroKMS for encryption operations.\n * Can also be set via the `CS_CLIENT_KEY` environment variable.\n * Generated during workspace onboarding in the CipherStash dashboard.\n */\n clientKey?: string\n\n /**\n * An optional keyset identifier for multi-tenant encryption.\n * Each keyset provides cryptographic isolation, giving each tenant its own keyspace.\n * Specify by name (`{ name: \"tenant-a\" }`) or UUID (`{ id: \"...\" }`).\n * Keysets are created and managed in the CipherStash dashboard.\n */\n keyset?: KeysetIdentifier\n}\n\ntype AtLeastOneCsTable<T> = [T, ...T[]]\n\nexport type EncryptionClientConfig = {\n schemas: AtLeastOneCsTable<EncryptedTable<EncryptedTableColumn>>\n config?: ClientConfig\n logging?: LoggingConfig\n}\n\n// ---------------------------------------------------------------------------\n// Encrypt / decrypt operation options and results\n// ---------------------------------------------------------------------------\n\n/**\n * Options for single-value encrypt operations.\n * Use a column from your table schema (from {@link encryptedColumn}) or a nested\n * field (from {@link encryptedField}) as the target for encryption.\n */\nexport type EncryptOptions = {\n /** The column or nested field to encrypt into. From {@link EncryptedColumn} or {@link EncryptedField}. */\n column: EncryptedColumn | EncryptedField\n table: EncryptedTable<EncryptedTableColumn>\n}\n\n/** Format for encrypted query/search term return values */\nexport type EncryptedReturnType =\n | 'eql'\n | 'composite-literal'\n | 'escaped-composite-literal'\n\nexport type SearchTerm = {\n value: JsPlaintext\n column: EncryptedColumn\n table: EncryptedTable<EncryptedTableColumn>\n returnType?: EncryptedReturnType\n}\n\n/** Encrypted search term result: EQL object or composite literal string */\nexport type EncryptedSearchTerm = Encrypted | string\n\n/** Result of encryptQuery (single or batch): EQL, composite literal string, or null */\nexport type EncryptedQueryResult = Encrypted | string | null\n\n// ---------------------------------------------------------------------------\n// Model field types (encrypted vs decrypted views)\n// ---------------------------------------------------------------------------\n\nexport type EncryptedFields<T> = {\n [K in keyof T as T[K] extends Encrypted ? K : never]: T[K]\n}\n\nexport type OtherFields<T> = {\n [K in keyof T as T[K] extends Encrypted ? never : K]: T[K]\n}\n\nexport type DecryptedFields<T> = {\n [K in keyof T as T[K] extends Encrypted ? K : never]: string\n}\n\n/** Model with encrypted fields replaced by plaintext (decrypted) values */\nexport type Decrypted<T> = OtherFields<T> & DecryptedFields<T>\n\n/**\n * Maps a plaintext model type to its encrypted form using the table schema.\n *\n * Fields whose keys match columns defined in `S` become `Encrypted`;\n * all other fields retain their original types from `T`.\n *\n * When `S` is the widened `EncryptedTableColumn` (e.g. when a user passes an\n * explicit `<User>` type argument without specifying `S`), the type degrades\n * gracefully to `T` — preserving backward compatibility.\n *\n * @typeParam T - The plaintext model type (e.g. `{ id: string; email: string }`)\n * @typeParam S - The table schema column definition, inferred from the `table` argument\n *\n * @example\n * ```typescript\n * type User = { id: string; email: string }\n * // With a schema that defines `email`:\n * type Encrypted = EncryptedFromSchema<User, { email: EncryptedColumn }>\n * // => { id: string; email: Encrypted }\n * ```\n */\nexport type EncryptedFromSchema<T, S extends EncryptedTableColumn> = {\n [K in keyof T]: [K] extends [keyof S]\n ? [S[K & keyof S]] extends [EncryptedColumn | EncryptedField]\n ? Encrypted\n : T[K]\n : T[K]\n}\n\n// ---------------------------------------------------------------------------\n// Bulk operations\n// ---------------------------------------------------------------------------\n\nexport type BulkEncryptPayload = Array<{\n id?: string\n plaintext: JsPlaintext | null\n}>\n\nexport type BulkEncryptedData = Array<{ id?: string; data: Encrypted }>\nexport type BulkDecryptPayload = Array<{ id?: string; data: Encrypted }>\nexport type BulkDecryptedData = Array<DecryptionResult<JsPlaintext | null>>\n\ntype DecryptionSuccess<T> = { error?: never; data: T; id?: string }\ntype DecryptionError<T> = { error: T; id?: string; data?: never }\n\n/**\n * Result type for individual items in bulk decrypt operations.\n * Uses `error`/`data` fields (not `failure`/`data`) since bulk operations\n * can have per-item failures.\n */\nexport type DecryptionResult<T> = DecryptionSuccess<T> | DecryptionError<T>\n\n// ---------------------------------------------------------------------------\n// Query types (for searchable encryption / encryptQuery)\n// ---------------------------------------------------------------------------\n\n/**\n * User-facing query type names for encrypting query values.\n *\n * - `'equality'`: Exact match. [Exact Queries](https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/exact)\n * - `'freeTextSearch'`: Text search. [Match Queries](https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/match)\n * - `'orderAndRange'`: Comparison and range. [Range Queries](https://cipherstash.com/docs/platform/searchable-encryption/supported-queries/range)\n * - `'steVecSelector'`: JSONPath selector (e.g. `'$.user.email'`)\n * - `'steVecTerm'`: Containment (e.g. `{ role: 'admin' }`)\n * - `'searchableJson'`: Auto-infers selector or term from plaintext type (recommended)\n */\nexport type QueryTypeName =\n | 'orderAndRange'\n | 'freeTextSearch'\n | 'equality'\n | 'steVecSelector'\n | 'steVecTerm'\n | 'searchableJson'\n\n/** @internal */\nexport type FfiIndexTypeName = 'ore' | 'match' | 'unique' | 'ste_vec'\n\nexport const queryTypes = {\n orderAndRange: 'orderAndRange',\n freeTextSearch: 'freeTextSearch',\n equality: 'equality',\n steVecSelector: 'steVecSelector',\n steVecTerm: 'steVecTerm',\n searchableJson: 'searchableJson',\n} as const satisfies Record<string, QueryTypeName>\n\n/** @internal */\nexport const queryTypeToFfi: Record<QueryTypeName, FfiIndexTypeName> = {\n orderAndRange: 'ore',\n freeTextSearch: 'match',\n equality: 'unique',\n steVecSelector: 'ste_vec',\n steVecTerm: 'ste_vec',\n searchableJson: 'ste_vec',\n}\n\n/** @internal */\nexport const queryTypeToQueryOp: Partial<Record<QueryTypeName, QueryOpName>> = {\n steVecSelector: 'ste_vec_selector',\n steVecTerm: 'ste_vec_term',\n}\n\n/** @internal */\nexport type QueryTermBase = {\n column: EncryptedColumn\n table: EncryptedTable<EncryptedTableColumn>\n queryType?: QueryTypeName\n returnType?: EncryptedReturnType\n}\n\nexport type EncryptQueryOptions = QueryTermBase\n\nexport type ScalarQueryTerm = QueryTermBase & {\n value: JsPlaintext | null\n}\n"],"mappings":";AA6NO,IAAM,aAAa;AAAA,EACxB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,gBAAgB;AAClB;AAGO,IAAM,iBAA0D;AAAA,EACrE,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,gBAAgB;AAClB;AAGO,IAAM,qBAAkE;AAAA,EAC7E,gBAAgB;AAAA,EAChB,YAAY;AACd;","names":[]}