@cipherstash/stack 0.19.0 → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/CHANGELOG.md +531 -0
  2. package/README.md +95 -77
  3. package/dist/adapter-kit.cjs +923 -0
  4. package/dist/adapter-kit.cjs.map +1 -0
  5. package/dist/adapter-kit.d.cts +82 -0
  6. package/dist/adapter-kit.d.ts +82 -0
  7. package/dist/adapter-kit.js +47 -0
  8. package/dist/adapter-kit.js.map +1 -0
  9. package/dist/base-operation-AOAIvsSB.d.cts +32 -0
  10. package/dist/base-operation-FXEzUXIq.d.ts +32 -0
  11. package/dist/{chunk-4AVL4VZD.js → chunk-3B5ZX3IS.js} +3 -1
  12. package/dist/chunk-3B5ZX3IS.js.map +1 -0
  13. package/dist/chunk-7333ZC6L.js +48 -0
  14. package/dist/chunk-7333ZC6L.js.map +1 -0
  15. package/dist/{chunk-MP3SSDNN.js → chunk-CLM7E4I6.js} +15 -15
  16. package/dist/{chunk-MP3SSDNN.js.map → chunk-CLM7E4I6.js.map} +1 -1
  17. package/dist/{chunk-U66S7VIF.js → chunk-V2Q3NYIH.js} +166 -107
  18. package/dist/chunk-V2Q3NYIH.js.map +1 -0
  19. package/dist/chunk-X3JRXEIB.js +98 -0
  20. package/dist/chunk-X3JRXEIB.js.map +1 -0
  21. package/dist/{chunk-36AA7IBJ.js → chunk-ZTP5QJ27.js} +51 -18
  22. package/dist/chunk-ZTP5QJ27.js.map +1 -0
  23. package/dist/client.cjs +29 -12
  24. package/dist/client.cjs.map +1 -1
  25. package/dist/client.d.cts +3 -2
  26. package/dist/client.d.ts +3 -2
  27. package/dist/client.js +2 -2
  28. package/dist/{table-DihEAlxG.d.cts → columns-D2_YzrCX.d.cts} +155 -136
  29. package/dist/{table-CIH7jZ2h.d.ts → columns-rZc7fQHI.d.ts} +155 -136
  30. package/dist/dynamodb/index.d.cts +3 -2
  31. package/dist/dynamodb/index.d.ts +3 -2
  32. package/dist/encryption/index.cjs +54 -16
  33. package/dist/encryption/index.cjs.map +1 -1
  34. package/dist/encryption/index.d.cts +807 -6
  35. package/dist/encryption/index.d.ts +807 -6
  36. package/dist/encryption/index.js +4 -4
  37. package/dist/encryption/v3.cjs +1078 -973
  38. package/dist/encryption/v3.cjs.map +1 -1
  39. package/dist/encryption/v3.d.cts +15 -12
  40. package/dist/encryption/v3.d.ts +15 -12
  41. package/dist/encryption/v3.js +49 -21
  42. package/dist/encryption/v3.js.map +1 -1
  43. package/dist/eql/v3/index.cjs +130 -79
  44. package/dist/eql/v3/index.cjs.map +1 -1
  45. package/dist/eql/v3/index.d.cts +115 -13
  46. package/dist/eql/v3/index.d.ts +115 -13
  47. package/dist/eql/v3/index.js +16 -6
  48. package/dist/index-BquA71_Y.d.ts +24 -0
  49. package/dist/index-fhWTOV0K.d.cts +24 -0
  50. package/dist/index.cjs +79 -27
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.d.cts +5 -17
  53. package/dist/index.d.ts +5 -17
  54. package/dist/index.js +4 -4
  55. package/dist/schema/index.cjs +29 -12
  56. package/dist/schema/index.cjs.map +1 -1
  57. package/dist/schema/index.d.cts +1 -1
  58. package/dist/schema/index.d.ts +1 -1
  59. package/dist/schema/index.js +2 -2
  60. package/dist/{types-public-CpS5KjwX.d.ts → types-public-QMjYNfQO.d.cts} +765 -726
  61. package/dist/{types-public-CpS5KjwX.d.cts → types-public-QMjYNfQO.d.ts} +765 -726
  62. package/dist/types-public.cjs.map +1 -1
  63. package/dist/types-public.d.cts +1 -1
  64. package/dist/types-public.d.ts +1 -1
  65. package/dist/types-public.js +1 -1
  66. package/dist/wasm-inline.d.ts +779 -405
  67. package/dist/wasm-inline.js +606 -299
  68. package/dist/wasm-inline.js.map +1 -1
  69. package/package.json +25 -53
  70. package/dist/chunk-36AA7IBJ.js.map +0 -1
  71. package/dist/chunk-4AVL4VZD.js.map +0 -1
  72. package/dist/chunk-IADZCZEA.js +0 -23
  73. package/dist/chunk-IADZCZEA.js.map +0 -1
  74. package/dist/chunk-IBSK6P33.js +0 -209
  75. package/dist/chunk-IBSK6P33.js.map +0 -1
  76. package/dist/chunk-U66S7VIF.js.map +0 -1
  77. package/dist/client-DSGHBN-g.d.cts +0 -834
  78. package/dist/client-DfCrlHXh.d.ts +0 -834
  79. package/dist/drizzle/index.cjs +0 -5617
  80. package/dist/drizzle/index.cjs.map +0 -1
  81. package/dist/drizzle/index.d.cts +0 -358
  82. package/dist/drizzle/index.d.ts +0 -358
  83. package/dist/drizzle/index.js +0 -1220
  84. package/dist/drizzle/index.js.map +0 -1
  85. package/dist/supabase/index.cjs +0 -5951
  86. package/dist/supabase/index.cjs.map +0 -1
  87. package/dist/supabase/index.d.cts +0 -223
  88. package/dist/supabase/index.d.ts +0 -223
  89. package/dist/supabase/index.js +0 -1217
  90. package/dist/supabase/index.js.map +0 -1
