@cipherstash/stack 0.2.0 → 0.3.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 (64) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -2
  3. package/dist/bin/stash.js +63 -45
  4. package/dist/bin/stash.js.map +1 -1
  5. package/dist/{chunk-5G4F4JJG.js → chunk-JLI27P46.js} +1 -1
  6. package/dist/chunk-JLI27P46.js.map +1 -0
  7. package/dist/{chunk-LHZ6KZIG.js → chunk-MW6D52V2.js} +42 -31
  8. package/dist/chunk-MW6D52V2.js.map +1 -0
  9. package/dist/{chunk-5DCT6YU2.js → chunk-OAPLZLR5.js} +7 -3
  10. package/dist/{chunk-5DCT6YU2.js.map → chunk-OAPLZLR5.js.map} +1 -1
  11. package/dist/{chunk-7XRPN2KX.js → chunk-TBAIVO6T.js} +26 -23
  12. package/dist/chunk-TBAIVO6T.js.map +1 -0
  13. package/dist/{client-D-ZH8SB2.d.cts → client-Bf0Xw2xo.d.cts} +19 -16
  14. package/dist/{client-BV9pXC-d.d.ts → client-Kfp8OsPB.d.ts} +19 -16
  15. package/dist/client.cjs +25 -22
  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 +5 -5
  20. package/dist/drizzle/index.cjs +19 -16
  21. package/dist/drizzle/index.cjs.map +1 -1
  22. package/dist/drizzle/index.d.cts +5 -5
  23. package/dist/drizzle/index.d.ts +5 -5
  24. package/dist/drizzle/index.js +2 -2
  25. package/dist/drizzle/index.js.map +1 -1
  26. package/dist/dynamodb/index.cjs.map +1 -1
  27. package/dist/dynamodb/index.d.cts +10 -10
  28. package/dist/dynamodb/index.d.ts +10 -10
  29. package/dist/dynamodb/index.js.map +1 -1
  30. package/dist/identity/index.cjs +6 -2
  31. package/dist/identity/index.cjs.map +1 -1
  32. package/dist/identity/index.js +1 -1
  33. package/dist/index.cjs +67 -49
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +3 -3
  36. package/dist/index.d.ts +3 -3
  37. package/dist/index.js +7 -7
  38. package/dist/schema/index.cjs +31 -28
  39. package/dist/schema/index.cjs.map +1 -1
  40. package/dist/schema/index.d.cts +1 -1
  41. package/dist/schema/index.d.ts +1 -1
  42. package/dist/schema/index.js +11 -11
  43. package/dist/secrets/index.cjs +63 -45
  44. package/dist/secrets/index.cjs.map +1 -1
  45. package/dist/secrets/index.d.cts +1 -1
  46. package/dist/secrets/index.d.ts +1 -1
  47. package/dist/secrets/index.js +4 -4
  48. package/dist/secrets/index.js.map +1 -1
  49. package/dist/supabase/index.cjs +7 -7
  50. package/dist/supabase/index.cjs.map +1 -1
  51. package/dist/supabase/index.d.cts +3 -3
  52. package/dist/supabase/index.d.ts +3 -3
  53. package/dist/supabase/index.js +3 -3
  54. package/dist/supabase/index.js.map +1 -1
  55. package/dist/{types-public-Dfg-hkuQ.d.cts → types-public-0CzBV45X.d.cts} +70 -52
  56. package/dist/{types-public-Dfg-hkuQ.d.ts → types-public-0CzBV45X.d.ts} +70 -52
  57. package/dist/types-public.cjs.map +1 -1
  58. package/dist/types-public.d.cts +1 -1
  59. package/dist/types-public.d.ts +1 -1
  60. package/dist/types-public.js +1 -1
  61. package/package.json +1 -1
  62. package/dist/chunk-5G4F4JJG.js.map +0 -1
  63. package/dist/chunk-7XRPN2KX.js.map +0 -1
  64. package/dist/chunk-LHZ6KZIG.js.map +0 -1
@@ -61,20 +61,26 @@ type ClientConfig = {
61
61
  };
62
62
  type AtLeastOneCsTable<T> = [T, ...T[]];
63
63
  type EncryptionClientConfig = {
64
- schemas: AtLeastOneCsTable<ProtectTable<ProtectTableColumn>>;
64
+ schemas: AtLeastOneCsTable<EncryptedTable<EncryptedTableColumn>>;
65
65
  config?: ClientConfig;
66
66
  logging?: LoggingConfig;
67
67
  };
68
+ /**
69
+ * Options for single-value encrypt operations.
70
+ * Use a column from your table schema (from {@link encryptedColumn}) or a nested
71
+ * field (from {@link encryptedField}) as the target for encryption.
72
+ */
68
73
  type EncryptOptions = {
69
- column: ProtectColumn | ProtectValue;
70
- table: ProtectTable<ProtectTableColumn>;
74
+ /** The column or nested field to encrypt into. From {@link EncryptedColumn} or {@link EncryptedField}. */
75
+ column: EncryptedColumn | EncryptedField;
76
+ table: EncryptedTable<EncryptedTableColumn>;
71
77
  };
72
78
  /** Format for encrypted query/search term return values */
