@cipherstash/stack 0.18.0 → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +704 -0
  2. package/README.md +97 -79
  3. package/dist/adapter-kit.cjs +923 -0
  4. package/dist/adapter-kit.cjs.map +1 -0
  5. package/dist/adapter-kit.d.cts +82 -0
  6. package/dist/adapter-kit.d.ts +82 -0
  7. package/dist/adapter-kit.js +47 -0
  8. package/dist/adapter-kit.js.map +1 -0
  9. package/dist/base-operation-AOAIvsSB.d.cts +32 -0
  10. package/dist/base-operation-FXEzUXIq.d.ts +32 -0
  11. package/dist/{chunk-VPOTNP4K.js → chunk-3B5ZX3IS.js} +3 -1
  12. package/dist/chunk-3B5ZX3IS.js.map +1 -0
  13. package/dist/chunk-7333ZC6L.js +48 -0
  14. package/dist/chunk-7333ZC6L.js.map +1 -0
  15. package/dist/{chunk-XWPGAHBZ.js → chunk-BNO32ZMV.js} +1 -1
  16. package/dist/chunk-BNO32ZMV.js.map +1 -0
  17. package/dist/chunk-CLM7E4I6.js +4439 -0
  18. package/dist/chunk-CLM7E4I6.js.map +1 -0
  19. package/dist/{chunk-LLCCNKDL.js → chunk-HQANMV7R.js} +3 -3
  20. package/dist/{chunk-LLCCNKDL.js.map → chunk-HQANMV7R.js.map} +1 -1
  21. package/dist/chunk-JSG2AMDI.js +17 -0
  22. package/dist/chunk-JSG2AMDI.js.map +1 -0
  23. package/dist/chunk-OFQ555AX.js +191 -0
  24. package/dist/chunk-OFQ555AX.js.map +1 -0
  25. package/dist/chunk-PZ5AY32C.js +10 -0
  26. package/dist/chunk-PZ5AY32C.js.map +1 -0
  27. package/dist/chunk-V2Q3NYIH.js +494 -0
  28. package/dist/chunk-V2Q3NYIH.js.map +1 -0
  29. package/dist/chunk-X3JRXEIB.js +98 -0
  30. package/dist/chunk-X3JRXEIB.js.map +1 -0
  31. package/dist/{chunk-ZYOZHZMJ.js → chunk-ZTP5QJ27.js} +193 -169
  32. package/dist/chunk-ZTP5QJ27.js.map +1 -0
  33. package/dist/client.cjs +4124 -49
  34. package/dist/client.cjs.map +1 -1
  35. package/dist/client.d.cts +6 -5
  36. package/dist/client.d.ts +6 -5
  37. package/dist/client.js +3 -1
  38. package/dist/columns-D2_YzrCX.d.cts +622 -0
  39. package/dist/columns-rZc7fQHI.d.ts +622 -0
  40. package/dist/dynamodb/index.cjs +19 -12
  41. package/dist/dynamodb/index.cjs.map +1 -1
  42. package/dist/dynamodb/index.d.cts +3 -2
  43. package/dist/dynamodb/index.d.ts +3 -2
  44. package/dist/dynamodb/index.js +8 -10
  45. package/dist/dynamodb/index.js.map +1 -1
  46. package/dist/encryption/index.cjs +4496 -222
  47. package/dist/encryption/index.cjs.map +1 -1
  48. package/dist/encryption/index.d.cts +807 -6
  49. package/dist/encryption/index.d.ts +807 -6
  50. package/dist/encryption/index.js +15 -7
  51. package/dist/encryption/v3.cjs +7896 -0
  52. package/dist/encryption/v3.cjs.map +1 -0
  53. package/dist/encryption/v3.d.cts +103 -0
  54. package/dist/encryption/v3.d.ts +103 -0
  55. package/dist/encryption/v3.js +189 -0
  56. package/dist/encryption/v3.js.map +1 -0
  57. package/dist/eql/v3/index.cjs +663 -0
  58. package/dist/eql/v3/index.cjs.map +1 -0
  59. package/dist/eql/v3/index.d.cts +173 -0
  60. package/dist/eql/v3/index.d.ts +173 -0
  61. package/dist/eql/v3/index.js +99 -0
  62. package/dist/eql/v3/index.js.map +1 -0
  63. package/dist/errors/index.js +1 -0
  64. package/dist/identity/index.cjs +55 -35
  65. package/dist/identity/index.cjs.map +1 -1
  66. package/dist/identity/index.d.cts +54 -30
  67. package/dist/identity/index.d.ts +54 -30
  68. package/dist/identity/index.js +9 -177
  69. package/dist/identity/index.js.map +1 -1
  70. package/dist/index-BquA71_Y.d.ts +24 -0
  71. package/dist/index-fhWTOV0K.d.cts +24 -0
  72. package/dist/index.cjs +4547 -243
  73. package/dist/index.cjs.map +1 -1
  74. package/dist/index.d.cts +18 -19
  75. package/dist/index.d.ts +18 -19
  76. package/dist/index.js +20 -5
  77. package/dist/index.js.map +1 -1
  78. package/dist/schema/index.cjs +4128 -49
  79. package/dist/schema/index.cjs.map +1 -1
  80. package/dist/schema/index.d.cts +1 -1
  81. package/dist/schema/index.d.ts +1 -1
  82. package/dist/schema/index.js +3 -1
  83. package/dist/{types-public-BTxqjmtv.d.cts → types-public-QMjYNfQO.d.cts} +448 -251
  84. package/dist/{types-public-BTxqjmtv.d.ts → types-public-QMjYNfQO.d.ts} +448 -251
  85. package/dist/types-public.cjs.map +1 -1
  86. package/dist/types-public.d.cts +2 -2
  87. package/dist/types-public.d.ts +2 -2
  88. package/dist/types-public.js +2 -1
  89. package/dist/wasm-inline.d.ts +1643 -0
  90. package/dist/wasm-inline.js +4901 -0
  91. package/dist/wasm-inline.js.map +1 -0
  92. package/package.json +74 -52
  93. package/dist/chunk-VPOTNP4K.js.map +0 -1
  94. package/dist/chunk-XWPGAHBZ.js.map +0 -1
  95. package/dist/chunk-YWQXTZ5M.js +0 -383
  96. package/dist/chunk-YWQXTZ5M.js.map +0 -1
  97. package/dist/chunk-ZYOZHZMJ.js.map +0 -1
  98. package/dist/client-CIsfZ2zg.d.ts +0 -692
  99. package/dist/client-Dt98Rugc.d.cts +0 -692
  100. package/dist/drizzle/index.cjs +0 -1558
  101. package/dist/drizzle/index.cjs.map +0 -1
  102. package/dist/drizzle/index.d.cts +0 -358
  103. package/dist/drizzle/index.d.ts +0 -358
  104. package/dist/drizzle/index.js +0 -1215
  105. package/dist/drizzle/index.js.map +0 -1
  106. package/dist/supabase/index.cjs +0 -1526
  107. package/dist/supabase/index.cjs.map +0 -1
  108. package/dist/supabase/index.d.cts +0 -144
  109. package/dist/supabase/index.d.ts +0 -144
  110. package/dist/supabase/index.js +0 -899
  111. package/dist/supabase/index.js.map +0 -1