@@ -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 { g as EncryptedTable, k as EncryptedColumn, l as CastAs, M as MatchIndexOpts, T as TokenFilter } from '../types-public-CpS5KjwX.js';
4
- import { SQLWrapper, SQL, exists, notExists, isNull, isNotNull, not, arrayContains, arrayContained, arrayOverlaps } from 'drizzle-orm';
5
- import { e as EncryptionClient } from '../client-DfCrlHXh.js';
6
- import '@cipherstash/protect-ffi';
7
- import 'zod';
8
- import '@byteslice/result';
9
- import '../errors/index.js';
10
- import '../identity/index.js';
11
-
12
- /**
13
- * Custom error types for better debugging
14
- */
15
- declare class EncryptionOperatorError extends Error {
16
- readonly context?: {
17
- tableName?: string;
18
- columnName?: string;
19
- operator?: string;
20
- } | undefined;
21
- constructor(message: string, context?: {
22
- tableName?: string;
23
- columnName?: string;
24
- operator?: string;
25
- } | undefined);
26
- }
27
- declare class EncryptionConfigError extends EncryptionOperatorError {
28
- constructor(message: string, context?: EncryptionOperatorError['context']);
29
- }
30
- /**
31
- * Creates a set of encryption-aware operators that automatically encrypt values
32
- * for encrypted columns before using them with Drizzle operators.
33
- *
34
- * For equality and text search operators (eq, ne, like, ilike, inArray, etc.):
35
- * Values are encrypted and then passed to regular Drizzle operators, which use
36
- * PostgreSQL's built-in operators for eql_v2_encrypted types.
37
- *
38
- * For order and range operators (gt, gte, lt, lte, between, notBetween):
39
- * Values are encrypted and then use eql_v2.* functions (eql_v2.gt(), eql_v2.gte(), etc.)
40
- * which are required for ORE (Order-Revealing Encryption) comparisons.
41
- *
42
- * @param encryptionClient - The EncryptionClient instance
43
- * @returns An object with all Drizzle operators wrapped for encrypted columns
44
- *
45
- * @example
46
- * ```ts
47
- * // Initialize operators
48
- * const ops = createEncryptionOperators(encryptionClient)
49
- *
50
- * // Equality search - automatically encrypts and uses PostgreSQL operators
51
- * const results = await db
52
- * .select()
53
- * .from(usersTable)
54
- * .where(await ops.eq(usersTable.email, 'user@example.com'))
55
- *
56
- * // Range query - automatically encrypts and uses eql_v2.gte()
57
- * const olderUsers = await db
58
- * .select()
59
- * .from(usersTable)
60
- * .where(await ops.gte(usersTable.age, 25))
61
- * ```
62
- */
63
- declare function createEncryptionOperators(encryptionClient: EncryptionClient): {
64
- /**
65
- * Equality operator - encrypts value for encrypted columns.
66
- * Requires either `equality` or `orderAndRange` to be set on {@link EncryptedColumnConfig}.
67
- *
68
- * @example
69
- * Select users with a specific email address.
70
- * ```ts
71
- * const condition = await ops.eq(usersTable.email, 'user@example.com')
72
- * const results = await db.select().from(usersTable).where(condition)
73
- * ```
74
- */
75
- eq: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
76
- /**
77
- * Not equal operator - encrypts value for encrypted columns.
78
- * Requires either `equality` or `orderAndRange` to be set on {@link EncryptedColumnConfig}.
79
- *
80
- * @example
81
- * Select users whose email address is not a specific value.
82
- * ```ts
83
- * const condition = await ops.ne(usersTable.email, 'user@example.com')
84
- * const results = await db.select().from(usersTable).where(condition)
85
- * ```
86
- */
87
- ne: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
88
- /**
89
- * Greater than operator for encrypted columns with ORE index.
90
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
91
- *
92
- * @example
93
- * Select users older than a specific age.
94
- * ```ts
95
- * const condition = await ops.gt(usersTable.age, 30)
96
- * const results = await db.select().from(usersTable).where(condition)
97
- * ```
98
- */
99
- gt: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
100
- /**
101
- * Greater than or equal operator for encrypted columns with ORE index.
102
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
103
- *
104
- * @example
105
- * Select users older than or equal to a specific age.
106
- * ```ts
107
- * const condition = await ops.gte(usersTable.age, 30)
108
- * const results = await db.select().from(usersTable).where(condition)
109
- * ```
110
- */
111
- gte: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
112
- /**
113
- * Less than operator for encrypted columns with ORE index.
114
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
115
- *
116
- * @example
117
- * Select users younger than a specific age.
118
- * ```ts
119
- * const condition = await ops.lt(usersTable.age, 30)
120
- * const results = await db.select().from(usersTable).where(condition)
121
- * ```
122
- */
123
- lt: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
124
- /**
125
- * Less than or equal operator for encrypted columns with ORE index.
126
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
127
- *
128
- * @example
129
- * Select users younger than or equal to a specific age.
130
- * ```ts
131
- * const condition = await ops.lte(usersTable.age, 30)
132
- * const results = await db.select().from(usersTable).where(condition)
133
- * ```
134
- */
135
- lte: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
136
- /**
137
- * Between operator for encrypted columns with ORE index.
138
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
139
- *
140
- * @example
141
- * Select users within a specific age range.
142
- * ```ts
143
- * const condition = await ops.between(usersTable.age, 20, 30)
144
- * const results = await db.select().from(usersTable).where(condition)
145
- * ```
146
- */
147
- between: (left: SQLWrapper, min: unknown, max: unknown) => Promise<SQL> | SQL;
148
- /**
149
- * Not between operator for encrypted columns with ORE index.
150
- * Requires `orderAndRange` to be set on {@link EncryptedColumnConfig}.
151
- *
152
- * @example
153
- * Select users outside a specific age range.
154
- * ```ts
155
- * const condition = await ops.notBetween(usersTable.age, 20, 30)
156
- * const results = await db.select().from(usersTable).where(condition)
157
- * ```
158
- */
159
- notBetween: (left: SQLWrapper, min: unknown, max: unknown) => Promise<SQL> | SQL;
160
- /**
161
- * Like operator for encrypted columns with free text search.
162
- * Requires `freeTextSearch` to be set on {@link EncryptedColumnConfig}.
163
- *
164
- * > [!IMPORTANT]
165
- * > Case sensitivity on encrypted columns depends on the {@link EncryptedColumnConfig}.
166
- * > Ensure that the column is configured for case-insensitive search if needed.
167
- *
168
- * @example
169
- * Select users with email addresses matching a pattern.
170
- * ```ts
171
- * const condition = await ops.like(usersTable.email, '%@example.com')
172
- * const results = await db.select().from(usersTable).where(condition)
173
- * ```
174
- */
175
- like: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
176
- /**
177
- * ILike operator for encrypted columns with free text search.
178
- * Requires `freeTextSearch` to be set on {@link EncryptedColumnConfig}.
179
- *
180
- * > [!IMPORTANT]
181
- * > Case sensitivity on encrypted columns depends on the {@link EncryptedColumnConfig}.
182
- * > Ensure that the column is configured for case-insensitive search if needed.
183
- *
184
- * @example
185
- * Select users with email addresses matching a pattern (case-insensitive).
186
- * ```ts
187
- * const condition = await ops.ilike(usersTable.email, '%@example.com')
188
- * const results = await db.select().from(usersTable).where(condition)
189
- * ```
190
- */
191
- ilike: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
192
- notIlike: (left: SQLWrapper, right: unknown) => Promise<SQL> | SQL;
193
- /**
194
- * JSONB path query first operator for encrypted columns with searchable JSON.
195
- * Requires `searchableJson` to be set on {@link EncryptedColumnConfig}.
196
- *
197
- * Encrypts the JSON path selector and calls `eql_v2.jsonb_path_query_first()`,
198
- * casting the parameter to `eql_v2_encrypted`.
199
- *
200
- * @throws {EncryptionOperatorError} If the column does not have `searchableJson` enabled.
201
- */
202
- jsonbPathQueryFirst: (left: SQLWrapper, right: unknown) => Promise<SQL>;
203
- /**
204
- * JSONB get operator for encrypted columns with searchable JSON.
205
- * Requires `searchableJson` to be set on {@link EncryptedColumnConfig}.
206
- *
207
- * Encrypts the JSON path selector and uses the `->` operator,
208
- * casting the parameter to `eql_v2_encrypted`.
209
- *
210
- * @throws {EncryptionOperatorError} If the column does not have `searchableJson` enabled.
211
- */
212
- jsonbGet: (left: SQLWrapper, right: unknown) => Promise<SQL>;
213
- /**
214
- * JSONB path exists operator for encrypted columns with searchable JSON.
215
- * Requires `searchableJson` to be set on {@link EncryptedColumnConfig}.
216
- *
217
- * Encrypts the JSON path selector and calls `eql_v2.jsonb_path_exists()`,
218
- * casting the parameter to `eql_v2_encrypted`.
219
- *
220
- * @throws {EncryptionOperatorError} If the column does not have `searchableJson` enabled.
221
- */
222
- jsonbPathExists: (left: SQLWrapper, right: unknown) => Promise<SQL>;
223
- inArray: (left: SQLWrapper, right: unknown[] | SQLWrapper) => Promise<SQL>;
224
- notInArray: (left: SQLWrapper, right: unknown[] | SQLWrapper) => Promise<SQL>;
225
- asc: (column: SQLWrapper) => SQL;
226
- desc: (column: SQLWrapper) => SQL;
227
- and: (...conditions: (SQL | SQLWrapper | Promise<SQL> | undefined)[]) => Promise<SQL>;
228
- or: (...conditions: (SQL | SQLWrapper | Promise<SQL> | undefined)[]) => Promise<SQL>;
229
- exists: typeof exists;
230
- notExists: typeof notExists;
231
- isNull: typeof isNull;
232
- isNotNull: typeof isNotNull;
233
- not: typeof not;
234
- arrayContains: typeof arrayContains;
235
- arrayContained: typeof arrayContained;
236
- arrayOverlaps: typeof arrayOverlaps;
237
- };
238
-
239
- /**
240
- * Extracts the encrypted column keys from a Drizzle table type.
241
- * Columns created with `encryptedType` are `PgCustomColumn` instances;
242
- * this picks only those keys and maps them to `EncryptedColumn`.
243
- */
244
- type DrizzleEncryptedSchema<T> = {
245
- [K in keyof T as T[K] extends PgCustomColumn<any> ? K : never]: EncryptedColumn;
246
- };
247
- /**
248
- * Extracts an encryption schema from a Drizzle table definition.
249
- * This function identifies columns created with `encryptedType` and
250
- * builds a corresponding `EncryptedTable` with `encryptedColumn` definitions.
251
- *
252
- * @param table - The Drizzle table definition
253
- * @returns A EncryptedTable that can be used with encryption client initialization
254
- *
255
- * @example
256
- * ```ts
257
- * const drizzleUsersTable = pgTable('users', {
258
- * email: encryptedType('email', { freeTextSearch: true, equality: true }),
259
- * age: encryptedType('age', { dataType: 'number', orderAndRange: true }),
260
- * })
261
- *
262
- * const encryptionSchema = extractEncryptionSchema(drizzleUsersTable)
263
- * const client = await createEncryptionClient({ schemas: [encryptionSchema.build()] })
264
- * ```
265
- */
266
- declare function extractEncryptionSchema<T extends PgTable<any>>(table: T): EncryptedTable<DrizzleEncryptedSchema<T>> & DrizzleEncryptedSchema<T>;
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 };