@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,1558 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc2) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/drizzle/index.ts
21
- var drizzle_exports = {};
22
- __export(drizzle_exports, {
23
- EncryptionConfigError: () => EncryptionConfigError,
24
- EncryptionOperatorError: () => EncryptionOperatorError,
25
- createEncryptionOperators: () => createEncryptionOperators,
26
- encryptedType: () => encryptedType,
27
- extractEncryptionSchema: () => extractEncryptionSchema,
28
- getEncryptedColumnConfig: () => getEncryptedColumnConfig
29
- });
30
- module.exports = __toCommonJS(drizzle_exports);
31
- var import_pg_core = require("drizzle-orm/pg-core");
32
-
33
- // src/schema/index.ts
34
- var import_zod = require("zod");
35
- var eqlCastAsEnum = import_zod.z.enum([
36
- "text",
37
- "int",
38
- "small_int",
39
- "big_int",
40
- "real",
41
- "double",
42
- "boolean",
43
- "date",
44
- "jsonb"
45
- ]).default("text");
46
- var castAsEnum = import_zod.z.enum(["bigint", "boolean", "date", "number", "string", "json", "text"]).default("text");
47
- var tokenFilterSchema = import_zod.z.object({
48
- kind: import_zod.z.literal("downcase")
49
- });
50
- var tokenizerSchema = import_zod.z.union([
51
- import_zod.z.object({
52
- kind: import_zod.z.literal("standard")
53
- }),
54
- import_zod.z.object({
55
- kind: import_zod.z.literal("ngram"),
56
- token_length: import_zod.z.number()
57
- })
58
- ]).default({ kind: "ngram", token_length: 3 }).optional();
59
- var oreIndexOptsSchema = import_zod.z.object({});
60
- var uniqueIndexOptsSchema = import_zod.z.object({
61
- token_filters: import_zod.z.array(tokenFilterSchema).default([]).optional()
62
- });
63
- var matchIndexOptsSchema = import_zod.z.object({
64
- tokenizer: tokenizerSchema,
65
- token_filters: import_zod.z.array(tokenFilterSchema).default([]).optional(),
66
- k: import_zod.z.number().default(6).optional(),
67
- m: import_zod.z.number().default(2048).optional(),
68
- include_original: import_zod.z.boolean().default(false).optional()
69
- });
70
- var arrayIndexModeSchema = import_zod.z.union([
71
- import_zod.z.literal("all"),
72
- import_zod.z.literal("none"),
73
- import_zod.z.object({
74
- item: import_zod.z.boolean().optional(),
75
- wildcard: import_zod.z.boolean().optional(),
76
- position: import_zod.z.boolean().optional()
77
- })
78
- ]);
79
- var steVecIndexOptsSchema = import_zod.z.object({
80
- prefix: import_zod.z.string(),
81
- array_index_mode: arrayIndexModeSchema.optional()
82
- });
83
- var indexesSchema = import_zod.z.object({
84
- ore: oreIndexOptsSchema.optional(),
85
- unique: uniqueIndexOptsSchema.optional(),
86
- match: matchIndexOptsSchema.optional(),
87
- ste_vec: steVecIndexOptsSchema.optional()
88
- }).default({});
89
- var columnSchema = import_zod.z.object({
90
- cast_as: castAsEnum,
91
- indexes: indexesSchema
92
- }).default({});
93
- var tableSchema = import_zod.z.record(columnSchema).default({});
94
- var tablesSchema = import_zod.z.record(tableSchema).default({});
95
- var encryptConfigSchema = import_zod.z.object({
96
- v: import_zod.z.number(),
97
- tables: tablesSchema
98
- });
99
- var EncryptedField = class {
100
- valueName;
101
- castAsValue;
102
- constructor(valueName) {
103
- this.valueName = valueName;
104
- this.castAsValue = "string";
105
- }
106
- /**
107
- * Set or override the plaintext data type for this field.
108
- *
109
- * By default all values are treated as `'string'`. Use this method to specify
110
- * a different type so the encryption layer knows how to encode the plaintext
111
- * before encrypting.
112
- *
113
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'text'`, `'bigint'`, or `'json'`.
114
- * @returns This `EncryptedField` instance for method chaining.
115
- *
116
- * @example
117
- * ```typescript
118
- * import { encryptedField } from "@cipherstash/stack/schema"
119
- *
120
- * const age = encryptedField("age").dataType("number")
121
- * ```
122
- */
123
- dataType(castAs) {
124
- this.castAsValue = castAs;
125
- return this;
126
- }
127
- build() {
128
- return {
129
- cast_as: this.castAsValue,
130
- indexes: {}
131
- };
132
- }
133
- getName() {
134
- return this.valueName;
135
- }
136
- };
137
- var EncryptedColumn = class {
138
- columnName;
139
- castAsValue;
140
- indexesValue = {};
141
- constructor(columnName) {
142
- this.columnName = columnName;
143
- this.castAsValue = "string";
144
- }
145
- /**
146
- * Set or override the plaintext data type for this column.
147
- *
148
- * By default all columns are treated as `'string'`. Use this method to specify
149
- * a different type so the encryption layer knows how to encode the plaintext
150
- * before encrypting.
151
- *
152
- * @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
153
- * @returns This `EncryptedColumn` instance for method chaining.
154
- *
155
- * @example
156
- * ```typescript
157
- * import { encryptedColumn } from "@cipherstash/stack/schema"
158
- *
159
- * const dateOfBirth = encryptedColumn("date_of_birth").dataType("date")
160
- * ```
161
- */
162
- dataType(castAs) {
163
- this.castAsValue = castAs;
164
- return this;
165
- }
166
- /**
167
- * Enable Order-Revealing Encryption (ORE) indexing on this column.
168
- *
169
- * ORE allows sorting, comparison, and range queries on encrypted data.
170
- * Use with `encryptQuery` and `queryType: 'orderAndRange'`.
171
- *
172
- * @returns This `EncryptedColumn` instance for method chaining.
173
- *
174
- * @example
175
- * ```typescript
176
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
177
- *
178
- * const users = encryptedTable("users", {
179
- * email: encryptedColumn("email").orderAndRange(),
180
- * })
181
- * ```
182
- */
183
- orderAndRange() {
184
- this.indexesValue.ore = {};
185
- return this;
186
- }
187
- /**
188
- * Enable an exact-match (unique) index on this column.
189
- *
190
- * Allows equality queries on encrypted data. Use with `encryptQuery`
191
- * and `queryType: 'equality'`.
192
- *
193
- * @param tokenFilters - Optional array of token filters (e.g. `[{ kind: 'downcase' }]`).
194
- * When omitted, no token filters are applied.
195
- * @returns This `EncryptedColumn` instance for method chaining.
196
- *
197
- * @example
198
- * ```typescript
199
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
200
- *
201
- * const users = encryptedTable("users", {
202
- * email: encryptedColumn("email").equality(),
203
- * })
204
- * ```
205
- */
206
- equality(tokenFilters) {
207
- this.indexesValue.unique = {
208
- token_filters: tokenFilters ?? []
209
- };
210
- return this;
211
- }
212
- /**
213
- * Enable a full-text / fuzzy search (match) index on this column.
214
- *
215
- * Uses n-gram tokenization by default for substring and fuzzy matching.
216
- * Use with `encryptQuery` and `queryType: 'freeTextSearch'`.
217
- *
218
- * @param opts - Optional match index configuration. Defaults to 3-character ngram
219
- * tokenization with a downcase filter, `k=6`, `m=2048`, and `include_original=true`.
220
- * @returns This `EncryptedColumn` instance for method chaining.
221
- *
222
- * @example
223
- * ```typescript
224
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
225
- *
226
- * const users = encryptedTable("users", {
227
- * email: encryptedColumn("email").freeTextSearch(),
228
- * })
229
- *
230
- * // With custom options
231
- * const posts = encryptedTable("posts", {
232
- * body: encryptedColumn("body").freeTextSearch({
233
- * tokenizer: { kind: "ngram", token_length: 4 },
234
- * k: 8,
235
- * m: 4096,
236
- * }),
237
- * })
238
- * ```
239
- */
240
- freeTextSearch(opts) {
241
- this.indexesValue.match = {
242
- tokenizer: opts?.tokenizer ?? { kind: "ngram", token_length: 3 },
243
- token_filters: opts?.token_filters ?? [
244
- {
245
- kind: "downcase"
246
- }
247
- ],
248
- k: opts?.k ?? 6,
249
- m: opts?.m ?? 2048,
250
- include_original: opts?.include_original ?? true
251
- };
252
- return this;
253
- }
254
- /**
255
- * Configure this column for searchable encrypted JSON (STE-Vec).
256
- *
257
- * Enables encrypted JSONPath selector queries (e.g. `'$.user.email'`) and
258
- * containment queries (e.g. `{ role: 'admin' }`). Automatically sets the
259
- * data type to `'json'`.
260
- *
261
- * When used with `encryptQuery`, the query operation is auto-inferred from
262
- * the plaintext type: strings become selector queries, objects/arrays become
263
- * containment queries.
264
- *
265
- * @returns This `EncryptedColumn` instance for method chaining.
266
- *
267
- * @example
268
- * ```typescript
269
- * import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
270
- *
271
- * const documents = encryptedTable("documents", {
272
- * metadata: encryptedColumn("metadata").searchableJson(),
273
- * })
274
- * ```
275
- */
276
- searchableJson() {
277
- this.castAsValue = "json";
278
- this.indexesValue.ste_vec = { prefix: "enabled", array_index_mode: "all" };
279
- return this;
280
- }
281
- build() {
282
- return {
283
- cast_as: this.castAsValue,
284
- indexes: this.indexesValue
285
- };
286
- }
287
- getName() {
288
- return this.columnName;
289
- }
290
- };
291
- var EncryptedTable = class {
292
- constructor(tableName, columnBuilders) {
293
- this.tableName = tableName;
294
- this.columnBuilders = columnBuilders;
295
- }
296
- tableName;
297
- columnBuilders;
298
- /**
299
- * Compile this table schema into a `TableDefinition` used internally by the encryption client.
300
- *
301
- * Iterates over all column builders, calls `.build()` on each, and assembles
302
- * the final `{ tableName, columns }` structure. For `searchableJson()` columns,
303
- * the STE-Vec prefix is automatically set to `"<tableName>/<columnName>"`.
304
- *
305
- * @returns A `TableDefinition` containing the table name and built column configs.
306
- *
307
- * @example
308
- * ```typescript
309
- * const users = encryptedTable("users", {
310
- * email: encryptedColumn("email").equality(),
311
- * })
312
- *
313
- * const definition = users.build()
314
- * // { tableName: "users", columns: { email: { cast_as: "string", indexes: { unique: ... } } } }
315
- * ```
316
- */
317
- build() {
318
- const builtColumns = {};
319
- const processColumn = (builder, colName) => {
320
- if (builder instanceof EncryptedColumn) {
321
- const builtColumn = builder.build();
322
- if (builtColumn.cast_as === "json" && builtColumn.indexes.ste_vec?.prefix === "enabled") {
323
- builtColumns[colName] = {
324
- ...builtColumn,
325
- indexes: {
326
- ...builtColumn.indexes,
327
- ste_vec: {
328
- ...builtColumn.indexes.ste_vec,
329
- prefix: `${this.tableName}/${colName}`
330
- }
331
- }
332
- };
333
- } else {
334
- builtColumns[colName] = builtColumn;
335
- }
336
- } else {
337
- for (const [key, value] of Object.entries(builder)) {
338
- if (value instanceof EncryptedField) {
339
- builtColumns[value.getName()] = value.build();
340
- } else {
341
- processColumn(value, key);
342
- }
343
- }
344
- }
345
- };
346
- for (const [colName, builder] of Object.entries(this.columnBuilders)) {
347
- processColumn(builder, colName);
348
- }
349
- return {
350
- tableName: this.tableName,
351
- columns: builtColumns
352
- };
353
- }
354
- };
355
- function encryptedTable(tableName, columns) {
356
- const tableBuilder = new EncryptedTable(
357
- tableName,
358
- columns
359
- );
360
- for (const [colName, colBuilder] of Object.entries(columns)) {
361
- ;
362
- tableBuilder[colName] = colBuilder;
363
- }
364
- return tableBuilder;
365
- }
366
- function encryptedColumn(columnName) {
367
- return new EncryptedColumn(columnName);
368
- }
369
-
370
- // src/drizzle/schema-extraction.ts
371
- function extractEncryptionSchema(table) {
372
- const tableName = table[/* @__PURE__ */ Symbol.for("drizzle:Name")];
373
- if (!tableName) {
374
- throw new Error(
375
- "Unable to extract table name from Drizzle table. Ensure you are using a table created with pgTable()."
376
- );
377
- }
378
- const columns = {};
379
- for (const [columnName, column] of Object.entries(table)) {
380
- if (typeof column !== "object" || column === null) {
381
- continue;
382
- }
383
- const config = getEncryptedColumnConfig(columnName, column);
384
- if (config) {
385
- const actualColumnName = column.name || config.name;
386
- const csCol = encryptedColumn(actualColumnName);
387
- if (config.dataType && config.dataType !== "string") {
388
- csCol.dataType(config.dataType);
389
- }
390
- if (config.orderAndRange) {
391
- csCol.orderAndRange();
392
- }
393
- if (config.equality) {
394
- if (Array.isArray(config.equality)) {
395
- csCol.equality(config.equality);
396
- } else {
397
- csCol.equality();
398
- }
399
- }
400
- if (config.freeTextSearch) {
401
- if (typeof config.freeTextSearch === "object") {
402
- csCol.freeTextSearch(config.freeTextSearch);
403
- } else {
404
- csCol.freeTextSearch();
405
- }
406
- }
407
- if (config.searchableJson) {
408
- if (config.dataType !== "json") {
409
- throw new Error(
410
- `Column "${columnName}" has searchableJson enabled but dataType is "${config.dataType ?? "string"}". searchableJson requires dataType: 'json'.`
411
- );
412
- }
413
- csCol.searchableJson();
414
- }
415
- columns[actualColumnName] = csCol;
416
- }
417
- }
418
- if (Object.keys(columns).length === 0) {
419
- throw new Error(
420
- `No encrypted columns found in table "${tableName}". Use encryptedType() to define encrypted columns.`
421
- );
422
- }
423
- return encryptedTable(tableName, columns);
424
- }
425
-
426
- // src/types.ts
427
- var queryTypes = {
428
- orderAndRange: "orderAndRange",
429
- freeTextSearch: "freeTextSearch",
430
- equality: "equality",
431
- steVecSelector: "steVecSelector",
432
- steVecTerm: "steVecTerm",
433
- searchableJson: "searchableJson"
434
- };
435
-
436
- // src/drizzle/operators.ts
437
- var import_drizzle_orm = require("drizzle-orm");
438
- var import_drizzle_orm2 = require("drizzle-orm");
439
- function isSQLWrapper(value) {
440
- return typeof value === "object" && value !== null && "sql" in value && typeof value.sql !== "undefined";
441
- }
442
- function isPgTable(value) {
443
- return typeof value === "object" && value !== null && /* @__PURE__ */ Symbol.for("drizzle:Name") in value;
444
- }
445
- var EncryptionOperatorError = class extends Error {
446
- constructor(message, context) {
447
- super(message);
448
- this.context = context;
449
- this.name = "EncryptionOperatorError";
450
- }
451
- context;
452
- };
453
- var EncryptionConfigError = class extends EncryptionOperatorError {
454
- constructor(message, context) {
455
- super(message, context);
456
- this.name = "EncryptionConfigError";
457
- }
458
- };
459
- function getDrizzleTableName(drizzleTable) {
460
- if (!isPgTable(drizzleTable)) {
461
- return void 0;
462
- }
463
- const tableWithSymbol = drizzleTable;
464
- return tableWithSymbol[/* @__PURE__ */ Symbol.for("drizzle:Name")];
465
- }
466
- function getDrizzleTableFromColumn(drizzleColumn) {
467
- const column = drizzleColumn;
468
- return column.table;
469
- }
470
- function getEncryptedTableFromColumn(drizzleColumn, tableCache) {
471
- const drizzleTable = getDrizzleTableFromColumn(drizzleColumn);
472
- if (!drizzleTable) {
473
- return void 0;
474
- }
475
- const tableName = getDrizzleTableName(drizzleTable);
476
- if (!tableName) {
477
- return void 0;
478
- }
479
- let encryptedTable2 = tableCache.get(tableName);
480
- if (encryptedTable2) {
481
- return encryptedTable2;
482
- }
483
- try {
484
- encryptedTable2 = extractEncryptionSchema(drizzleTable);
485
- tableCache.set(tableName, encryptedTable2);
486
- return encryptedTable2;
487
- } catch {
488
- return void 0;
489
- }
490
- }
491
- function getEncryptedColumn(drizzleColumn, encryptedTable2) {
492
- const column = drizzleColumn;
493
- const columnName = column.name;
494
- if (!columnName) {
495
- return void 0;
496
- }
497
- const tableRecord = encryptedTable2;
498
- return tableRecord[columnName];
499
- }
500
- function getColumnInfo(drizzleColumn, encryptedTable2, tableCache) {
501
- const column = drizzleColumn;
502
- const columnName = column.name || "unknown";
503
- let resolvedTable = encryptedTable2;
504
- if (!resolvedTable) {
505
- resolvedTable = getEncryptedTableFromColumn(drizzleColumn, tableCache);
506
- }
507
- const drizzleTable = getDrizzleTableFromColumn(drizzleColumn);
508
- const tableName = getDrizzleTableName(drizzleTable);
509
- if (!resolvedTable) {
510
- const config2 = getEncryptedColumnConfig(columnName, drizzleColumn);
511
- return {
512
- encryptedColumn: void 0,
513
- config: config2,
514
- encryptedTable: void 0,
515
- columnName,
516
- tableName
517
- };
518
- }
519
- const encryptedColumn2 = getEncryptedColumn(drizzleColumn, resolvedTable);
520
- const config = getEncryptedColumnConfig(columnName, drizzleColumn);
521
- return {
522
- encryptedColumn: encryptedColumn2,
523
- config,
524
- encryptedTable: resolvedTable,
525
- columnName,
526
- tableName
527
- };
528
- }
529
- function toPlaintext(value) {
530
- if (typeof value === "boolean") {
531
- return value ? 1 : 0;
532
- }
533
- if (typeof value === "string" || typeof value === "number") {
534
- return value;
535
- }
536
- if (value instanceof Date) {
537
- return value.toISOString();
538
- }
539
- return String(value);
540
- }
541
- async function encryptValues(encryptionClient, values, encryptedTable2, tableCache) {
542
- if (values.length === 0) {
543
- return [];
544
- }
545
- const valuesToEncrypt = [];
546
- const results = new Array(values.length);
547
- for (let i = 0; i < values.length; i++) {
548
- const { value, column, queryType } = values[i];
549
- const columnInfo = getColumnInfo(column, encryptedTable2, tableCache);
550
- if (!columnInfo.encryptedColumn || !columnInfo.config || !columnInfo.encryptedTable) {
551
- results[i] = value;
552
- continue;
553
- }
554
- const plaintextValue = toPlaintext(value);
555
- valuesToEncrypt.push({
556
- value: plaintextValue,
557
- column,
558
- columnInfo,
559
- queryType,
560
- originalIndex: i
561
- });
562
- }
563
- if (valuesToEncrypt.length === 0) {
564
- return results;
565
- }
566
- const columnGroups = /* @__PURE__ */ new Map();
567
- let valueIndex = 0;
568
- for (const {
569
- value,
570
- columnInfo,
571
- queryType,
572
- originalIndex
573
- } of valuesToEncrypt) {
574
- if (!columnInfo.config || !columnInfo.encryptedColumn || !columnInfo.encryptedTable) {
575
- continue;
576
- }
577
- const columnName = columnInfo.config.name;
578
- const groupKey = `${columnInfo.tableName ?? "unknown"}/${columnName}`;
579
- let group = columnGroups.get(groupKey);
580
- if (!group) {
581
- group = {
582
- column: columnInfo.encryptedColumn,
583
- table: columnInfo.encryptedTable,
584
- columnName,
585
- values: [],
586
- resultIndices: []
587
- };
588
- columnGroups.set(groupKey, group);
589
- }
590
- group.values.push({ value, index: valueIndex++, queryType });
591
- group.resultIndices.push(originalIndex);
592
- }
593
- for (const [, group] of columnGroups) {
594
- const { columnName } = group;
595
- try {
596
- const terms = group.values.map((v) => ({
597
- value: v.value,
598
- column: group.column,
599
- table: group.table,
600
- queryType: v.queryType
601
- }));
602
- const encryptedTerms = await encryptionClient.encryptQuery(terms);
603
- if (encryptedTerms.failure) {
604
- throw new EncryptionOperatorError(
605
- `Failed to encrypt query terms for column "${columnName}": ${encryptedTerms.failure.message}`,
606
- { columnName }
607
- );
608
- }
609
- for (let i = 0; i < group.values.length; i++) {
610
- const resultIndex = group.resultIndices[i] ?? -1;
611
- if (resultIndex >= 0 && resultIndex < results.length) {
612
- results[resultIndex] = encryptedTerms.data[i];
613
- }
614
- }
615
- } catch (error) {
616
- if (error instanceof EncryptionOperatorError) {
617
- throw error;
618
- }
619
- const errorMessage = error instanceof Error ? error.message : String(error);
620
- throw new EncryptionOperatorError(
621
- `Unexpected error encrypting values for column "${columnName}": ${errorMessage}`,
622
- { columnName }
623
- );
624
- }
625
- }
626
- return results;
627
- }
628
- async function encryptValue(encryptionClient, value, drizzleColumn, encryptedTable2, tableCache, queryType) {
629
- const results = await encryptValues(
630
- encryptionClient,
631
- [{ value, column: drizzleColumn, queryType }],
632
- encryptedTable2,
633
- tableCache
634
- );
635
- return results[0];
636
- }
637
- function isLazyOperator(value) {
638
- return typeof value === "object" && value !== null && "__isLazyOperator" in value && value.__isLazyOperator === true;
639
- }
640
- function createLazyOperator(operator, left, right, execute, needsEncryption, columnInfo, encryptionClient, defaultTable, tableCache, min, max, queryType) {
641
- let resolvedSQL;
642
- let encryptionPromise;
643
- const lazyOp = {
644
- __isLazyOperator: true,
645
- operator,
646
- queryType,
647
- left,
648
- right,
649
- min,
650
- max,
651
- needsEncryption,
652
- columnInfo,
653
- execute
654
- };
655
- const promise = new Promise((resolve, reject) => {
656
- queueMicrotask(async () => {
657
- if (resolvedSQL !== void 0) {
658
- resolve(resolvedSQL);
659
- return;
660
- }
661
- try {
662
- if (!encryptionPromise) {
663
- encryptionPromise = executeLazyOperatorDirect(
664
- lazyOp,
665
- encryptionClient,
666
- defaultTable,
667
- tableCache
668
- );
669
- }
670
- const sql2 = await encryptionPromise;
671
- resolvedSQL = sql2;
672
- resolve(sql2);
673
- } catch (error) {
674
- reject(error);
675
- }
676
- });
677
- });
678
- return Object.assign(promise, lazyOp);
679
- }
680
- async function executeLazyOperator(lazyOp, encryptedValues) {
681
- if (!lazyOp.needsEncryption) {
682
- return lazyOp.execute(lazyOp.right);
683
- }
684
- if (lazyOp.min !== void 0 && lazyOp.max !== void 0) {
685
- let encryptedMin;
686
- let encryptedMax;
687
- if (encryptedValues && encryptedValues.length >= 2) {
688
- encryptedMin = encryptedValues[0]?.encrypted;
689
- encryptedMax = encryptedValues[1]?.encrypted;
690
- } else {
691
- throw new EncryptionOperatorError(
692
- "Between operator requires both min and max encrypted values",
693
- {
694
- columnName: lazyOp.columnInfo.columnName,
695
- tableName: lazyOp.columnInfo.tableName,
696
- operator: lazyOp.operator
697
- }
698
- );
699
- }
700
- if (encryptedMin === void 0 || encryptedMax === void 0) {
701
- throw new EncryptionOperatorError(
702
- "Between operator requires both min and max values to be encrypted",
703
- {
704
- columnName: lazyOp.columnInfo.columnName,
705
- tableName: lazyOp.columnInfo.tableName,
706
- operator: lazyOp.operator
707
- }
708
- );
709
- }
710
- return lazyOp.execute(void 0, encryptedMin, encryptedMax);
711
- }
712
- let encrypted;
713
- if (encryptedValues && encryptedValues.length > 0) {
714
- encrypted = encryptedValues[0]?.encrypted;
715
- } else {
716
- throw new EncryptionOperatorError(
717
- "Operator requires encrypted value but none provided",
718
- {
719
- columnName: lazyOp.columnInfo.columnName,
720
- tableName: lazyOp.columnInfo.tableName,
721
- operator: lazyOp.operator
722
- }
723
- );
724
- }
725
- if (encrypted === void 0) {
726
- throw new EncryptionOperatorError(
727
- "Encryption failed or value was not encrypted",
728
- {
729
- columnName: lazyOp.columnInfo.columnName,
730
- tableName: lazyOp.columnInfo.tableName,
731
- operator: lazyOp.operator
732
- }
733
- );
734
- }
735
- return lazyOp.execute(encrypted);
736
- }
737
- async function executeLazyOperatorDirect(lazyOp, encryptionClient, defaultTable, tableCache) {
738
- if (!lazyOp.needsEncryption) {
739
- return lazyOp.execute(lazyOp.right);
740
- }
741
- if (lazyOp.min !== void 0 && lazyOp.max !== void 0) {
742
- const [encryptedMin, encryptedMax] = await encryptValues(
743
- encryptionClient,
744
- [
745
- { value: lazyOp.min, column: lazyOp.left, queryType: lazyOp.queryType },
746
- { value: lazyOp.max, column: lazyOp.left, queryType: lazyOp.queryType }
747
- ],
748
- defaultTable,
749
- tableCache
750
- );
751
- return lazyOp.execute(void 0, encryptedMin, encryptedMax);
752
- }
753
- const encrypted = await encryptValue(
754
- encryptionClient,
755
- lazyOp.right,
756
- lazyOp.left,
757
- defaultTable,
758
- tableCache,
759
- lazyOp.queryType
760
- );
761
- return lazyOp.execute(encrypted);
762
- }
763
- function createComparisonOperator(operator, left, right, columnInfo, encryptionClient, defaultTable, tableCache) {
764
- const { config } = columnInfo;
765
- const requiresOrderAndRange = ["gt", "gte", "lt", "lte"].includes(operator);
766
- if (requiresOrderAndRange) {
767
- if (!config?.orderAndRange) {
768
- switch (operator) {
769
- case "gt":
770
- return (0, import_drizzle_orm.gt)(left, right);
771
- case "gte":
772
- return (0, import_drizzle_orm.gte)(left, right);
773
- case "lt":
774
- return (0, import_drizzle_orm.lt)(left, right);
775
- case "lte":
776
- return (0, import_drizzle_orm.lte)(left, right);
777
- }
778
- }
779
- const executeFn = (encrypted) => {
780
- if (encrypted === void 0) {
781
- throw new EncryptionOperatorError(
782
- `Encryption failed for ${operator} operator`,
783
- {
784
- columnName: columnInfo.columnName,
785
- tableName: columnInfo.tableName,
786
- operator
787
- }
788
- );
789
- }
790
- return import_drizzle_orm2.sql`eql_v2.${import_drizzle_orm2.sql.raw(operator)}(${left}, ${(0, import_drizzle_orm2.bindIfParam)(encrypted, left)})`;
791
- };
792
- return createLazyOperator(
793
- operator,
794
- left,
795
- right,
796
- executeFn,
797
- true,
798
- columnInfo,
799
- encryptionClient,
800
- defaultTable,
801
- tableCache,
802
- void 0,
803
- // min
804
- void 0,
805
- // max
806
- queryTypes.orderAndRange
807
- );
808
- }
809
- const requiresEquality = ["eq", "ne"].includes(operator);
810
- if (requiresEquality && config?.equality) {
811
- const executeFn = (encrypted) => {
812
- if (encrypted === void 0) {
813
- throw new EncryptionOperatorError(
814
- `Encryption failed for ${operator} operator`,
815
- {
816
- columnName: columnInfo.columnName,
817
- tableName: columnInfo.tableName,
818
- operator
819
- }
820
- );
821
- }
822
- return operator === "eq" ? (0, import_drizzle_orm.eq)(left, encrypted) : (0, import_drizzle_orm.ne)(left, encrypted);
823
- };
824
- return createLazyOperator(
825
- operator,
826
- left,
827
- right,
828
- executeFn,
829
- true,
830
- columnInfo,
831
- encryptionClient,
832
- defaultTable,
833
- tableCache,
834
- void 0,
835
- // min
836
- void 0,
837
- // max
838
- queryTypes.equality
839
- );
840
- }
841
- return operator === "eq" ? (0, import_drizzle_orm.eq)(left, right) : (0, import_drizzle_orm.ne)(left, right);
842
- }
843
- function createRangeOperator(operator, left, min, max, columnInfo, encryptionClient, defaultTable, tableCache) {
844
- const { config } = columnInfo;
845
- if (!config?.orderAndRange) {
846
- return operator === "between" ? (0, import_drizzle_orm.between)(left, min, max) : (0, import_drizzle_orm.notBetween)(left, min, max);
847
- }
848
- const executeFn = (_encrypted, encryptedMin, encryptedMax) => {
849
- if (encryptedMin === void 0 || encryptedMax === void 0) {
850
- throw new EncryptionOperatorError(
851
- `${operator} operator requires both min and max values`,
852
- {
853
- columnName: columnInfo.columnName,
854
- tableName: columnInfo.tableName,
855
- operator
856
- }
857
- );
858
- }
859
- const rangeCondition = import_drizzle_orm2.sql`eql_v2.gte(${left}, ${(0, import_drizzle_orm2.bindIfParam)(encryptedMin, left)}) AND eql_v2.lte(${left}, ${(0, import_drizzle_orm2.bindIfParam)(encryptedMax, left)})`;
860
- return operator === "between" ? rangeCondition : import_drizzle_orm2.sql`NOT (${rangeCondition})`;
861
- };
862
- return createLazyOperator(
863
- operator,
864
- left,
865
- void 0,
866
- executeFn,
867
- true,
868
- columnInfo,
869
- encryptionClient,
870
- defaultTable,
871
- tableCache,
872
- min,
873
- max,
874
- queryTypes.orderAndRange
875
- );
876
- }
877
- function createTextSearchOperator(operator, left, right, columnInfo, encryptionClient, defaultTable, tableCache) {
878
- const { config } = columnInfo;
879
- if (!config?.freeTextSearch) {
880
- const rightValue = right;
881
- switch (operator) {
882
- case "like":
883
- return (0, import_drizzle_orm.like)(left, rightValue);
884
- case "ilike":
885
- return (0, import_drizzle_orm.ilike)(left, rightValue);
886
- case "notIlike":
887
- return (0, import_drizzle_orm.notIlike)(left, rightValue);
888
- }
889
- }
890
- const executeFn = (encrypted) => {
891
- if (encrypted === void 0) {
892
- throw new EncryptionOperatorError(
893
- `Encryption failed for ${operator} operator`,
894
- {
895
- columnName: columnInfo.columnName,
896
- tableName: columnInfo.tableName,
897
- operator
898
- }
899
- );
900
- }
901
- const sqlFn = import_drizzle_orm2.sql`eql_v2.${import_drizzle_orm2.sql.raw(operator === "notIlike" ? "ilike" : operator)}(${left}, ${(0, import_drizzle_orm2.bindIfParam)(encrypted, left)})`;
902
- return operator === "notIlike" ? import_drizzle_orm2.sql`NOT (${sqlFn})` : sqlFn;
903
- };
904
- return createLazyOperator(
905
- operator,
906
- left,
907
- right,
908
- executeFn,
909
- true,
910
- columnInfo,
911
- encryptionClient,
912
- defaultTable,
913
- tableCache,
914
- void 0,
915
- // min
916
- void 0,
917
- // max
918
- queryTypes.freeTextSearch
919
- );
920
- }
921
- function createJsonbOperator(operator, left, right, columnInfo, encryptionClient, defaultTable, tableCache) {
922
- const { config } = columnInfo;
923
- const encryptedSelector = (value) => import_drizzle_orm2.sql`${(0, import_drizzle_orm2.bindIfParam)(value, left)}::eql_v2_encrypted`;
924
- if (!config?.searchableJson) {
925
- throw new EncryptionOperatorError(
926
- `The ${operator} operator requires searchableJson to be enabled on the column configuration.`,
927
- {
928
- columnName: columnInfo.columnName,
929
- tableName: columnInfo.tableName,
930
- operator
931
- }
932
- );
933
- }
934
- const executeFn = (encrypted) => {
935
- if (encrypted === void 0) {
936
- throw new EncryptionOperatorError(
937
- `Encryption failed for ${operator} operator`,
938
- {
939
- columnName: columnInfo.columnName,
940
- tableName: columnInfo.tableName,
941
- operator
942
- }
943
- );
944
- }
945
- switch (operator) {
946
- case "jsonbPathQueryFirst":
947
- return import_drizzle_orm2.sql`eql_v2.jsonb_path_query_first(${left}, ${encryptedSelector(encrypted)})`;
948
- case "jsonbGet":
949
- return import_drizzle_orm2.sql`${left} -> ${encryptedSelector(encrypted)}`;
950
- case "jsonbPathExists":
951
- return import_drizzle_orm2.sql`eql_v2.jsonb_path_exists(${left}, ${encryptedSelector(encrypted)})`;
952
- }
953
- };
954
- return createLazyOperator(
955
- operator,
956
- left,
957
- right,
958
- executeFn,
959
- true,
960
- columnInfo,
961
- encryptionClient,
962
- defaultTable,
963
- tableCache,
964
- void 0,
965
- void 0,
966
- queryTypes.steVecSelector
967
- );
968
- }
969
- function createEncryptionOperators(encryptionClient) {
970
- const tableCache = /* @__PURE__ */ new Map();
971
- const defaultTable = void 0;
972
- const encryptedEq = (left, right) => {
973
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
974
- return createComparisonOperator(
975
- "eq",
976
- left,
977
- right,
978
- columnInfo,
979
- encryptionClient,
980
- defaultTable,
981
- tableCache
982
- );
983
- };
984
- const encryptedNe = (left, right) => {
985
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
986
- return createComparisonOperator(
987
- "ne",
988
- left,
989
- right,
990
- columnInfo,
991
- encryptionClient,
992
- defaultTable,
993
- tableCache
994
- );
995
- };
996
- const encryptedGt = (left, right) => {
997
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
998
- return createComparisonOperator(
999
- "gt",
1000
- left,
1001
- right,
1002
- columnInfo,
1003
- encryptionClient,
1004
- defaultTable,
1005
- tableCache
1006
- );
1007
- };
1008
- const encryptedGte = (left, right) => {
1009
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1010
- return createComparisonOperator(
1011
- "gte",
1012
- left,
1013
- right,
1014
- columnInfo,
1015
- encryptionClient,
1016
- defaultTable,
1017
- tableCache
1018
- );
1019
- };
1020
- const encryptedLt = (left, right) => {
1021
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1022
- return createComparisonOperator(
1023
- "lt",
1024
- left,
1025
- right,
1026
- columnInfo,
1027
- encryptionClient,
1028
- defaultTable,
1029
- tableCache
1030
- );
1031
- };
1032
- const encryptedLte = (left, right) => {
1033
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1034
- return createComparisonOperator(
1035
- "lte",
1036
- left,
1037
- right,
1038
- columnInfo,
1039
- encryptionClient,
1040
- defaultTable,
1041
- tableCache
1042
- );
1043
- };
1044
- const encryptedBetween = (left, min, max) => {
1045
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1046
- return createRangeOperator(
1047
- "between",
1048
- left,
1049
- min,
1050
- max,
1051
- columnInfo,
1052
- encryptionClient,
1053
- defaultTable,
1054
- tableCache
1055
- );
1056
- };
1057
- const encryptedNotBetween = (left, min, max) => {
1058
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1059
- return createRangeOperator(
1060
- "notBetween",
1061
- left,
1062
- min,
1063
- max,
1064
- columnInfo,
1065
- encryptionClient,
1066
- defaultTable,
1067
- tableCache
1068
- );
1069
- };
1070
- const encryptedLike = (left, right) => {
1071
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1072
- return createTextSearchOperator(
1073
- "like",
1074
- left,
1075
- right,
1076
- columnInfo,
1077
- encryptionClient,
1078
- defaultTable,
1079
- tableCache
1080
- );
1081
- };
1082
- const encryptedIlike = (left, right) => {
1083
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1084
- return createTextSearchOperator(
1085
- "ilike",
1086
- left,
1087
- right,
1088
- columnInfo,
1089
- encryptionClient,
1090
- defaultTable,
1091
- tableCache
1092
- );
1093
- };
1094
- const encryptedNotIlike = (left, right) => {
1095
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1096
- return createTextSearchOperator(
1097
- "notIlike",
1098
- left,
1099
- right,
1100
- columnInfo,
1101
- encryptionClient,
1102
- defaultTable,
1103
- tableCache
1104
- );
1105
- };
1106
- const encryptedJsonbPathQueryFirst = (left, right) => {
1107
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1108
- return createJsonbOperator(
1109
- "jsonbPathQueryFirst",
1110
- left,
1111
- right,
1112
- columnInfo,
1113
- encryptionClient,
1114
- defaultTable,
1115
- tableCache
1116
- );
1117
- };
1118
- const encryptedJsonbGet = (left, right) => {
1119
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1120
- return createJsonbOperator(
1121
- "jsonbGet",
1122
- left,
1123
- right,
1124
- columnInfo,
1125
- encryptionClient,
1126
- defaultTable,
1127
- tableCache
1128
- );
1129
- };
1130
- const encryptedJsonbPathExists = (left, right) => {
1131
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1132
- return createJsonbOperator(
1133
- "jsonbPathExists",
1134
- left,
1135
- right,
1136
- columnInfo,
1137
- encryptionClient,
1138
- defaultTable,
1139
- tableCache
1140
- );
1141
- };
1142
- const encryptedInArray = async (left, right) => {
1143
- if (isSQLWrapper(right)) {
1144
- return (0, import_drizzle_orm.inArray)(left, right);
1145
- }
1146
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1147
- if (!columnInfo.config?.equality || !Array.isArray(right)) {
1148
- return (0, import_drizzle_orm.inArray)(left, right);
1149
- }
1150
- const encryptedValues = await encryptValues(
1151
- encryptionClient,
1152
- right.map((value) => ({
1153
- value,
1154
- column: left,
1155
- queryType: queryTypes.equality
1156
- })),
1157
- defaultTable,
1158
- tableCache
1159
- );
1160
- const conditions = encryptedValues.filter((encrypted) => encrypted !== void 0).map((encrypted) => (0, import_drizzle_orm.eq)(left, encrypted));
1161
- if (conditions.length === 0) {
1162
- return import_drizzle_orm2.sql`false`;
1163
- }
1164
- const combined = (0, import_drizzle_orm.or)(...conditions);
1165
- return combined ?? import_drizzle_orm2.sql`false`;
1166
- };
1167
- const encryptedNotInArray = async (left, right) => {
1168
- if (isSQLWrapper(right)) {
1169
- return (0, import_drizzle_orm.notInArray)(
1170
- left,
1171
- right
1172
- );
1173
- }
1174
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
1175
- if (!columnInfo.config?.equality || !Array.isArray(right)) {
1176
- return (0, import_drizzle_orm.notInArray)(left, right);
1177
- }
1178
- const encryptedValues = await encryptValues(
1179
- encryptionClient,
1180
- right.map((value) => ({
1181
- value,
1182
- column: left,
1183
- queryType: queryTypes.equality
1184
- })),
1185
- defaultTable,
1186
- tableCache
1187
- );
1188
- const conditions = encryptedValues.filter((encrypted) => encrypted !== void 0).map((encrypted) => (0, import_drizzle_orm.ne)(left, encrypted));
1189
- if (conditions.length === 0) {
1190
- return import_drizzle_orm2.sql`true`;
1191
- }
1192
- const combined = (0, import_drizzle_orm.and)(...conditions);
1193
- return combined ?? import_drizzle_orm2.sql`true`;
1194
- };
1195
- const encryptedAsc = (column) => {
1196
- const columnInfo = getColumnInfo(column, defaultTable, tableCache);
1197
- if (columnInfo.config?.orderAndRange) {
1198
- return (0, import_drizzle_orm.asc)(import_drizzle_orm2.sql`eql_v2.order_by(${column})`);
1199
- }
1200
- return (0, import_drizzle_orm.asc)(column);
1201
- };
1202
- const encryptedDesc = (column) => {
1203
- const columnInfo = getColumnInfo(column, defaultTable, tableCache);
1204
- if (columnInfo.config?.orderAndRange) {
1205
- return (0, import_drizzle_orm.desc)(import_drizzle_orm2.sql`eql_v2.order_by(${column})`);
1206
- }
1207
- return (0, import_drizzle_orm.desc)(column);
1208
- };
1209
- const encryptedAnd = async (...conditions) => {
1210
- const lazyOperators = [];
1211
- const regularConditions = [];
1212
- const regularPromises = [];
1213
- for (const condition of conditions) {
1214
- if (condition === void 0) {
1215
- continue;
1216
- }
1217
- if (isLazyOperator(condition)) {
1218
- lazyOperators.push(condition);
1219
- } else if (condition instanceof Promise) {
1220
- if (isLazyOperator(condition)) {
1221
- lazyOperators.push(condition);
1222
- } else {
1223
- regularPromises.push(condition);
1224
- }
1225
- } else {
1226
- regularConditions.push(condition);
1227
- }
1228
- }
1229
- if (lazyOperators.length === 0) {
1230
- const allConditions2 = [
1231
- ...regularConditions,
1232
- ...await Promise.all(regularPromises)
1233
- ];
1234
- return (0, import_drizzle_orm.and)(...allConditions2) ?? import_drizzle_orm2.sql`true`;
1235
- }
1236
- const valuesToEncrypt = [];
1237
- for (let i = 0; i < lazyOperators.length; i++) {
1238
- const lazyOp = lazyOperators[i];
1239
- if (!lazyOp.needsEncryption) {
1240
- continue;
1241
- }
1242
- if (lazyOp.min !== void 0 && lazyOp.max !== void 0) {
1243
- valuesToEncrypt.push({
1244
- value: lazyOp.min,
1245
- column: lazyOp.left,
1246
- columnInfo: lazyOp.columnInfo,
1247
- queryType: lazyOp.queryType,
1248
- lazyOpIndex: i,
1249
- isMin: true
1250
- });
1251
- valuesToEncrypt.push({
1252
- value: lazyOp.max,
1253
- column: lazyOp.left,
1254
- columnInfo: lazyOp.columnInfo,
1255
- queryType: lazyOp.queryType,
1256
- lazyOpIndex: i,
1257
- isMax: true
1258
- });
1259
- } else if (lazyOp.right !== void 0) {
1260
- valuesToEncrypt.push({
1261
- value: lazyOp.right,
1262
- column: lazyOp.left,
1263
- columnInfo: lazyOp.columnInfo,
1264
- queryType: lazyOp.queryType,
1265
- lazyOpIndex: i
1266
- });
1267
- }
1268
- }
1269
- const encryptedResults = await encryptValues(
1270
- encryptionClient,
1271
- valuesToEncrypt.map((v) => ({
1272
- value: v.value,
1273
- column: v.column,
1274
- queryType: v.queryType
1275
- })),
1276
- defaultTable,
1277
- tableCache
1278
- );
1279
- const encryptedByLazyOp = /* @__PURE__ */ new Map();
1280
- for (let i = 0; i < valuesToEncrypt.length; i++) {
1281
- const { lazyOpIndex, isMin, isMax } = valuesToEncrypt[i];
1282
- const encrypted = encryptedResults[i];
1283
- let group = encryptedByLazyOp.get(lazyOpIndex);
1284
- if (!group) {
1285
- group = {};
1286
- encryptedByLazyOp.set(lazyOpIndex, group);
1287
- }
1288
- if (isMin) {
1289
- group.min = encrypted;
1290
- } else if (isMax) {
1291
- group.max = encrypted;
1292
- } else {
1293
- group.value = encrypted;
1294
- }
1295
- }
1296
- const sqlConditions = [];
1297
- for (let i = 0; i < lazyOperators.length; i++) {
1298
- const lazyOp = lazyOperators[i];
1299
- const encrypted = encryptedByLazyOp.get(i);
1300
- let sqlCondition;
1301
- if (lazyOp.needsEncryption && encrypted) {
1302
- const encryptedValues = [];
1303
- if (encrypted.value !== void 0) {
1304
- encryptedValues.push({
1305
- value: lazyOp.right,
1306
- encrypted: encrypted.value
1307
- });
1308
- }
1309
- if (encrypted.min !== void 0) {
1310
- encryptedValues.push({ value: lazyOp.min, encrypted: encrypted.min });
1311
- }
1312
- if (encrypted.max !== void 0) {
1313
- encryptedValues.push({ value: lazyOp.max, encrypted: encrypted.max });
1314
- }
1315
- sqlCondition = await executeLazyOperator(lazyOp, encryptedValues);
1316
- } else {
1317
- sqlCondition = lazyOp.execute(lazyOp.right);
1318
- }
1319
- sqlConditions.push(sqlCondition);
1320
- }
1321
- const regularPromisesResults = await Promise.all(regularPromises);
1322
- const allConditions = [
1323
- ...regularConditions,
1324
- ...sqlConditions,
1325
- ...regularPromisesResults
1326
- ];
1327
- return (0, import_drizzle_orm.and)(...allConditions) ?? import_drizzle_orm2.sql`true`;
1328
- };
1329
- const encryptedOr = async (...conditions) => {
1330
- const lazyOperators = [];
1331
- const regularConditions = [];
1332
- const regularPromises = [];
1333
- for (const condition of conditions) {
1334
- if (condition === void 0) {
1335
- continue;
1336
- }
1337
- if (isLazyOperator(condition)) {
1338
- lazyOperators.push(condition);
1339
- } else if (condition instanceof Promise) {
1340
- if (isLazyOperator(condition)) {
1341
- lazyOperators.push(condition);
1342
- } else {
1343
- regularPromises.push(condition);
1344
- }
1345
- } else {
1346
- regularConditions.push(condition);
1347
- }
1348
- }
1349
- if (lazyOperators.length === 0) {
1350
- const allConditions2 = [
1351
- ...regularConditions,
1352
- ...await Promise.all(regularPromises)
1353
- ];
1354
- return (0, import_drizzle_orm.or)(...allConditions2) ?? import_drizzle_orm2.sql`false`;
1355
- }
1356
- const valuesToEncrypt = [];
1357
- for (let i = 0; i < lazyOperators.length; i++) {
1358
- const lazyOp = lazyOperators[i];
1359
- if (!lazyOp.needsEncryption) {
1360
- continue;
1361
- }
1362
- if (lazyOp.min !== void 0 && lazyOp.max !== void 0) {
1363
- valuesToEncrypt.push({
1364
- value: lazyOp.min,
1365
- column: lazyOp.left,
1366
- columnInfo: lazyOp.columnInfo,
1367
- queryType: lazyOp.queryType,
1368
- lazyOpIndex: i,
1369
- isMin: true
1370
- });
1371
- valuesToEncrypt.push({
1372
- value: lazyOp.max,
1373
- column: lazyOp.left,
1374
- columnInfo: lazyOp.columnInfo,
1375
- queryType: lazyOp.queryType,
1376
- lazyOpIndex: i,
1377
- isMax: true
1378
- });
1379
- } else if (lazyOp.right !== void 0) {
1380
- valuesToEncrypt.push({
1381
- value: lazyOp.right,
1382
- column: lazyOp.left,
1383
- columnInfo: lazyOp.columnInfo,
1384
- queryType: lazyOp.queryType,
1385
- lazyOpIndex: i
1386
- });
1387
- }
1388
- }
1389
- const encryptedResults = await encryptValues(
1390
- encryptionClient,
1391
- valuesToEncrypt.map((v) => ({
1392
- value: v.value,
1393
- column: v.column,
1394
- queryType: v.queryType
1395
- })),
1396
- defaultTable,
1397
- tableCache
1398
- );
1399
- const encryptedByLazyOp = /* @__PURE__ */ new Map();
1400
- for (let i = 0; i < valuesToEncrypt.length; i++) {
1401
- const { lazyOpIndex, isMin, isMax } = valuesToEncrypt[i];
1402
- const encrypted = encryptedResults[i];
1403
- let group = encryptedByLazyOp.get(lazyOpIndex);
1404
- if (!group) {
1405
- group = {};
1406
- encryptedByLazyOp.set(lazyOpIndex, group);
1407
- }
1408
- if (isMin) {
1409
- group.min = encrypted;
1410
- } else if (isMax) {
1411
- group.max = encrypted;
1412
- } else {
1413
- group.value = encrypted;
1414
- }
1415
- }
1416
- const sqlConditions = [];
1417
- for (let i = 0; i < lazyOperators.length; i++) {
1418
- const lazyOp = lazyOperators[i];
1419
- const encrypted = encryptedByLazyOp.get(i);
1420
- let sqlCondition;
1421
- if (lazyOp.needsEncryption && encrypted) {
1422
- const encryptedValues = [];
1423
- if (encrypted.value !== void 0) {
1424
- encryptedValues.push({
1425
- value: lazyOp.right,
1426
- encrypted: encrypted.value
1427
- });
1428
- }
1429
- if (encrypted.min !== void 0) {
1430
- encryptedValues.push({ value: lazyOp.min, encrypted: encrypted.min });
1431
- }
1432
- if (encrypted.max !== void 0) {
1433
- encryptedValues.push({ value: lazyOp.max, encrypted: encrypted.max });
1434
- }
1435
- sqlCondition = await executeLazyOperator(lazyOp, encryptedValues);
1436
- } else {
1437
- sqlCondition = lazyOp.execute(lazyOp.right);
1438
- }
1439
- sqlConditions.push(sqlCondition);
1440
- }
1441
- const regularPromisesResults = await Promise.all(regularPromises);
1442
- const allConditions = [
1443
- ...regularConditions,
1444
- ...sqlConditions,
1445
- ...regularPromisesResults
1446
- ];
1447
- return (0, import_drizzle_orm.or)(...allConditions) ?? import_drizzle_orm2.sql`false`;
1448
- };
1449
- return {
1450
- // Comparison operators
1451
- eq: encryptedEq,
1452
- ne: encryptedNe,
1453
- gt: encryptedGt,
1454
- gte: encryptedGte,
1455
- lt: encryptedLt,
1456
- lte: encryptedLte,
1457
- // Range operators
1458
- between: encryptedBetween,
1459
- notBetween: encryptedNotBetween,
1460
- // Text search operators
1461
- like: encryptedLike,
1462
- ilike: encryptedIlike,
1463
- notIlike: encryptedNotIlike,
1464
- // Searchable JSON operators
1465
- jsonbPathQueryFirst: encryptedJsonbPathQueryFirst,
1466
- jsonbGet: encryptedJsonbGet,
1467
- jsonbPathExists: encryptedJsonbPathExists,
1468
- // Array operators
1469
- inArray: encryptedInArray,
1470
- notInArray: encryptedNotInArray,
1471
- // Sorting operators
1472
- asc: encryptedAsc,
1473
- desc: encryptedDesc,
1474
- // AND operator - batches encryption operations
1475
- and: encryptedAnd,
1476
- // OR operator - batches encryption operations
1477
- or: encryptedOr,
1478
- // Operators that don't need encryption (pass through to Drizzle)
1479
- exists: import_drizzle_orm.exists,
1480
- notExists: import_drizzle_orm.notExists,
1481
- isNull: import_drizzle_orm.isNull,
1482
- isNotNull: import_drizzle_orm.isNotNull,
1483
- not: import_drizzle_orm.not,
1484
- // Array operators that work with arrays directly (not encrypted values)
1485
- arrayContains: import_drizzle_orm.arrayContains,
1486
- arrayContained: import_drizzle_orm.arrayContained,
1487
- arrayOverlaps: import_drizzle_orm.arrayOverlaps
1488
- };
1489
- }
1490
-
1491
- // src/drizzle/index.ts
1492
- var EQL_ENCRYPTED_DATA_TYPE = "eql_v2_encrypted";
1493
- var columnConfigMap = /* @__PURE__ */ new Map();
1494
- var encryptedType = (name, config) => {
1495
- const customColumnType = (0, import_pg_core.customType)({
1496
- dataType() {
1497
- return EQL_ENCRYPTED_DATA_TYPE;
1498
- },
1499
- toDriver(value) {
1500
- const jsonStr = JSON.stringify(value);
1501
- const escaped = jsonStr.replace(/"/g, '""');
1502
- return `("${escaped}")`;
1503
- },
1504
- fromDriver(value) {
1505
- const parseComposite = (str) => {
1506
- if (!str || str === "") return null;
1507
- const trimmed = str.trim();
1508
- if (trimmed.startsWith("(") && trimmed.endsWith(")")) {
1509
- let inner = trimmed.slice(1, -1);
1510
- inner = inner.replace(/""/g, '"');
1511
- if (inner.startsWith('"') && inner.endsWith('"')) {
1512
- const stripped = inner.slice(1, -1);
1513
- return JSON.parse(stripped);
1514
- }
1515
- if (inner.startsWith("{") || inner.startsWith("[")) {
1516
- return JSON.parse(inner);
1517
- }
1518
- return inner;
1519
- }
1520
- return JSON.parse(str);
1521
- };
1522
- return parseComposite(value);
1523
- }
1524
- });
1525
- const column = customColumnType(name);
1526
- const fullConfig = {
1527
- name,
1528
- ...config
1529
- };
1530
- columnConfigMap.set(name, fullConfig);
1531
- column._encryptionConfig = fullConfig;
1532
- return column;
1533
- };
1534
- function getEncryptedColumnConfig(columnName, column) {
1535
- if (column && typeof column === "object") {
1536
- const columnAny = column;
1537
- const isEncryptedTypeString = (value) => value === EQL_ENCRYPTED_DATA_TYPE || value === '"public"."eql_v2_encrypted"';
1538
- const isEncrypted = isEncryptedTypeString(columnAny.sqlName) || isEncryptedTypeString(columnAny.dataType) || columnAny.dataType && typeof columnAny.dataType === "function" && isEncryptedTypeString(columnAny.dataType());
1539
- if (isEncrypted) {
1540
- if (columnAny._encryptionConfig) {
1541
- return columnAny._encryptionConfig;
1542
- }
1543
- const lookupName = columnAny.name || columnName;
1544
- return columnConfigMap.get(lookupName);
1545
- }
1546
- }
1547
- return void 0;
1548
- }
1549
- // Annotate the CommonJS export names for ESM import in node:
1550
- 0 && (module.exports = {
1551
- EncryptionConfigError,
1552
- EncryptionOperatorError,
1553
- createEncryptionOperators,
1554
- encryptedType,
1555
- extractEncryptionSchema,
1556
- getEncryptedColumnConfig
1557
- });
1558
- //# sourceMappingURL=index.cjs.map