@@ -1,358 +0,0 @@
1
- import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
2
- import { PgTable, PgCustomColumn } from 'drizzle-orm/pg-core';
3
- import { c as EncryptedTable, f as EncryptedColumn, C as CastAs, M as MatchIndexOpts, T as TokenFilter } from '../types-public-BTxqjmtv.cjs';
4
- import { a as EncryptionClient } from '../client-Dt98Rugc.cjs';
5
- import { SQLWrapper, SQL, exists, notExists, isNull, isNotNull, not, arrayContains, arrayContained, arrayOverlaps } from 'drizzle-orm';
6
- import 'zod';
7
- import '@cipherstash/protect-ffi';
8
- import '../errors/index.cjs';
9
- import '@byteslice/result';
10
- import '../identity/index.cjs';
11
-
12
- /**
13
- * Extracts the encrypted column keys from a Drizzle table type.
14
- * Columns created with `encryptedType` are `PgCustomColumn` instances;
15
- * this picks only those keys and maps them to `EncryptedColumn`.
16
- */
17
- type DrizzleEncryptedSchema<T> = {
18
- [K in keyof T as T[K] extends PgCustomColumn<any> ? K : never]: EncryptedColumn;
19
- };
20
- /**
21
- * Extracts an encryption schema from a Drizzle table definition.
22
- * This function identifies columns created with `encryptedType` and
23
- * builds a corresponding `EncryptedTable` with `encryptedColumn` definitions.
24
- *
25
- * @param table - The Drizzle table definition
26
- * @returns A EncryptedTable that can be used with encryption client initialization
27
- *
28
- * @example
29
- * ```ts
30
- * const drizzleUsersTable = pgTable('users', {
31
- * email: encryptedType('email', { freeTextSearch: true, equality: true }),
32
- * age: encryptedType('age', { dataType: 'number', orderAndRange: true }),
33
- * })
34
- *
35
- * const encryptionSchema = extractEncryptionSchema(drizzleUsersTable)
36
- * const client = await createEncryptionClient({ schemas: [encryptionSchema.build()] })
37
- * ```
38
- */
39
- declare function extractEncryptionSchema<T extends PgTable<any>>(table: T): EncryptedTable<DrizzleEncryptedSchema<T>> & DrizzleEncryptedSchema<T>;
40
-
41
- /**
42
- * Custom error types for better debugging
43
- */
44
- declare class EncryptionOperatorError extends Error {
45
- readonly context?: {
46
- tableName?: string;
47
- columnName?: string;
48
- operator?: string;
49
- } | undefined;
50
- constructor(message: string, context?: {
51
- tableName?: string;
52
- columnName?: string;
53
- operator?: string;
54
- } | undefined);
55
- }
56
- declare class EncryptionConfigError extends EncryptionOperatorError {
57
- constructor(message: string, context?: EncryptionOperatorError['context']);
58
- }
59
- /**
60
- * Creates a set of encryption-aware operators that automatically encrypt values
61
- * for encrypted columns before using them with Drizzle operators.
62
- *
63
- * For equality and text search operators (eq, ne, like, ilike, inArray, etc.):
64
- * Values are encrypted and then passed to regular Drizzle operators, which use
65
- * PostgreSQL's built-in operators for eql_v2_encrypted types.
66
- *
67
- * For order and range operators (gt, gte, lt, lte, between, notBetween):
68
- * Values are encrypted and then use eql_v2.* functions (eql_v2.gt(), eql_v2.gte(), etc.)
69
- * which are required for ORE (Order-Revealing Encryption) comparisons.
70
- *
71
- * @param encryptionClient - The EncryptionClient instance
72
- * @returns An object with all Drizzle operators wrapped for encrypted columns
73
- *
74
- * @example
75
- * ```ts
76
- * // Initialize operators
77
- * const ops = createEncryptionOperators(encryptionClient)
78
- *
79
- * // Equality search - automatically encrypts and uses PostgreSQL operators
80
- * const results = await db
81
- * .select()
82
- * .from(usersTable)
83
- * .where(await ops.eq(usersTable.email, 'user@example.com'))
84
- *
85
- * // Range query - automatically encrypts and uses eql_v2.gte()
86
- * const olderUsers = await db
87
- * .select()
88
- * .from(usersTable)
89
- * .where(await ops.gte(usersTable.age, 25))
90
- * ```
91
- */
92
- declare function createEncryptionOperators(encryptionClient: EncryptionClient): {
93
- /**
94
- * Equality operator - encrypts value for encrypted columns.
95
- * Requires either `equality` or `orderAndRange` to be set on {@link EncryptedColumnConfig}.
96
- *
97
- * @example
98
- * Select users with a specific email address.
99
- * ```ts
100
- * const condition = await ops.eq(usersTable.email, 'user@example.com')
101
- * const results = await db.select().from(usersTable).where(condition)
102
- * ```
103
- */
104
- eq: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
105
- /**
106
- * Not equal operator - encrypts value for encrypted columns.
107
- * Requires either `equality` or `orderAndRange` to be set on {@link EncryptedColumnConfig}.
108
- *
109
- * @example
110
- * Select users whose email address is not a specific value.
111
- * ```ts
112
- * const condition = await ops.ne(usersTable.email, 'user@example.com')
113
- * const results = await db.select().from(usersTable).where(condition)
114
- * ```
115
- */
116
- ne: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
117
- /**
118
- * Greater than operator for encrypted columns with ORE index.
119
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
120
- *
121
- * @example
122
- * Select users older than a specific age.
123
- * ```ts
124
- * const condition = await ops.gt(usersTable.age, 30)
125
- * const results = await db.select().from(usersTable).where(condition)
126
- * ```
127
- */
128
- gt: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
129
- /**
130
- * Greater than or equal operator for encrypted columns with ORE index.
131
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
132
- *
133
- * @example
134
- * Select users older than or equal to a specific age.
135
- * ```ts
136
- * const condition = await ops.gte(usersTable.age, 30)
137
- * const results = await db.select().from(usersTable).where(condition)
138
- * ```
139
- */
140
- gte: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
141
- /**
142
- * Less than operator for encrypted columns with ORE index.
143
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
144
- *
145
- * @example
146
- * Select users younger than a specific age.
147
- * ```ts
148
- * const condition = await ops.lt(usersTable.age, 30)
149
- * const results = await db.select().from(usersTable).where(condition)
150
- * ```
151
- */
152
- lt: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
153
- /**
154
- * Less than or equal operator for encrypted columns with ORE index.
155
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
156
- *
157
- * @example
158
- * Select users younger than or equal to a specific age.
159
- * ```ts
160
- * const condition = await ops.lte(usersTable.age, 30)
161
- * const results = await db.select().from(usersTable).where(condition)
162
- * ```
163
- */
164
- lte: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
165
- /**
166
- * Between operator for encrypted columns with ORE index.
167
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
168
- *
169
- * @example
170
- * Select users within a specific age range.
171
- * ```ts
172
- * const condition = await ops.between(usersTable.age, 20, 30)
173
- * const results = await db.select().from(usersTable).where(condition)
174
- * ```
175
- */
176
- between: (left: SQLWrapper, min: unknown, max: unknown) => Promise<SQL> | SQL;
177
- /**
178
- * Not between operator for encrypted columns with ORE index.
179
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
180
- *
181
- * @example
182
- * Select users outside a specific age range.
183
- * ```ts
184
- * const condition = await ops.notBetween(usersTable.age, 20, 30)
185
- * const results = await db.select().from(usersTable).where(condition)
186
- * ```
187
- */
188
- notBetween: (left: SQLWrapper, min: unknown, max: unknown) => Promise<SQL> | SQL;
189
- /**
190
- * Like operator for encrypted columns with free text search.
191
- * Requires `freeTextSearch` to be set on {@link EncryptedColumnConfig}.
192
- *
193
- * > [!IMPORTANT]
194
- * > Case sensitivity on encrypted columns depends on the {@link EncryptedColumnConfig}.
195
- * > Ensure that the column is configured for case-insensitive search if needed.
196
- *
197
- * @example
198
- * Select users with email addresses matching a pattern.
199
- * ```ts
200
- * const condition = await ops.like(usersTable.email, '%@example.com')
201
- * const results = await db.select().from(usersTable).where(condition)
202
- * ```
203
- */
204
- like: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
205
- /**
206
- * ILike operator for encrypted columns with free text search.
207
- * Requires `freeTextSearch` to be set on {@link EncryptedColumnConfig}.
208
- *
209
- * > [!IMPORTANT]
210
- * > Case sensitivity on encrypted columns depends on the {@link EncryptedColumnConfig}.
211
- * > Ensure that the column is configured for case-insensitive search if needed.
212
- *
213
- * @example
214
- * Select users with email addresses matching a pattern (case-insensitive).
215
- * ```ts
216
- * const condition = await ops.ilike(usersTable.email, '%@example.com')
217
- * const results = await db.select().from(usersTable).where(condition)
218
- * ```
219
- */
220
- ilike: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
221
- notIlike: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
222
- /**
223
- * JSONB path query first operator for encrypted columns with searchable JSON.
224
- * Requires `searchableJson` to be set on {@link EncryptedColumnConfig}.
225
- *
226
- * Encrypts the JSON path selector and calls `eql_v2.jsonb_path_query_first()`,
227
- * casting the parameter to `eql_v2_encrypted`.
228
- *
229
- * @throws {EncryptionOperatorError} If the column does not have `searchableJson` enabled.
230
- */
231
- jsonbPathQueryFirst: (left: SQLWrapper, right: unknown) => Promise<SQL>;
232
- /**
233
- * JSONB get operator for encrypted columns with searchable JSON.
234
- * Requires `searchableJson` to be set on {@link EncryptedColumnConfig}.
235
- *
236
- * Encrypts the JSON path selector and uses the `->` operator,
237
- * casting the parameter to `eql_v2_encrypted`.
238
- *
239
- * @throws {EncryptionOperatorError} If the column does not have `searchableJson` enabled.
240
- */
241
- jsonbGet: (left: SQLWrapper, right: unknown) => Promise<SQL>;
242
- /**
243
- * JSONB path exists operator for encrypted columns with searchable JSON.
244
- * Requires `searchableJson` to be set on {@link EncryptedColumnConfig}.
245
- *
246
- * Encrypts the JSON path selector and calls `eql_v2.jsonb_path_exists()`,
247
- * casting the parameter to `eql_v2_encrypted`.
248
- *
249
- * @throws {EncryptionOperatorError} If the column does not have `searchableJson` enabled.
250
- */
251
- jsonbPathExists: (left: SQLWrapper, right: unknown) => Promise<SQL>;
252
- inArray: (left: SQLWrapper, right: unknown[] | SQLWrapper) => Promise<SQL>;
253
- notInArray: (left: SQLWrapper, right: unknown[] | SQLWrapper) => Promise<SQL>;
254
- asc: (column: SQLWrapper) => SQL;
255
- desc: (column: SQLWrapper) => SQL;
256
- and: (...conditions: (SQL | SQLWrapper | Promise<SQL> | undefined)[]) => Promise<SQL>;
257
- or: (...conditions: (SQL | SQLWrapper | Promise<SQL> | undefined)[]) => Promise<SQL>;
258
- exists: typeof exists;
259
- notExists: typeof notExists;
260
- isNull: typeof isNull;
261
- isNotNull: typeof isNotNull;
262
- not: typeof not;
263
- arrayContains: typeof arrayContains;
264
- arrayContained: typeof arrayContained;
265
- arrayOverlaps: typeof arrayOverlaps;
266
- };
267
-
268
- /**
269
- * Configuration for encrypted column indexes and data types
270
- */
271
- type EncryptedColumnConfig = {
272
- /**
273
- * Data type for the column (default: 'string')
274
- */
275
- dataType?: CastAs;
276
- /**
277
- * Enable free text search. Can be a boolean for default options, or an object for custom configuration.
278
- */
279
- freeTextSearch?: boolean | MatchIndexOpts;
280
- /**
281
- * Enable equality index. Can be a boolean for default options, or an array of token filters.
282
- */
283
- equality?: boolean | TokenFilter[];
284
- /**
285
- * Enable order and range index for sorting and range queries.
286
- */
287
- orderAndRange?: boolean;
288
- /**
289
- * Enable searchable JSON index for JSONB path queries.
290
- * Requires dataType: 'json'.
291
- */
292
- searchableJson?: boolean;
293
- };
294
- /**
295
- * Creates an encrypted column type for Drizzle ORM with configurable searchable encryption options.
296
- *
297
- * When data is encrypted, the actual stored value is an [EQL v2](/docs/reference/eql) encrypted composite type which includes any searchable encryption indexes defined for the column.
298
- * Importantly, the original data type is not known until it is decrypted. Therefore, this function allows specifying
299
- * the original data type via the `dataType` option in the configuration.
300
- * This ensures that when data is decrypted, it can be correctly interpreted as the intended TypeScript type.
301
- *
302
- * @typeParam TData - The TypeScript type of the data stored in the column
303
- * @param name - The column name in the database
304
- * @param config - Optional configuration for data type and searchable encryption indexes
305
- * @returns A Drizzle column type that can be used in pgTable definitions
306
- *
307
- * ## Searchable Encryption Options
308
- *
309
- * - `dataType`: Specifies the original data type of the column (e.g., 'string', 'number', 'json'). Default is 'string'.
310
- * - `freeTextSearch`: Enables free text search index. Can be a boolean for default options, or an object for custom configuration.
311
- * - `equality`: Enables equality index. Can be a boolean for default options, or an array of token filters.
312
- * - `orderAndRange`: Enables order and range index for sorting and range queries.
313
- * - `searchableJson`: Enables searchable JSON index for JSONB path queries on encrypted JSON columns.
314
- *
315
- * See {@link EncryptedColumnConfig}.
316
- *
317
- * @example
318
- * Defining a drizzle table schema for postgres table with encrypted columns.
319
- *
320
- * ```typescript
321
- * import { pgTable, integer, timestamp } from 'drizzle-orm/pg-core'
322
- * import { encryptedType } from '@cipherstash/stack/drizzle'
323
- *
324
- * const users = pgTable('users', {
325
- * email: encryptedType('email', {
326
- * freeTextSearch: true,
327
- * equality: true,
328
- * orderAndRange: true,
329
- * }),
330
- * age: encryptedType('age', {
331
- * dataType: 'number',
332
- * equality: true,
333
- * orderAndRange: true,
334
- * }),
335
- * profile: encryptedType('profile', {
336
- * dataType: 'json',
337
- * }),
338
- * })
339
- * ```
340
- */
341
- declare const encryptedType: <TData>(name: string, config?: EncryptedColumnConfig) => drizzle_orm_pg_core.PgCustomColumnBuilder<{
342
- name: string;
343
- dataType: "custom";
344
- columnType: "PgCustomColumn";
345
- data: TData;
346
- driverParam: string;
347
- enumValues: undefined;
348
- }>;
349
- /**
350
- * Get configuration for an encrypted column by checking if it's an encrypted type
351
- * and looking up the config by column name
352
- * @internal
353
- */
354
- declare function getEncryptedColumnConfig(columnName: string, column: unknown): (EncryptedColumnConfig & {
355
- name: string;
356
- }) | undefined;
357
-
358
- export { CastAs, type EncryptedColumnConfig, EncryptionConfigError, EncryptionOperatorError, MatchIndexOpts, TokenFilter, createEncryptionOperators, encryptedType, extractEncryptionSchema, getEncryptedColumnConfig };