73
79
  type EncryptedReturnType = 'eql' | 'composite-literal' | 'escaped-composite-literal';
74
80
  type SearchTerm = {
75
81
  value: JsPlaintext;
76
- column: ProtectColumn;
77
- table: ProtectTable<ProtectTableColumn>;
82
+ column: EncryptedColumn;
83
+ table: EncryptedTable<EncryptedTableColumn>;
78
84
  returnType?: EncryptedReturnType;
79
85
  };
80
86
  /** Encrypted search term result: EQL object or composite literal string */
@@ -98,7 +104,7 @@ type Decrypted<T> = OtherFields<T> & DecryptedFields<T>;
98
104
  * Fields whose keys match columns defined in `S` become `Encrypted`;
99
105
  * all other fields retain their original types from `T`.
100
106
  *
101
- * When `S` is the widened `ProtectTableColumn` (e.g. when a user passes an
107
+ * When `S` is the widened `EncryptedTableColumn` (e.g. when a user passes an
102
108
  * explicit `<User>` type argument without specifying `S`), the type degrades
103
109
  * gracefully to `T` — preserving backward compatibility.
104
110
  *
@@ -109,12 +115,12 @@ type Decrypted<T> = OtherFields<T> & DecryptedFields<T>;
109
115
  * ```typescript
110
116
  * type User = { id: string; email: string }
111
117
  * // With a schema that defines `email`:
112
- * type Encrypted = EncryptedFromSchema<User, { email: ProtectColumn }>
118
+ * type Encrypted = EncryptedFromSchema<User, { email: EncryptedColumn }>
113
119
  * // => { id: string; email: Encrypted }
114
120
  * ```
115
121
  */
116
- type EncryptedFromSchema<T, S extends ProtectTableColumn> = {
117
- [K in keyof T]: [K] extends [keyof S] ? [S[K & keyof S]] extends [ProtectColumn | ProtectValue] ? Encrypted : T[K] : T[K];
122
+ 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];
118
124
  };
119
125
  type BulkEncryptPayload = Array<{
120
126
  id?: string;
@@ -166,8 +172,8 @@ declare const queryTypes: {
166
172
  };
167
173
  /** @internal */
168
174
  type QueryTermBase = {
169
- column: ProtectColumn;
170
- table: ProtectTable<ProtectTableColumn>;
175
+ column: EncryptedColumn;
176
+ table: EncryptedTable<EncryptedTableColumn>;
171
177
  queryType?: QueryTypeName;
172
178
  returnType?: EncryptedReturnType;
173
179
  };
@@ -729,35 +735,44 @@ type SteVecIndexOpts = z.infer<typeof steVecIndexOptsSchema>;
729
735
  type UniqueIndexOpts = z.infer<typeof uniqueIndexOptsSchema>;
730
736
  type OreIndexOpts = z.infer<typeof oreIndexOptsSchema>;
731
737
  type ColumnSchema = z.infer<typeof columnSchema>;
732
- type ProtectTableColumn = {
733
- [key: string]: ProtectColumn | {
734
- [key: string]: ProtectValue | {
735
- [key: string]: ProtectValue | {
736
- [key: string]: ProtectValue;
738
+ /**
739
+ * Shape of table columns: either top-level {@link EncryptedColumn} or nested
740
+ * objects whose leaves are {@link EncryptedField}. Used with {@link encryptedTable}.
741
+ */
742
+ type EncryptedTableColumn = {
743
+ [key: string]: EncryptedColumn | {
744
+ [key: string]: EncryptedField | {
745
+ [key: string]: EncryptedField | {
746
+ [key: string]: EncryptedField;
737
747
  };
738
748
  };
739
749
  };
740
750
  };
741
751
  type EncryptConfig = z.infer<typeof encryptConfigSchema>;
742
- declare class ProtectValue {
752
+ /**
753
+ * Builder for a nested encrypted field (encrypted but not searchable).
754
+ * Create with {@link encryptedField}. Use inside nested objects in {@link encryptedTable};
755
+ * supports `.dataType()` for plaintext type. No index methods (equality, orderAndRange, etc.).
756
+ */
757
+ declare class EncryptedField {
743
758
  private valueName;
744
759
  private castAsValue;
745
760
  constructor(valueName: string);
746
761
  /**
747
- * Set or override the plaintext data type for this value.
762
+ * Set or override the plaintext data type for this field.
748
763
  *
749
764
  * By default all values are treated as `'string'`. Use this method to specify
750
765
  * a different type so the encryption layer knows how to encode the plaintext
751
766
  * before encrypting.
752
767
  *
753
768
  * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
754
- * @returns This `ProtectValue` instance for method chaining.
769
+ * @returns This `EncryptedField` instance for method chaining.
755
770
  *
756
771
  * @example
757
772
  * ```typescript
758
- * import { encryptedValue } from "@cipherstash/stack/schema"
773
+ * import { encryptedField } from "@cipherstash/stack/schema"
759
774
  *
760
- * const age = encryptedValue("age").dataType("number")
775
+ * const age = encryptedField("age").dataType("number")
761
776
  * ```
762
777
  */
763
778
  dataType(castAs: CastAs): this;
@@ -767,7 +782,7 @@ declare class ProtectValue {
767
782
  };
768
783
  getName(): string;
769
784
  }
770
- declare class ProtectColumn {
785
+ declare class EncryptedColumn {
771
786
  private columnName;
772
787
  private castAsValue;
773
788
  private indexesValue;
@@ -780,7 +795,7 @@ declare class ProtectColumn {
780
795
  * before encrypting.
781
796
  *
782
797
  * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
783
- * @returns This `ProtectColumn` instance for method chaining.
798
+ * @returns This `EncryptedColumn` instance for method chaining.
784
799
  *
785
800
  * @example
786
801
  * ```typescript
@@ -796,7 +811,7 @@ declare class ProtectColumn {
796
811
  * ORE allows sorting, comparison, and range queries on encrypted data.
797
812
  * Use with `encryptQuery` and `queryType: 'orderAndRange'`.
798
813
  *
799
- * @returns This `ProtectColumn` instance for method chaining.
814
+ * @returns This `EncryptedColumn` instance for method chaining.
800
815
  *
801
816
  * @example
802
817
  * ```typescript
@@ -816,7 +831,7 @@ declare class ProtectColumn {
816
831
  *
817
832
  * @param tokenFilters - Optional array of token filters (e.g. `[{ kind: 'downcase' }]`).
818
833
  * When omitted, no token filters are applied.
819
- * @returns This `ProtectColumn` instance for method chaining.
834
+ * @returns This `EncryptedColumn` instance for method chaining.
820
835
  *
821
836
  * @example
822
837
  * ```typescript
@@ -836,7 +851,7 @@ declare class ProtectColumn {
836
851
  *
837
852
  * @param opts - Optional match index configuration. Defaults to 3-character ngram
838
853
  * tokenization with a downcase filter, `k=6`, `m=2048`, and `include_original=true`.
839
- * @returns This `ProtectColumn` instance for method chaining.
854
+ * @returns This `EncryptedColumn` instance for method chaining.
840
855
  *
841
856
  * @example
842
857
  * ```typescript
@@ -868,7 +883,7 @@ declare class ProtectColumn {
868
883
  * the plaintext type: strings become selector queries, objects/arrays become
869
884
  * containment queries.
870
885
  *
871
- * @returns This `ProtectColumn` instance for method chaining.
886
+ * @returns This `EncryptedColumn` instance for method chaining.
872
887
  *
873
888
  * @example
874
889
  * ```typescript
@@ -895,9 +910,11 @@ interface TableDefinition {
895
910
  tableName: string;
896
911
  columns: Record<string, ColumnSchema>;
897
912
  }
898
- declare class ProtectTable<T extends ProtectTableColumn> {
913
+ declare class EncryptedTable<T extends EncryptedTableColumn> {
899
914
  readonly tableName: string;
900
915
  private readonly columnBuilders;
916
+ /** @internal Type-level brand so TypeScript can infer `T` from `EncryptedTable<T>`. */
917
+ readonly _columnType: T;
901
918
  constructor(tableName: string, columnBuilders: T);
902
919
  /**
903
920
  * Compile this table schema into a `TableDefinition` used internally by the encryption client.
@@ -921,7 +938,7 @@ declare class ProtectTable<T extends ProtectTableColumn> {
921
938
  build(): TableDefinition;
922
939
  }
923
940
  /**
924
- * Infer the plaintext (decrypted) type from a ProtectTable schema.
941
+ * Infer the plaintext (decrypted) type from a EncryptedTable schema.
925
942
  *
926
943
  * @example
927
944
  * ```typescript
@@ -934,11 +951,11 @@ declare class ProtectTable<T extends ProtectTableColumn> {
934
951
  * // => { email: string; name: string }
935
952
  * ```
936
953
  */
937
- type InferPlaintext<T extends ProtectTable<any>> = T extends ProtectTable<infer C> ? {
938
- [K in keyof C as C[K] extends ProtectColumn | ProtectValue ? K : never]: string;
954
+ type InferPlaintext<T extends EncryptedTable<any>> = T extends EncryptedTable<infer C> ? {
955
+ [K in keyof C as C[K] extends EncryptedColumn | EncryptedField ? K : never]: string;
939
956
  } : never;
940
957
  /**
941
- * Infer the encrypted type from a ProtectTable schema.
958
+ * Infer the encrypted type from a EncryptedTable schema.
942
959
  *
943
960
  * @example
944
961
  * ```typescript
@@ -950,13 +967,13 @@ type InferPlaintext<T extends ProtectTable<any>> = T extends ProtectTable<infer
950
967
  * // => { email: Encrypted }
951
968
  * ```
952
969
  */
953
- type InferEncrypted<T extends ProtectTable<any>> = T extends ProtectTable<infer C> ? {
954
- [K in keyof C as C[K] extends ProtectColumn | ProtectValue ? K : never]: Encrypted;
970
+ type InferEncrypted<T extends EncryptedTable<any>> = T extends EncryptedTable<infer C> ? {
971
+ [K in keyof C as C[K] extends EncryptedColumn | EncryptedField ? K : never]: Encrypted;
955
972
  } : never;
956
973
  /**
957
974
  * Define an encrypted table schema.
958
975
  *
959
- * Creates a `ProtectTable` that maps a database table name to a set of encrypted
976
+ * Creates a `EncryptedTable` that maps a database table name to a set of encrypted
960
977
  * column definitions. Pass the resulting object to `Encryption({ schemas: [...] })`
961
978
  * when initializing the client.
962
979
  *
@@ -966,8 +983,9 @@ type InferEncrypted<T extends ProtectTable<any>> = T extends ProtectTable<infer
966
983
  *
967
984
  * @param tableName - The name of the database table this schema represents.
968
985
  * @param columns - An object whose keys are logical column names and values are
969
- * `ProtectColumn` instances created with {@link encryptedColumn}.
970
- * @returns A `ProtectTable<T> & T` that can be used as both a schema definition
986
+ * {@link EncryptedColumn} from {@link encryptedColumn}, or nested objects whose
987
+ * leaves are {@link EncryptedField} from {@link encryptedField}.
988
+ * @returns A `EncryptedTable<T> & T` that can be used as both a schema definition
971
989
  * and a column accessor.
972
990
  *
973
991
  * @example
@@ -986,17 +1004,17 @@ type InferEncrypted<T extends ProtectTable<any>> = T extends ProtectTable<infer
986
1004
  * await client.encrypt("hello@example.com", { column: users.email, table: users })
987
1005
  * ```
988
1006
  */
989
- declare function encryptedTable<T extends ProtectTableColumn>(tableName: string, columns: T): ProtectTable<T> & T;
1007
+ declare function encryptedTable<T extends EncryptedTableColumn>(tableName: string, columns: T): EncryptedTable<T> & T;
990
1008
  /**
991
1009
  * Define an encrypted column within a table schema.
992
1010
  *
993
- * Creates a `ProtectColumn` builder for the given column name. Chain index
1011
+ * Creates a `EncryptedColumn` builder for the given column name. Chain index
994
1012
  * methods (`.equality()`, `.freeTextSearch()`, `.orderAndRange()`,
995
1013
  * `.searchableJson()`) and/or `.dataType()` to configure searchable encryption
996
1014
  * and the plaintext data type.
997
1015
  *
998
1016
  * @param columnName - The name of the database column to encrypt.
999
- * @returns A new `ProtectColumn` builder.
1017
+ * @returns A new `EncryptedColumn` builder.
1000
1018
  *
1001
1019
  * @example
1002
1020
  * ```typescript
@@ -1007,31 +1025,31 @@ declare function encryptedTable<T extends ProtectTableColumn>(tableName: string,
1007
1025
  * })
1008
1026
  * ```
1009
1027
  */
1010
- declare function encryptedColumn(columnName: string): ProtectColumn;
1028
+ declare function encryptedColumn(columnName: string): EncryptedColumn;
1011
1029
  /**
1012
- * Define an encrypted value for use in nested or structured schemas.
1030
+ * Define an encrypted field for use in nested or structured schemas.
1013
1031
  *
1014
- * `encryptedValue` is similar to {@link encryptedColumn} but creates a `ProtectValue`
1015
- * intended for nested fields within a table schema. It supports `.dataType()`
1016
- * for specifying the plaintext type.
1032
+ * `encryptedField` is similar to {@link encryptedColumn} but creates an {@link EncryptedField}
1033
+ * for nested fields that are encrypted but not searchable (no indexes). Use `.dataType()`
1034
+ * to specify the plaintext type.
1017
1035
  *
1018
1036
  * @param valueName - The name of the value field.
1019
- * @returns A new `ProtectValue` builder.
1037
+ * @returns A new `EncryptedField` builder.
1020
1038
  *
1021
1039
  * @example
1022
1040
  * ```typescript
1023
- * import { encryptedTable, encryptedValue } from "@cipherstash/stack/schema"
1041
+ * import { encryptedTable, encryptedField } from "@cipherstash/stack/schema"
1024
1042
  *
1025
1043
  * const orders = encryptedTable("orders", {
1026
1044
  * details: {
1027
- * amount: encryptedValue("amount").dataType("number"),
1028
- * currency: encryptedValue("currency"),
1045
+ * amount: encryptedField("amount").dataType("number"),
1046
+ * currency: encryptedField("currency"),
1029
1047
  * },
1030
1048
  * })
1031
1049
  * ```
1032
1050
  */
1033
- declare function encryptedValue(valueName: string): ProtectValue;
1051
+ declare function encryptedField(valueName: string): EncryptedField;
1034
1052
  /** @internal */
1035
- declare function buildEncryptConfig(...protectTables: Array<ProtectTable<ProtectTableColumn>>): EncryptConfig;
1053
+ declare function buildEncryptConfig(...protectTables: Array<EncryptedTable<EncryptedTableColumn>>): EncryptConfig;
1036
1054
 
1037
- 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, ProtectColumn as P, type QueryTypeName as Q, queryTypes as R, type ScalarQueryTerm as S, type TokenFilter as T, type UniqueIndexOpts as U, encryptedColumn as a, encryptedValue as b, type InferEncrypted as c, ProtectTable as d, encryptedTable as e, type ProtectTableColumn as f, ProtectValue as g, type EncryptedFromSchema as h, type Encrypted as i, type EncryptedValue as j, type EncryptedQueryResult as k, type Client as l, type BulkDecryptPayload as m, type BulkEncryptedData as n, type BulkEncryptPayload as o, type EncryptOptions as p, type EncryptQueryOptions as q, type EncryptedReturnType as r, type EncryptConfig as s, castAsEnum as t, encryptConfigSchema as u, type SteVecIndexOpts as v, type ColumnSchema as w, buildEncryptConfig as x, type EncryptPayload as y, type ClientConfig as z };
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 };
@@ -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 ProtectColumn,\n ProtectTable,\n ProtectTableColumn,\n ProtectValue,\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<ProtectTable<ProtectTableColumn>>\n config?: ClientConfig\n logging?: LoggingConfig\n}\n\n// ---------------------------------------------------------------------------\n// Encrypt / decrypt operation options and results\n// ---------------------------------------------------------------------------\n\nexport type EncryptOptions = {\n column: ProtectColumn | ProtectValue\n table: ProtectTable<ProtectTableColumn>\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: ProtectColumn\n table: ProtectTable<ProtectTableColumn>\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 `ProtectTableColumn` (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: ProtectColumn }>\n * // => { id: string; email: Encrypted }\n * ```\n */\nexport type EncryptedFromSchema<\n T,\n S extends ProtectTableColumn,\n> = {\n [K in keyof T]: [K] extends [keyof S]\n ? [S[K & keyof S]] extends [ProtectColumn | ProtectValue]\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: ProtectColumn\n table: ProtectTable<ProtectTableColumn>\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;;;AC0NO,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 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,4 +1,4 @@
1
- export { m as BulkDecryptPayload, B as BulkDecryptedData, o as BulkEncryptPayload, n as BulkEncryptedData, l as Client, z as ClientConfig, D as Decrypted, J as DecryptedFields, L as DecryptionResult, p as EncryptOptions, y as EncryptPayload, q as EncryptQueryOptions, i as Encrypted, G as EncryptedFields, k as EncryptedQueryResult, r as EncryptedReturnType, F as EncryptedSearchTerm, j as EncryptedValue, E as EncryptionClientConfig, K as KeysetIdentifier, N as LoggingConfig, H as OtherFields, Q as QueryTypeName, S as ScalarQueryTerm, A as SearchTerm, R as queryTypes } from './types-public-Dfg-hkuQ.cjs';
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';
2
2
  import 'zod';
3
3
  import 'evlog';
4
4
  import '@cipherstash/protect-ffi';
@@ -1,4 +1,4 @@
1
- export { m as BulkDecryptPayload, B as BulkDecryptedData, o as BulkEncryptPayload, n as BulkEncryptedData, l as Client, z as ClientConfig, D as Decrypted, J as DecryptedFields, L as DecryptionResult, p as EncryptOptions, y as EncryptPayload, q as EncryptQueryOptions, i as Encrypted, G as EncryptedFields, k as EncryptedQueryResult, r as EncryptedReturnType, F as EncryptedSearchTerm, j as EncryptedValue, E as EncryptionClientConfig, K as KeysetIdentifier, N as LoggingConfig, H as OtherFields, Q as QueryTypeName, S as ScalarQueryTerm, A as SearchTerm, R as queryTypes } from './types-public-Dfg-hkuQ.js';
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';
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-5G4F4JJG.js";
3
+ } from "./chunk-JLI27P46.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.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "CipherStash Stack for TypeScript and JavaScript",
5
5
  "keywords": [
6
6
  "encrypted",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n ProtectColumn,\n ProtectTable,\n ProtectTableColumn,\n ProtectValue,\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<ProtectTable<ProtectTableColumn>>\n config?: ClientConfig\n logging?: LoggingConfig\n}\n\n// ---------------------------------------------------------------------------\n// Encrypt / decrypt operation options and results\n// ---------------------------------------------------------------------------\n\nexport type EncryptOptions = {\n column: ProtectColumn | ProtectValue\n table: ProtectTable<ProtectTableColumn>\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: ProtectColumn\n table: ProtectTable<ProtectTableColumn>\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 `ProtectTableColumn` (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: ProtectColumn }>\n * // => { id: string; email: Encrypted }\n * ```\n */\nexport type EncryptedFromSchema<\n T,\n S extends ProtectTableColumn,\n> = {\n [K in keyof T]: [K] extends [keyof S]\n ? [S[K & keyof S]] extends [ProtectColumn | ProtectValue]\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: ProtectColumn\n table: ProtectTable<ProtectTableColumn>\n queryType?: QueryTypeName\n returnType?: EncryptedReturnType\n}\n\nexport type EncryptQueryOptions = QueryTermBase\n\nexport type ScalarQueryTerm = QueryTermBase & {\n value: JsPlaintext | null\n}\n"],"mappings":";AA0NO,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":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schema/index.ts"],"sourcesContent":["import type { Encrypted } from '@/types'\nimport { z } from 'zod'\n\n// ------------------------\n// Zod schemas\n// ------------------------\n\n/**\n * Allowed cast types for CipherStash schema fields.\n *\n * **Possible values:**\n * - `\"bigint\"`\n * - `\"boolean\"`\n * - `\"date\"`\n * - `\"number\"`\n * - `\"string\"`\n * - `\"json\"`\n *\n * @remarks\n * This is a Zod enum used at runtime to validate schema definitions.\n * Use {@link CastAs} when typing your own code.\n *\n * @internal\n */\nexport const castAsEnum = z\n .enum(['bigint', 'boolean', 'date', 'number', 'string', 'json'])\n .default('string')\n\nconst tokenFilterSchema = z.object({\n kind: z.literal('downcase'),\n})\n\nconst tokenizerSchema = z\n .union([\n z.object({\n kind: z.literal('standard'),\n }),\n z.object({\n kind: z.literal('ngram'),\n token_length: z.number(),\n }),\n ])\n .default({ kind: 'ngram', token_length: 3 })\n .optional()\n\nconst oreIndexOptsSchema = z.object({})\n\nconst uniqueIndexOptsSchema = z.object({\n token_filters: z.array(tokenFilterSchema).default([]).optional(),\n})\n\nconst matchIndexOptsSchema = z.object({\n tokenizer: tokenizerSchema,\n token_filters: z.array(tokenFilterSchema).default([]).optional(),\n k: z.number().default(6).optional(),\n m: z.number().default(2048).optional(),\n include_original: z.boolean().default(false).optional(),\n})\n\nconst steVecIndexOptsSchema = z.object({\n prefix: z.string(),\n})\n\nconst indexesSchema = z\n .object({\n ore: oreIndexOptsSchema.optional(),\n unique: uniqueIndexOptsSchema.optional(),\n match: matchIndexOptsSchema.optional(),\n ste_vec: steVecIndexOptsSchema.optional(),\n })\n .default({})\n\nconst columnSchema = z\n .object({\n cast_as: castAsEnum,\n indexes: indexesSchema,\n })\n .default({})\n\nconst tableSchema = z.record(columnSchema).default({})\n\nconst tablesSchema = z.record(tableSchema).default({})\n\n/** @internal */\nexport const encryptConfigSchema = z.object({\n v: z.number(),\n tables: tablesSchema,\n})\n\n// ------------------------\n// Type definitions\n// ------------------------\n\n/**\n * Type-safe alias for {@link castAsEnum} used to specify the *unencrypted* data type of a column or value.\n * This is important because once encrypted, all data is stored as binary blobs.\n *\n * @see {@link castAsEnum} for possible values.\n */\nexport type CastAs = z.infer<typeof castAsEnum>\nexport type TokenFilter = z.infer<typeof tokenFilterSchema>\nexport type MatchIndexOpts = z.infer<typeof matchIndexOptsSchema>\nexport type SteVecIndexOpts = z.infer<typeof steVecIndexOptsSchema>\nexport type UniqueIndexOpts = z.infer<typeof uniqueIndexOptsSchema>\nexport type OreIndexOpts = z.infer<typeof oreIndexOptsSchema>\nexport type ColumnSchema = z.infer<typeof columnSchema>\n\nexport type ProtectTableColumn = {\n [key: string]:\n | ProtectColumn\n | {\n [key: string]:\n | ProtectValue\n | {\n [key: string]:\n | ProtectValue\n | {\n [key: string]: ProtectValue\n }\n }\n }\n}\nexport type EncryptConfig = z.infer<typeof encryptConfigSchema>\n\n// ------------------------\n// Interface definitions\n// ------------------------\nexport class ProtectValue {\n private valueName: string\n private castAsValue: CastAs\n\n constructor(valueName: string) {\n this.valueName = valueName\n this.castAsValue = 'string'\n }\n\n /**\n * Set or override the plaintext data type for this value.\n *\n * By default all values are treated as `'string'`. Use this method to specify\n * a different type so the encryption layer knows how to encode the plaintext\n * before encrypting.\n *\n * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.\n * @returns This `ProtectValue` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedValue } from \"@cipherstash/stack/schema\"\n *\n * const age = encryptedValue(\"age\").dataType(\"number\")\n * ```\n */\n dataType(castAs: CastAs) {\n this.castAsValue = castAs\n return this\n }\n\n build() {\n return {\n cast_as: this.castAsValue,\n indexes: {},\n }\n }\n\n getName() {\n return this.valueName\n }\n}\n\nexport class ProtectColumn {\n private columnName: string\n private castAsValue: CastAs\n private indexesValue: {\n ore?: OreIndexOpts\n unique?: UniqueIndexOpts\n match?: Required<MatchIndexOpts>\n ste_vec?: SteVecIndexOpts\n } = {}\n\n constructor(columnName: string) {\n this.columnName = columnName\n this.castAsValue = 'string'\n }\n\n /**\n * Set or override the plaintext data type for this column.\n *\n * By default all columns are treated as `'string'`. Use this method to specify\n * a different type so the encryption layer knows how to encode the plaintext\n * before encrypting.\n *\n * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.\n * @returns This `ProtectColumn` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const dateOfBirth = encryptedColumn(\"date_of_birth\").dataType(\"date\")\n * ```\n */\n dataType(castAs: CastAs) {\n this.castAsValue = castAs\n return this\n }\n\n /**\n * Enable Order-Revealing Encryption (ORE) indexing on this column.\n *\n * ORE allows sorting, comparison, and range queries on encrypted data.\n * Use with `encryptQuery` and `queryType: 'orderAndRange'`.\n *\n * @returns This `ProtectColumn` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").orderAndRange(),\n * })\n * ```\n */\n orderAndRange() {\n this.indexesValue.ore = {}\n return this\n }\n\n /**\n * Enable an exact-match (unique) index on this column.\n *\n * Allows equality queries on encrypted data. Use with `encryptQuery`\n * and `queryType: 'equality'`.\n *\n * @param tokenFilters - Optional array of token filters (e.g. `[{ kind: 'downcase' }]`).\n * When omitted, no token filters are applied.\n * @returns This `ProtectColumn` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * })\n * ```\n */\n equality(tokenFilters?: TokenFilter[]) {\n this.indexesValue.unique = {\n token_filters: tokenFilters ?? [],\n }\n return this\n }\n\n /**\n * Enable a full-text / fuzzy search (match) index on this column.\n *\n * Uses n-gram tokenization by default for substring and fuzzy matching.\n * Use with `encryptQuery` and `queryType: 'freeTextSearch'`.\n *\n * @param opts - Optional match index configuration. Defaults to 3-character ngram\n * tokenization with a downcase filter, `k=6`, `m=2048`, and `include_original=true`.\n * @returns This `ProtectColumn` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").freeTextSearch(),\n * })\n *\n * // With custom options\n * const posts = encryptedTable(\"posts\", {\n * body: encryptedColumn(\"body\").freeTextSearch({\n * tokenizer: { kind: \"ngram\", token_length: 4 },\n * k: 8,\n * m: 4096,\n * }),\n * })\n * ```\n */\n freeTextSearch(opts?: MatchIndexOpts) {\n // Provide defaults\n this.indexesValue.match = {\n tokenizer: opts?.tokenizer ?? { kind: 'ngram', token_length: 3 },\n token_filters: opts?.token_filters ?? [\n {\n kind: 'downcase',\n },\n ],\n k: opts?.k ?? 6,\n m: opts?.m ?? 2048,\n include_original: opts?.include_original ?? true,\n }\n return this\n }\n\n /**\n * Configure this column for searchable encrypted JSON (STE-Vec).\n *\n * Enables encrypted JSONPath selector queries (e.g. `'$.user.email'`) and\n * containment queries (e.g. `{ role: 'admin' }`). Automatically sets the\n * data type to `'json'`.\n *\n * When used with `encryptQuery`, the query operation is auto-inferred from\n * the plaintext type: strings become selector queries, objects/arrays become\n * containment queries.\n *\n * @returns This `ProtectColumn` instance for method chaining.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const documents = encryptedTable(\"documents\", {\n * metadata: encryptedColumn(\"metadata\").searchableJson(),\n * })\n * ```\n */\n searchableJson() {\n this.castAsValue = 'json'\n this.indexesValue.ste_vec = { prefix: 'enabled' }\n return this\n }\n\n build() {\n return {\n cast_as: this.castAsValue,\n indexes: this.indexesValue,\n }\n }\n\n getName() {\n return this.columnName\n }\n}\n\ninterface TableDefinition {\n tableName: string\n columns: Record<string, ColumnSchema>\n}\n\nexport class ProtectTable<T extends ProtectTableColumn> {\n constructor(\n public readonly tableName: string,\n private readonly columnBuilders: T,\n ) {}\n\n /**\n * Compile this table schema into a `TableDefinition` used internally by the encryption client.\n *\n * Iterates over all column builders, calls `.build()` on each, and assembles\n * the final `{ tableName, columns }` structure. For `searchableJson()` columns,\n * the STE-Vec prefix is automatically set to `\"<tableName>/<columnName>\"`.\n *\n * @returns A `TableDefinition` containing the table name and built column configs.\n *\n * @example\n * ```typescript\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * })\n *\n * const definition = users.build()\n * // { tableName: \"users\", columns: { email: { cast_as: \"string\", indexes: { unique: ... } } } }\n * ```\n */\n build(): TableDefinition {\n const builtColumns: Record<string, ColumnSchema> = {}\n\n const processColumn = (\n builder:\n | ProtectColumn\n | Record<\n string,\n | ProtectValue\n | Record<\n string,\n | ProtectValue\n | Record<string, ProtectValue | Record<string, ProtectValue>>\n >\n >,\n colName: string,\n ) => {\n if (builder instanceof ProtectColumn) {\n const builtColumn = builder.build()\n\n // Hanlde building the ste_vec index for JSON columns so users don't have to pass the prefix.\n if (\n builtColumn.cast_as === 'json' &&\n builtColumn.indexes.ste_vec?.prefix === 'enabled'\n ) {\n builtColumns[colName] = {\n ...builtColumn,\n indexes: {\n ...builtColumn.indexes,\n ste_vec: {\n prefix: `${this.tableName}/${colName}`,\n },\n },\n }\n } else {\n builtColumns[colName] = builtColumn\n }\n } else {\n for (const [key, value] of Object.entries(builder)) {\n if (value instanceof ProtectValue) {\n builtColumns[value.getName()] = value.build()\n } else {\n processColumn(value, key)\n }\n }\n }\n }\n\n for (const [colName, builder] of Object.entries(this.columnBuilders)) {\n processColumn(builder, colName)\n }\n\n return {\n tableName: this.tableName,\n columns: builtColumns,\n }\n }\n}\n\n// ------------------------\n// Schema type inference helpers\n// ------------------------\n\n/**\n * Infer the plaintext (decrypted) type from a ProtectTable schema.\n *\n * @example\n * ```typescript\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * name: encryptedColumn(\"name\"),\n * })\n *\n * type UserPlaintext = InferPlaintext<typeof users>\n * // => { email: string; name: string }\n * ```\n */\nexport type InferPlaintext<T extends ProtectTable<any>> =\n T extends ProtectTable<infer C>\n ? {\n [K in keyof C as C[K] extends ProtectColumn | ProtectValue\n ? K\n : never]: string\n }\n : never\n\n/**\n * Infer the encrypted type from a ProtectTable schema.\n *\n * @example\n * ```typescript\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality(),\n * })\n *\n * type UserEncrypted = InferEncrypted<typeof users>\n * // => { email: Encrypted }\n * ```\n */\nexport type InferEncrypted<T extends ProtectTable<any>> =\n T extends ProtectTable<infer C>\n ? {\n [K in keyof C as C[K] extends ProtectColumn | ProtectValue\n ? K\n : never]: Encrypted\n }\n : never\n\n// ------------------------\n// User facing functions\n// ------------------------\n\n/**\n * Define an encrypted table schema.\n *\n * Creates a `ProtectTable` that maps a database table name to a set of encrypted\n * column definitions. Pass the resulting object to `Encryption({ schemas: [...] })`\n * when initializing the client.\n *\n * The returned object is also a proxy that exposes each column builder directly,\n * so you can reference columns as `users.email` when calling `encrypt`, `decrypt`,\n * and `encryptQuery`.\n *\n * @param tableName - The name of the database table this schema represents.\n * @param columns - An object whose keys are logical column names and values are\n * `ProtectColumn` instances created with {@link encryptedColumn}.\n * @returns A `ProtectTable<T> & T` that can be used as both a schema definition\n * and a column accessor.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality().freeTextSearch(),\n * address: encryptedColumn(\"address\"),\n * })\n *\n * // Use as schema\n * const client = await Encryption({ schemas: [users] })\n *\n * // Use as column accessor\n * await client.encrypt(\"hello@example.com\", { column: users.email, table: users })\n * ```\n */\nexport function encryptedTable<T extends ProtectTableColumn>(\n tableName: string,\n columns: T,\n): ProtectTable<T> & T {\n const tableBuilder = new ProtectTable(tableName, columns) as ProtectTable<T> &\n T\n\n for (const [colName, colBuilder] of Object.entries(columns)) {\n ;(tableBuilder as ProtectTableColumn)[colName] = colBuilder\n }\n\n return tableBuilder\n}\n\n/**\n * Define an encrypted column within a table schema.\n *\n * Creates a `ProtectColumn` builder for the given column name. Chain index\n * methods (`.equality()`, `.freeTextSearch()`, `.orderAndRange()`,\n * `.searchableJson()`) and/or `.dataType()` to configure searchable encryption\n * and the plaintext data type.\n *\n * @param columnName - The name of the database column to encrypt.\n * @returns A new `ProtectColumn` builder.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedColumn } from \"@cipherstash/stack/schema\"\n *\n * const users = encryptedTable(\"users\", {\n * email: encryptedColumn(\"email\").equality().freeTextSearch().orderAndRange(),\n * })\n * ```\n */\nexport function encryptedColumn(columnName: string) {\n return new ProtectColumn(columnName)\n}\n\n/**\n * Define an encrypted value for use in nested or structured schemas.\n *\n * `encryptedValue` is similar to {@link encryptedColumn} but creates a `ProtectValue`\n * intended for nested fields within a table schema. It supports `.dataType()`\n * for specifying the plaintext type.\n *\n * @param valueName - The name of the value field.\n * @returns A new `ProtectValue` builder.\n *\n * @example\n * ```typescript\n * import { encryptedTable, encryptedValue } from \"@cipherstash/stack/schema\"\n *\n * const orders = encryptedTable(\"orders\", {\n * details: {\n * amount: encryptedValue(\"amount\").dataType(\"number\"),\n * currency: encryptedValue(\"currency\"),\n * },\n * })\n * ```\n */\nexport function encryptedValue(valueName: string) {\n return new ProtectValue(valueName)\n}\n\n// ------------------------\n// Internal functions\n// ------------------------\n\n/** @internal */\nexport function buildEncryptConfig(\n ...protectTables: Array<ProtectTable<ProtectTableColumn>>\n): EncryptConfig {\n const config: EncryptConfig = {\n v: 2,\n tables: {},\n }\n\n for (const tb of protectTables) {\n const tableDef = tb.build()\n config.tables[tableDef.tableName] = tableDef.columns\n }\n\n return config\n}\n"],"mappings":"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","names":[]}