@cipherstash/stack 0.19.0 → 1.0.0-rc.1

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 (101) hide show
  1. package/CHANGELOG.md +596 -0
  2. package/README.md +376 -276
  3. package/dist/adapter-kit.cjs +1002 -0
  4. package/dist/adapter-kit.cjs.map +1 -0
  5. package/dist/adapter-kit.d.cts +120 -0
  6. package/dist/adapter-kit.d.ts +120 -0
  7. package/dist/adapter-kit.js +122 -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-U66S7VIF.js → chunk-6SGN52W6.js} +166 -107
  14. package/dist/chunk-6SGN52W6.js.map +1 -0
  15. package/dist/chunk-7333ZC6L.js +48 -0
  16. package/dist/chunk-7333ZC6L.js.map +1 -0
  17. package/dist/{chunk-MP3SSDNN.js → chunk-CLM7E4I6.js} +15 -15
  18. package/dist/{chunk-MP3SSDNN.js.map → chunk-CLM7E4I6.js.map} +1 -1
  19. package/dist/{chunk-OFQ555AX.js → chunk-IDKP6ABU.js} +2 -2
  20. package/dist/{chunk-36AA7IBJ.js → chunk-L7ISHSG7.js} +53 -20
  21. package/dist/chunk-L7ISHSG7.js.map +1 -0
  22. package/dist/{chunk-LBMC4D6D.js → chunk-NVKK7UDN.js} +1 -1
  23. package/dist/chunk-NVKK7UDN.js.map +1 -0
  24. package/dist/chunk-X3JRXEIB.js +98 -0
  25. package/dist/chunk-X3JRXEIB.js.map +1 -0
  26. package/dist/client.cjs +29 -12
  27. package/dist/client.cjs.map +1 -1
  28. package/dist/client.d.cts +3 -2
  29. package/dist/client.d.ts +3 -2
  30. package/dist/client.js +2 -2
  31. package/dist/{table-CIH7jZ2h.d.ts → columns-0lbT9stl.d.ts} +157 -138
  32. package/dist/{table-DihEAlxG.d.cts → columns-Bxv7Oo9o.d.cts} +157 -138
  33. package/dist/dynamodb/index.d.cts +3 -2
  34. package/dist/dynamodb/index.d.ts +3 -2
  35. package/dist/encryption/index.cjs +54 -16
  36. package/dist/encryption/index.cjs.map +1 -1
  37. package/dist/encryption/index.d.cts +807 -6
  38. package/dist/encryption/index.d.ts +807 -6
  39. package/dist/encryption/index.js +6 -6
  40. package/dist/encryption/v3.cjs +1078 -973
  41. package/dist/encryption/v3.cjs.map +1 -1
  42. package/dist/encryption/v3.d.cts +15 -12
  43. package/dist/encryption/v3.d.ts +15 -12
  44. package/dist/encryption/v3.js +50 -22
  45. package/dist/encryption/v3.js.map +1 -1
  46. package/dist/eql/v3/index.cjs +130 -79
  47. package/dist/eql/v3/index.cjs.map +1 -1
  48. package/dist/eql/v3/index.d.cts +115 -13
  49. package/dist/eql/v3/index.d.ts +115 -13
  50. package/dist/eql/v3/index.js +16 -6
  51. package/dist/errors/index.cjs.map +1 -1
  52. package/dist/errors/index.d.cts +5 -5
  53. package/dist/errors/index.d.ts +5 -5
  54. package/dist/errors/index.js +1 -1
  55. package/dist/identity/index.cjs.map +1 -1
  56. package/dist/identity/index.js +2 -2
  57. package/dist/index-BquA71_Y.d.ts +24 -0
  58. package/dist/index-fhWTOV0K.d.cts +24 -0
  59. package/dist/index.cjs +79 -27
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.d.cts +5 -17
  62. package/dist/index.d.ts +5 -17
  63. package/dist/index.js +6 -6
  64. package/dist/schema/index.cjs +29 -12
  65. package/dist/schema/index.cjs.map +1 -1
  66. package/dist/schema/index.d.cts +1 -1
  67. package/dist/schema/index.d.ts +1 -1
  68. package/dist/schema/index.js +2 -2
  69. package/dist/{types-public-CpS5KjwX.d.ts → types-public-QMjYNfQO.d.cts} +765 -726
  70. package/dist/{types-public-CpS5KjwX.d.cts → types-public-QMjYNfQO.d.ts} +765 -726
  71. package/dist/types-public.cjs.map +1 -1
  72. package/dist/types-public.d.cts +1 -1
  73. package/dist/types-public.d.ts +1 -1
  74. package/dist/types-public.js +1 -1
  75. package/dist/wasm-inline.d.ts +779 -405
  76. package/dist/wasm-inline.js +606 -299
  77. package/dist/wasm-inline.js.map +1 -1
  78. package/package.json +25 -53
  79. package/dist/chunk-36AA7IBJ.js.map +0 -1
  80. package/dist/chunk-4AVL4VZD.js.map +0 -1
  81. package/dist/chunk-IADZCZEA.js +0 -23
  82. package/dist/chunk-IADZCZEA.js.map +0 -1
  83. package/dist/chunk-IBSK6P33.js +0 -209
  84. package/dist/chunk-IBSK6P33.js.map +0 -1
  85. package/dist/chunk-LBMC4D6D.js.map +0 -1
  86. package/dist/chunk-U66S7VIF.js.map +0 -1
  87. package/dist/client-DSGHBN-g.d.cts +0 -834
  88. package/dist/client-DfCrlHXh.d.ts +0 -834
  89. package/dist/drizzle/index.cjs +0 -5617
  90. package/dist/drizzle/index.cjs.map +0 -1
  91. package/dist/drizzle/index.d.cts +0 -358
  92. package/dist/drizzle/index.d.ts +0 -358
  93. package/dist/drizzle/index.js +0 -1220
  94. package/dist/drizzle/index.js.map +0 -1
  95. package/dist/supabase/index.cjs +0 -5951
  96. package/dist/supabase/index.cjs.map +0 -1
  97. package/dist/supabase/index.d.cts +0 -223
  98. package/dist/supabase/index.d.ts +0 -223
  99. package/dist/supabase/index.js +0 -1217
  100. package/dist/supabase/index.js.map +0 -1
  101. /package/dist/{chunk-OFQ555AX.js.map → chunk-IDKP6ABU.js.map} +0 -0
@@ -1,1220 +0,0 @@
1
- import {
2
- encryptedColumn,
3
- encryptedTable
4
- } from "../chunk-MP3SSDNN.js";
5
- import "../chunk-IADZCZEA.js";
6
- import {
7
- queryTypes
8
- } from "../chunk-4AVL4VZD.js";
9
- import "../chunk-PZ5AY32C.js";
10
-
11
- // src/drizzle/index.ts
12
- import { customType } from "drizzle-orm/pg-core";
13
-
14
- // src/drizzle/operators.ts
15
- import {
16
- and,
17
- arrayContained,
18
- arrayContains,
19
- arrayOverlaps,
20
- asc,
21
- between,
22
- bindIfParam,
23
- desc,
24
- eq,
25
- exists,
26
- gt,
27
- gte,
28
- ilike,
29
- inArray,
30
- isNotNull,
31
- isNull,
32
- like,
33
- lt,
34
- lte,
35
- ne,
36
- not,
37
- notBetween,
38
- notExists,
39
- notIlike,
40
- notInArray,
41
- or,
42
- sql
43
- } from "drizzle-orm";
44
-
45
- // src/drizzle/schema-extraction.ts
46
- function extractEncryptionSchema(table) {
47
- const tableName = table[/* @__PURE__ */ Symbol.for("drizzle:Name")];
48
- if (!tableName) {
49
- throw new Error(
50
- "Unable to extract table name from Drizzle table. Ensure you are using a table created with pgTable()."
51
- );
52
- }
53
- const columns = {};
54
- for (const [columnName, column] of Object.entries(table)) {
55
- if (typeof column !== "object" || column === null) {
56
- continue;
57
- }
58
- const config = getEncryptedColumnConfig(columnName, column);
59
- if (config) {
60
- const actualColumnName = column.name || config.name;
61
- const csCol = encryptedColumn(actualColumnName);
62
- if (config.dataType && config.dataType !== "string") {
63
- csCol.dataType(config.dataType);
64
- }
65
- if (config.orderAndRange) {
66
- csCol.orderAndRange();
67
- }
68
- if (config.equality) {
69
- if (Array.isArray(config.equality)) {
70
- csCol.equality(config.equality);
71
- } else {
72
- csCol.equality();
73
- }
74
- }
75
- if (config.freeTextSearch) {
76
- if (typeof config.freeTextSearch === "object") {
77
- csCol.freeTextSearch(config.freeTextSearch);
78
- } else {
79
- csCol.freeTextSearch();
80
- }
81
- }
82
- if (config.searchableJson) {
83
- if (config.dataType !== "json") {
84
- throw new Error(
85
- `Column "${columnName}" has searchableJson enabled but dataType is "${config.dataType ?? "string"}". searchableJson requires dataType: 'json'.`
86
- );
87
- }
88
- csCol.searchableJson();
89
- }
90
- columns[actualColumnName] = csCol;
91
- }
92
- }
93
- if (Object.keys(columns).length === 0) {
94
- throw new Error(
95
- `No encrypted columns found in table "${tableName}". Use encryptedType() to define encrypted columns.`
96
- );
97
- }
98
- return encryptedTable(tableName, columns);
99
- }
100
-
101
- // src/drizzle/operators.ts
102
- function isSQLWrapper(value) {
103
- return typeof value === "object" && value !== null && "sql" in value && typeof value.sql !== "undefined";
104
- }
105
- function isPgTable(value) {
106
- return typeof value === "object" && value !== null && /* @__PURE__ */ Symbol.for("drizzle:Name") in value;
107
- }
108
- var EncryptionOperatorError = class extends Error {
109
- constructor(message, context) {
110
- super(message);
111
- this.context = context;
112
- this.name = "EncryptionOperatorError";
113
- }
114
- context;
115
- };
116
- var EncryptionConfigError = class extends EncryptionOperatorError {
117
- constructor(message, context) {
118
- super(message, context);
119
- this.name = "EncryptionConfigError";
120
- }
121
- };
122
- function getDrizzleTableName(drizzleTable) {
123
- if (!isPgTable(drizzleTable)) {
124
- return void 0;
125
- }
126
- const tableWithSymbol = drizzleTable;
127
- return tableWithSymbol[/* @__PURE__ */ Symbol.for("drizzle:Name")];
128
- }
129
- function getDrizzleTableFromColumn(drizzleColumn) {
130
- const column = drizzleColumn;
131
- return column.table;
132
- }
133
- function getEncryptedTableFromColumn(drizzleColumn, tableCache) {
134
- const drizzleTable = getDrizzleTableFromColumn(drizzleColumn);
135
- if (!drizzleTable) {
136
- return void 0;
137
- }
138
- const tableName = getDrizzleTableName(drizzleTable);
139
- if (!tableName) {
140
- return void 0;
141
- }
142
- let encryptedTable2 = tableCache.get(tableName);
143
- if (encryptedTable2) {
144
- return encryptedTable2;
145
- }
146
- try {
147
- encryptedTable2 = extractEncryptionSchema(drizzleTable);
148
- tableCache.set(tableName, encryptedTable2);
149
- return encryptedTable2;
150
- } catch {
151
- return void 0;
152
- }
153
- }
154
- function getEncryptedColumn(drizzleColumn, encryptedTable2) {
155
- const column = drizzleColumn;
156
- const columnName = column.name;
157
- if (!columnName) {
158
- return void 0;
159
- }
160
- const tableRecord = encryptedTable2;
161
- return tableRecord[columnName];
162
- }
163
- function getColumnInfo(drizzleColumn, encryptedTable2, tableCache) {
164
- const column = drizzleColumn;
165
- const columnName = column.name || "unknown";
166
- let resolvedTable = encryptedTable2;
167
- if (!resolvedTable) {
168
- resolvedTable = getEncryptedTableFromColumn(drizzleColumn, tableCache);
169
- }
170
- const drizzleTable = getDrizzleTableFromColumn(drizzleColumn);
171
- const tableName = getDrizzleTableName(drizzleTable);
172
- if (!resolvedTable) {
173
- const config2 = getEncryptedColumnConfig(columnName, drizzleColumn);
174
- return {
175
- encryptedColumn: void 0,
176
- config: config2,
177
- encryptedTable: void 0,
178
- columnName,
179
- tableName
180
- };
181
- }
182
- const encryptedColumn2 = getEncryptedColumn(drizzleColumn, resolvedTable);
183
- const config = getEncryptedColumnConfig(columnName, drizzleColumn);
184
- return {
185
- encryptedColumn: encryptedColumn2,
186
- config,
187
- encryptedTable: resolvedTable,
188
- columnName,
189
- tableName
190
- };
191
- }
192
- function toPlaintext(value) {
193
- if (typeof value === "boolean") {
194
- return value ? 1 : 0;
195
- }
196
- if (typeof value === "string" || typeof value === "number") {
197
- return value;
198
- }
199
- if (value instanceof Date) {
200
- return value.toISOString();
201
- }
202
- return String(value);
203
- }
204
- async function encryptValues(encryptionClient, values, encryptedTable2, tableCache) {
205
- if (values.length === 0) {
206
- return [];
207
- }
208
- const valuesToEncrypt = [];
209
- const results = new Array(values.length);
210
- for (let i = 0; i < values.length; i++) {
211
- const { value, column, queryType } = values[i];
212
- const columnInfo = getColumnInfo(column, encryptedTable2, tableCache);
213
- if (!columnInfo.encryptedColumn || !columnInfo.config || !columnInfo.encryptedTable) {
214
- results[i] = value;
215
- continue;
216
- }
217
- const plaintextValue = toPlaintext(value);
218
- valuesToEncrypt.push({
219
- value: plaintextValue,
220
- column,
221
- columnInfo,
222
- queryType,
223
- originalIndex: i
224
- });
225
- }
226
- if (valuesToEncrypt.length === 0) {
227
- return results;
228
- }
229
- const columnGroups = /* @__PURE__ */ new Map();
230
- let valueIndex = 0;
231
- for (const {
232
- value,
233
- columnInfo,
234
- queryType,
235
- originalIndex
236
- } of valuesToEncrypt) {
237
- if (!columnInfo.config || !columnInfo.encryptedColumn || !columnInfo.encryptedTable) {
238
- continue;
239
- }
240
- const columnName = columnInfo.config.name;
241
- const groupKey = `${columnInfo.tableName ?? "unknown"}/${columnName}`;
242
- let group = columnGroups.get(groupKey);
243
- if (!group) {
244
- group = {
245
- column: columnInfo.encryptedColumn,
246
- table: columnInfo.encryptedTable,
247
- columnName,
248
- values: [],
249
- resultIndices: []
250
- };
251
- columnGroups.set(groupKey, group);
252
- }
253
- group.values.push({ value, index: valueIndex++, queryType });
254
- group.resultIndices.push(originalIndex);
255
- }
256
- for (const [, group] of columnGroups) {
257
- const { columnName } = group;
258
- try {
259
- const terms = group.values.map((v) => ({
260
- value: v.value,
261
- column: group.column,
262
- table: group.table,
263
- queryType: v.queryType
264
- }));
265
- const encryptedTerms = await encryptionClient.encryptQuery(terms);
266
- if (encryptedTerms.failure) {
267
- throw new EncryptionOperatorError(
268
- `Failed to encrypt query terms for column "${columnName}": ${encryptedTerms.failure.message}`,
269
- { columnName }
270
- );
271
- }
272
- for (let i = 0; i < group.values.length; i++) {
273
- const resultIndex = group.resultIndices[i] ?? -1;
274
- if (resultIndex >= 0 && resultIndex < results.length) {
275
- results[resultIndex] = encryptedTerms.data[i];
276
- }
277
- }
278
- } catch (error) {
279
- if (error instanceof EncryptionOperatorError) {
280
- throw error;
281
- }
282
- const errorMessage = error instanceof Error ? error.message : String(error);
283
- throw new EncryptionOperatorError(
284
- `Unexpected error encrypting values for column "${columnName}": ${errorMessage}`,
285
- { columnName }
286
- );
287
- }
288
- }
289
- return results;
290
- }
291
- async function encryptValue(encryptionClient, value, drizzleColumn, encryptedTable2, tableCache, queryType) {
292
- const results = await encryptValues(
293
- encryptionClient,
294
- [{ value, column: drizzleColumn, queryType }],
295
- encryptedTable2,
296
- tableCache
297
- );
298
- return results[0];
299
- }
300
- function isLazyOperator(value) {
301
- return typeof value === "object" && value !== null && "__isLazyOperator" in value && value.__isLazyOperator === true;
302
- }
303
- function createLazyOperator(operator, left, right, execute, needsEncryption, columnInfo, encryptionClient, defaultTable, tableCache, min, max, queryType) {
304
- let resolvedSQL;
305
- let encryptionPromise;
306
- const lazyOp = {
307
- __isLazyOperator: true,
308
- operator,
309
- queryType,
310
- left,
311
- right,
312
- min,
313
- max,
314
- needsEncryption,
315
- columnInfo,
316
- execute
317
- };
318
- const promise = new Promise((resolve, reject) => {
319
- queueMicrotask(async () => {
320
- if (resolvedSQL !== void 0) {
321
- resolve(resolvedSQL);
322
- return;
323
- }
324
- try {
325
- if (!encryptionPromise) {
326
- encryptionPromise = executeLazyOperatorDirect(
327
- lazyOp,
328
- encryptionClient,
329
- defaultTable,
330
- tableCache
331
- );
332
- }
333
- const sql2 = await encryptionPromise;
334
- resolvedSQL = sql2;
335
- resolve(sql2);
336
- } catch (error) {
337
- reject(error);
338
- }
339
- });
340
- });
341
- return Object.assign(promise, lazyOp);
342
- }
343
- async function executeLazyOperator(lazyOp, encryptedValues) {
344
- if (!lazyOp.needsEncryption) {
345
- return lazyOp.execute(lazyOp.right);
346
- }
347
- if (lazyOp.min !== void 0 && lazyOp.max !== void 0) {
348
- let encryptedMin;
349
- let encryptedMax;
350
- if (encryptedValues && encryptedValues.length >= 2) {
351
- encryptedMin = encryptedValues[0]?.encrypted;
352
- encryptedMax = encryptedValues[1]?.encrypted;
353
- } else {
354
- throw new EncryptionOperatorError(
355
- "Between operator requires both min and max encrypted values",
356
- {
357
- columnName: lazyOp.columnInfo.columnName,
358
- tableName: lazyOp.columnInfo.tableName,
359
- operator: lazyOp.operator
360
- }
361
- );
362
- }
363
- if (encryptedMin === void 0 || encryptedMax === void 0) {
364
- throw new EncryptionOperatorError(
365
- "Between operator requires both min and max values to be encrypted",
366
- {
367
- columnName: lazyOp.columnInfo.columnName,
368
- tableName: lazyOp.columnInfo.tableName,
369
- operator: lazyOp.operator
370
- }
371
- );
372
- }
373
- return lazyOp.execute(void 0, encryptedMin, encryptedMax);
374
- }
375
- let encrypted;
376
- if (encryptedValues && encryptedValues.length > 0) {
377
- encrypted = encryptedValues[0]?.encrypted;
378
- } else {
379
- throw new EncryptionOperatorError(
380
- "Operator requires encrypted value but none provided",
381
- {
382
- columnName: lazyOp.columnInfo.columnName,
383
- tableName: lazyOp.columnInfo.tableName,
384
- operator: lazyOp.operator
385
- }
386
- );
387
- }
388
- if (encrypted === void 0) {
389
- throw new EncryptionOperatorError(
390
- "Encryption failed or value was not encrypted",
391
- {
392
- columnName: lazyOp.columnInfo.columnName,
393
- tableName: lazyOp.columnInfo.tableName,
394
- operator: lazyOp.operator
395
- }
396
- );
397
- }
398
- return lazyOp.execute(encrypted);
399
- }
400
- async function executeLazyOperatorDirect(lazyOp, encryptionClient, defaultTable, tableCache) {
401
- if (!lazyOp.needsEncryption) {
402
- return lazyOp.execute(lazyOp.right);
403
- }
404
- if (lazyOp.min !== void 0 && lazyOp.max !== void 0) {
405
- const [encryptedMin, encryptedMax] = await encryptValues(
406
- encryptionClient,
407
- [
408
- { value: lazyOp.min, column: lazyOp.left, queryType: lazyOp.queryType },
409
- { value: lazyOp.max, column: lazyOp.left, queryType: lazyOp.queryType }
410
- ],
411
- defaultTable,
412
- tableCache
413
- );
414
- return lazyOp.execute(void 0, encryptedMin, encryptedMax);
415
- }
416
- const encrypted = await encryptValue(
417
- encryptionClient,
418
- lazyOp.right,
419
- lazyOp.left,
420
- defaultTable,
421
- tableCache,
422
- lazyOp.queryType
423
- );
424
- return lazyOp.execute(encrypted);
425
- }
426
- function createComparisonOperator(operator, left, right, columnInfo, encryptionClient, defaultTable, tableCache) {
427
- const { config } = columnInfo;
428
- const requiresOrderAndRange = ["gt", "gte", "lt", "lte"].includes(operator);
429
- if (requiresOrderAndRange) {
430
- if (!config?.orderAndRange) {
431
- switch (operator) {
432
- case "gt":
433
- return gt(left, right);
434
- case "gte":
435
- return gte(left, right);
436
- case "lt":
437
- return lt(left, right);
438
- case "lte":
439
- return lte(left, right);
440
- }
441
- }
442
- const executeFn = (encrypted) => {
443
- if (encrypted === void 0) {
444
- throw new EncryptionOperatorError(
445
- `Encryption failed for ${operator} operator`,
446
- {
447
- columnName: columnInfo.columnName,
448
- tableName: columnInfo.tableName,
449
- operator
450
- }
451
- );
452
- }
453
- return sql`eql_v2.${sql.raw(operator)}(${left}, ${bindIfParam(encrypted, left)})`;
454
- };
455
- return createLazyOperator(
456
- operator,
457
- left,
458
- right,
459
- executeFn,
460
- true,
461
- columnInfo,
462
- encryptionClient,
463
- defaultTable,
464
- tableCache,
465
- void 0,
466
- // min
467
- void 0,
468
- // max
469
- queryTypes.orderAndRange
470
- );
471
- }
472
- const requiresEquality = ["eq", "ne"].includes(operator);
473
- if (requiresEquality && config?.equality) {
474
- const executeFn = (encrypted) => {
475
- if (encrypted === void 0) {
476
- throw new EncryptionOperatorError(
477
- `Encryption failed for ${operator} operator`,
478
- {
479
- columnName: columnInfo.columnName,
480
- tableName: columnInfo.tableName,
481
- operator
482
- }
483
- );
484
- }
485
- return operator === "eq" ? eq(left, encrypted) : ne(left, encrypted);
486
- };
487
- return createLazyOperator(
488
- operator,
489
- left,
490
- right,
491
- executeFn,
492
- true,
493
- columnInfo,
494
- encryptionClient,
495
- defaultTable,
496
- tableCache,
497
- void 0,
498
- // min
499
- void 0,
500
- // max
501
- queryTypes.equality
502
- );
503
- }
504
- return operator === "eq" ? eq(left, right) : ne(left, right);
505
- }
506
- function createRangeOperator(operator, left, min, max, columnInfo, encryptionClient, defaultTable, tableCache) {
507
- const { config } = columnInfo;
508
- if (!config?.orderAndRange) {
509
- return operator === "between" ? between(left, min, max) : notBetween(left, min, max);
510
- }
511
- const executeFn = (_encrypted, encryptedMin, encryptedMax) => {
512
- if (encryptedMin === void 0 || encryptedMax === void 0) {
513
- throw new EncryptionOperatorError(
514
- `${operator} operator requires both min and max values`,
515
- {
516
- columnName: columnInfo.columnName,
517
- tableName: columnInfo.tableName,
518
- operator
519
- }
520
- );
521
- }
522
- const rangeCondition = sql`eql_v2.gte(${left}, ${bindIfParam(encryptedMin, left)}) AND eql_v2.lte(${left}, ${bindIfParam(encryptedMax, left)})`;
523
- return operator === "between" ? rangeCondition : sql`NOT (${rangeCondition})`;
524
- };
525
- return createLazyOperator(
526
- operator,
527
- left,
528
- void 0,
529
- executeFn,
530
- true,
531
- columnInfo,
532
- encryptionClient,
533
- defaultTable,
534
- tableCache,
535
- min,
536
- max,
537
- queryTypes.orderAndRange
538
- );
539
- }
540
- function createTextSearchOperator(operator, left, right, columnInfo, encryptionClient, defaultTable, tableCache) {
541
- const { config } = columnInfo;
542
- if (!config?.freeTextSearch) {
543
- const rightValue = right;
544
- switch (operator) {
545
- case "like":
546
- return like(left, rightValue);
547
- case "ilike":
548
- return ilike(left, rightValue);
549
- case "notIlike":
550
- return notIlike(left, rightValue);
551
- }
552
- }
553
- const executeFn = (encrypted) => {
554
- if (encrypted === void 0) {
555
- throw new EncryptionOperatorError(
556
- `Encryption failed for ${operator} operator`,
557
- {
558
- columnName: columnInfo.columnName,
559
- tableName: columnInfo.tableName,
560
- operator
561
- }
562
- );
563
- }
564
- const sqlFn = sql`eql_v2.${sql.raw(operator === "notIlike" ? "ilike" : operator)}(${left}, ${bindIfParam(encrypted, left)})`;
565
- return operator === "notIlike" ? sql`NOT (${sqlFn})` : sqlFn;
566
- };
567
- return createLazyOperator(
568
- operator,
569
- left,
570
- right,
571
- executeFn,
572
- true,
573
- columnInfo,
574
- encryptionClient,
575
- defaultTable,
576
- tableCache,
577
- void 0,
578
- // min
579
- void 0,
580
- // max
581
- queryTypes.freeTextSearch
582
- );
583
- }
584
- function createJsonbOperator(operator, left, right, columnInfo, encryptionClient, defaultTable, tableCache) {
585
- const { config } = columnInfo;
586
- const encryptedSelector = (value) => sql`${bindIfParam(value, left)}::eql_v2_encrypted`;
587
- if (!config?.searchableJson) {
588
- throw new EncryptionOperatorError(
589
- `The ${operator} operator requires searchableJson to be enabled on the column configuration.`,
590
- {
591
- columnName: columnInfo.columnName,
592
- tableName: columnInfo.tableName,
593
- operator
594
- }
595
- );
596
- }
597
- const executeFn = (encrypted) => {
598
- if (encrypted === void 0) {
599
- throw new EncryptionOperatorError(
600
- `Encryption failed for ${operator} operator`,
601
- {
602
- columnName: columnInfo.columnName,
603
- tableName: columnInfo.tableName,
604
- operator
605
- }
606
- );
607
- }
608
- switch (operator) {
609
- case "jsonbPathQueryFirst":
610
- return sql`eql_v2.jsonb_path_query_first(${left}, ${encryptedSelector(encrypted)})`;
611
- case "jsonbGet":
612
- return sql`${left} -> ${encryptedSelector(encrypted)}`;
613
- case "jsonbPathExists":
614
- return sql`eql_v2.jsonb_path_exists(${left}, ${encryptedSelector(encrypted)})`;
615
- }
616
- };
617
- return createLazyOperator(
618
- operator,
619
- left,
620
- right,
621
- executeFn,
622
- true,
623
- columnInfo,
624
- encryptionClient,
625
- defaultTable,
626
- tableCache,
627
- void 0,
628
- void 0,
629
- queryTypes.steVecSelector
630
- );
631
- }
632
- function createEncryptionOperators(encryptionClient) {
633
- const tableCache = /* @__PURE__ */ new Map();
634
- const defaultTable = void 0;
635
- const encryptedEq = (left, right) => {
636
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
637
- return createComparisonOperator(
638
- "eq",
639
- left,
640
- right,
641
- columnInfo,
642
- encryptionClient,
643
- defaultTable,
644
- tableCache
645
- );
646
- };
647
- const encryptedNe = (left, right) => {
648
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
649
- return createComparisonOperator(
650
- "ne",
651
- left,
652
- right,
653
- columnInfo,
654
- encryptionClient,
655
- defaultTable,
656
- tableCache
657
- );
658
- };
659
- const encryptedGt = (left, right) => {
660
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
661
- return createComparisonOperator(
662
- "gt",
663
- left,
664
- right,
665
- columnInfo,
666
- encryptionClient,
667
- defaultTable,
668
- tableCache
669
- );
670
- };
671
- const encryptedGte = (left, right) => {
672
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
673
- return createComparisonOperator(
674
- "gte",
675
- left,
676
- right,
677
- columnInfo,
678
- encryptionClient,
679
- defaultTable,
680
- tableCache
681
- );
682
- };
683
- const encryptedLt = (left, right) => {
684
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
685
- return createComparisonOperator(
686
- "lt",
687
- left,
688
- right,
689
- columnInfo,
690
- encryptionClient,
691
- defaultTable,
692
- tableCache
693
- );
694
- };
695
- const encryptedLte = (left, right) => {
696
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
697
- return createComparisonOperator(
698
- "lte",
699
- left,
700
- right,
701
- columnInfo,
702
- encryptionClient,
703
- defaultTable,
704
- tableCache
705
- );
706
- };
707
- const encryptedBetween = (left, min, max) => {
708
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
709
- return createRangeOperator(
710
- "between",
711
- left,
712
- min,
713
- max,
714
- columnInfo,
715
- encryptionClient,
716
- defaultTable,
717
- tableCache
718
- );
719
- };
720
- const encryptedNotBetween = (left, min, max) => {
721
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
722
- return createRangeOperator(
723
- "notBetween",
724
- left,
725
- min,
726
- max,
727
- columnInfo,
728
- encryptionClient,
729
- defaultTable,
730
- tableCache
731
- );
732
- };
733
- const encryptedLike = (left, right) => {
734
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
735
- return createTextSearchOperator(
736
- "like",
737
- left,
738
- right,
739
- columnInfo,
740
- encryptionClient,
741
- defaultTable,
742
- tableCache
743
- );
744
- };
745
- const encryptedIlike = (left, right) => {
746
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
747
- return createTextSearchOperator(
748
- "ilike",
749
- left,
750
- right,
751
- columnInfo,
752
- encryptionClient,
753
- defaultTable,
754
- tableCache
755
- );
756
- };
757
- const encryptedNotIlike = (left, right) => {
758
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
759
- return createTextSearchOperator(
760
- "notIlike",
761
- left,
762
- right,
763
- columnInfo,
764
- encryptionClient,
765
- defaultTable,
766
- tableCache
767
- );
768
- };
769
- const encryptedJsonbPathQueryFirst = (left, right) => {
770
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
771
- return createJsonbOperator(
772
- "jsonbPathQueryFirst",
773
- left,
774
- right,
775
- columnInfo,
776
- encryptionClient,
777
- defaultTable,
778
- tableCache
779
- );
780
- };
781
- const encryptedJsonbGet = (left, right) => {
782
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
783
- return createJsonbOperator(
784
- "jsonbGet",
785
- left,
786
- right,
787
- columnInfo,
788
- encryptionClient,
789
- defaultTable,
790
- tableCache
791
- );
792
- };
793
- const encryptedJsonbPathExists = (left, right) => {
794
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
795
- return createJsonbOperator(
796
- "jsonbPathExists",
797
- left,
798
- right,
799
- columnInfo,
800
- encryptionClient,
801
- defaultTable,
802
- tableCache
803
- );
804
- };
805
- const encryptedInArray = async (left, right) => {
806
- if (isSQLWrapper(right)) {
807
- return inArray(left, right);
808
- }
809
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
810
- if (!columnInfo.config?.equality || !Array.isArray(right)) {
811
- return inArray(left, right);
812
- }
813
- const encryptedValues = await encryptValues(
814
- encryptionClient,
815
- right.map((value) => ({
816
- value,
817
- column: left,
818
- queryType: queryTypes.equality
819
- })),
820
- defaultTable,
821
- tableCache
822
- );
823
- const conditions = encryptedValues.filter((encrypted) => encrypted !== void 0).map((encrypted) => eq(left, encrypted));
824
- if (conditions.length === 0) {
825
- return sql`false`;
826
- }
827
- const combined = or(...conditions);
828
- return combined ?? sql`false`;
829
- };
830
- const encryptedNotInArray = async (left, right) => {
831
- if (isSQLWrapper(right)) {
832
- return notInArray(
833
- left,
834
- right
835
- );
836
- }
837
- const columnInfo = getColumnInfo(left, defaultTable, tableCache);
838
- if (!columnInfo.config?.equality || !Array.isArray(right)) {
839
- return notInArray(left, right);
840
- }
841
- const encryptedValues = await encryptValues(
842
- encryptionClient,
843
- right.map((value) => ({
844
- value,
845
- column: left,
846
- queryType: queryTypes.equality
847
- })),
848
- defaultTable,
849
- tableCache
850
- );
851
- const conditions = encryptedValues.filter((encrypted) => encrypted !== void 0).map((encrypted) => ne(left, encrypted));
852
- if (conditions.length === 0) {
853
- return sql`true`;
854
- }
855
- const combined = and(...conditions);
856
- return combined ?? sql`true`;
857
- };
858
- const encryptedAsc = (column) => {
859
- const columnInfo = getColumnInfo(column, defaultTable, tableCache);
860
- if (columnInfo.config?.orderAndRange) {
861
- return asc(sql`eql_v2.order_by(${column})`);
862
- }
863
- return asc(column);
864
- };
865
- const encryptedDesc = (column) => {
866
- const columnInfo = getColumnInfo(column, defaultTable, tableCache);
867
- if (columnInfo.config?.orderAndRange) {
868
- return desc(sql`eql_v2.order_by(${column})`);
869
- }
870
- return desc(column);
871
- };
872
- const encryptedAnd = async (...conditions) => {
873
- const lazyOperators = [];
874
- const regularConditions = [];
875
- const regularPromises = [];
876
- for (const condition of conditions) {
877
- if (condition === void 0) {
878
- continue;
879
- }
880
- if (isLazyOperator(condition)) {
881
- lazyOperators.push(condition);
882
- } else if (condition instanceof Promise) {
883
- if (isLazyOperator(condition)) {
884
- lazyOperators.push(condition);
885
- } else {
886
- regularPromises.push(condition);
887
- }
888
- } else {
889
- regularConditions.push(condition);
890
- }
891
- }
892
- if (lazyOperators.length === 0) {
893
- const allConditions2 = [
894
- ...regularConditions,
895
- ...await Promise.all(regularPromises)
896
- ];
897
- return and(...allConditions2) ?? sql`true`;
898
- }
899
- const valuesToEncrypt = [];
900
- for (let i = 0; i < lazyOperators.length; i++) {
901
- const lazyOp = lazyOperators[i];
902
- if (!lazyOp.needsEncryption) {
903
- continue;
904
- }
905
- if (lazyOp.min !== void 0 && lazyOp.max !== void 0) {
906
- valuesToEncrypt.push({
907
- value: lazyOp.min,
908
- column: lazyOp.left,
909
- columnInfo: lazyOp.columnInfo,
910
- queryType: lazyOp.queryType,
911
- lazyOpIndex: i,
912
- isMin: true
913
- });
914
- valuesToEncrypt.push({
915
- value: lazyOp.max,
916
- column: lazyOp.left,
917
- columnInfo: lazyOp.columnInfo,
918
- queryType: lazyOp.queryType,
919
- lazyOpIndex: i,
920
- isMax: true
921
- });
922
- } else if (lazyOp.right !== void 0) {
923
- valuesToEncrypt.push({
924
- value: lazyOp.right,
925
- column: lazyOp.left,
926
- columnInfo: lazyOp.columnInfo,
927
- queryType: lazyOp.queryType,
928
- lazyOpIndex: i
929
- });
930
- }
931
- }
932
- const encryptedResults = await encryptValues(
933
- encryptionClient,
934
- valuesToEncrypt.map((v) => ({
935
- value: v.value,
936
- column: v.column,
937
- queryType: v.queryType
938
- })),
939
- defaultTable,
940
- tableCache
941
- );
942
- const encryptedByLazyOp = /* @__PURE__ */ new Map();
943
- for (let i = 0; i < valuesToEncrypt.length; i++) {
944
- const { lazyOpIndex, isMin, isMax } = valuesToEncrypt[i];
945
- const encrypted = encryptedResults[i];
946
- let group = encryptedByLazyOp.get(lazyOpIndex);
947
- if (!group) {
948
- group = {};
949
- encryptedByLazyOp.set(lazyOpIndex, group);
950
- }
951
- if (isMin) {
952
- group.min = encrypted;
953
- } else if (isMax) {
954
- group.max = encrypted;
955
- } else {
956
- group.value = encrypted;
957
- }
958
- }
959
- const sqlConditions = [];
960
- for (let i = 0; i < lazyOperators.length; i++) {
961
- const lazyOp = lazyOperators[i];
962
- const encrypted = encryptedByLazyOp.get(i);
963
- let sqlCondition;
964
- if (lazyOp.needsEncryption && encrypted) {
965
- const encryptedValues = [];
966
- if (encrypted.value !== void 0) {
967
- encryptedValues.push({
968
- value: lazyOp.right,
969
- encrypted: encrypted.value
970
- });
971
- }
972
- if (encrypted.min !== void 0) {
973
- encryptedValues.push({ value: lazyOp.min, encrypted: encrypted.min });
974
- }
975
- if (encrypted.max !== void 0) {
976
- encryptedValues.push({ value: lazyOp.max, encrypted: encrypted.max });
977
- }
978
- sqlCondition = await executeLazyOperator(lazyOp, encryptedValues);
979
- } else {
980
- sqlCondition = lazyOp.execute(lazyOp.right);
981
- }
982
- sqlConditions.push(sqlCondition);
983
- }
984
- const regularPromisesResults = await Promise.all(regularPromises);
985
- const allConditions = [
986
- ...regularConditions,
987
- ...sqlConditions,
988
- ...regularPromisesResults
989
- ];
990
- return and(...allConditions) ?? sql`true`;
991
- };
992
- const encryptedOr = async (...conditions) => {
993
- const lazyOperators = [];
994
- const regularConditions = [];
995
- const regularPromises = [];
996
- for (const condition of conditions) {
997
- if (condition === void 0) {
998
- continue;
999
- }
1000
- if (isLazyOperator(condition)) {
1001
- lazyOperators.push(condition);
1002
- } else if (condition instanceof Promise) {
1003
- if (isLazyOperator(condition)) {
1004
- lazyOperators.push(condition);
1005
- } else {
1006
- regularPromises.push(condition);
1007
- }
1008
- } else {
1009
- regularConditions.push(condition);
1010
- }
1011
- }
1012
- if (lazyOperators.length === 0) {
1013
- const allConditions2 = [
1014
- ...regularConditions,
1015
- ...await Promise.all(regularPromises)
1016
- ];
1017
- return or(...allConditions2) ?? sql`false`;
1018
- }
1019
- const valuesToEncrypt = [];
1020
- for (let i = 0; i < lazyOperators.length; i++) {
1021
- const lazyOp = lazyOperators[i];
1022
- if (!lazyOp.needsEncryption) {
1023
- continue;
1024
- }
1025
- if (lazyOp.min !== void 0 && lazyOp.max !== void 0) {
1026
- valuesToEncrypt.push({
1027
- value: lazyOp.min,
1028
- column: lazyOp.left,
1029
- columnInfo: lazyOp.columnInfo,
1030
- queryType: lazyOp.queryType,
1031
- lazyOpIndex: i,
1032
- isMin: true
1033
- });
1034
- valuesToEncrypt.push({
1035
- value: lazyOp.max,
1036
- column: lazyOp.left,
1037
- columnInfo: lazyOp.columnInfo,
1038
- queryType: lazyOp.queryType,
1039
- lazyOpIndex: i,
1040
- isMax: true
1041
- });
1042
- } else if (lazyOp.right !== void 0) {
1043
- valuesToEncrypt.push({
1044
- value: lazyOp.right,
1045
- column: lazyOp.left,
1046
- columnInfo: lazyOp.columnInfo,
1047
- queryType: lazyOp.queryType,
1048
- lazyOpIndex: i
1049
- });
1050
- }
1051
- }
1052
- const encryptedResults = await encryptValues(
1053
- encryptionClient,
1054
- valuesToEncrypt.map((v) => ({
1055
- value: v.value,
1056
- column: v.column,
1057
- queryType: v.queryType
1058
- })),
1059
- defaultTable,
1060
- tableCache
1061
- );
1062
- const encryptedByLazyOp = /* @__PURE__ */ new Map();
1063
- for (let i = 0; i < valuesToEncrypt.length; i++) {
1064
- const { lazyOpIndex, isMin, isMax } = valuesToEncrypt[i];
1065
- const encrypted = encryptedResults[i];
1066
- let group = encryptedByLazyOp.get(lazyOpIndex);
1067
- if (!group) {
1068
- group = {};
1069
- encryptedByLazyOp.set(lazyOpIndex, group);
1070
- }
1071
- if (isMin) {
1072
- group.min = encrypted;
1073
- } else if (isMax) {
1074
- group.max = encrypted;
1075
- } else {
1076
- group.value = encrypted;
1077
- }
1078
- }
1079
- const sqlConditions = [];
1080
- for (let i = 0; i < lazyOperators.length; i++) {
1081
- const lazyOp = lazyOperators[i];
1082
- const encrypted = encryptedByLazyOp.get(i);
1083
- let sqlCondition;
1084
- if (lazyOp.needsEncryption && encrypted) {
1085
- const encryptedValues = [];
1086
- if (encrypted.value !== void 0) {
1087
- encryptedValues.push({
1088
- value: lazyOp.right,
1089
- encrypted: encrypted.value
1090
- });
1091
- }
1092
- if (encrypted.min !== void 0) {
1093
- encryptedValues.push({ value: lazyOp.min, encrypted: encrypted.min });
1094
- }
1095
- if (encrypted.max !== void 0) {
1096
- encryptedValues.push({ value: lazyOp.max, encrypted: encrypted.max });
1097
- }
1098
- sqlCondition = await executeLazyOperator(lazyOp, encryptedValues);
1099
- } else {
1100
- sqlCondition = lazyOp.execute(lazyOp.right);
1101
- }
1102
- sqlConditions.push(sqlCondition);
1103
- }
1104
- const regularPromisesResults = await Promise.all(regularPromises);
1105
- const allConditions = [
1106
- ...regularConditions,
1107
- ...sqlConditions,
1108
- ...regularPromisesResults
1109
- ];
1110
- return or(...allConditions) ?? sql`false`;
1111
- };
1112
- return {
1113
- // Comparison operators
1114
- eq: encryptedEq,
1115
- ne: encryptedNe,
1116
- gt: encryptedGt,
1117
- gte: encryptedGte,
1118
- lt: encryptedLt,
1119
- lte: encryptedLte,
1120
- // Range operators
1121
- between: encryptedBetween,
1122
- notBetween: encryptedNotBetween,
1123
- // Text search operators
1124
- like: encryptedLike,
1125
- ilike: encryptedIlike,
1126
- notIlike: encryptedNotIlike,
1127
- // Searchable JSON operators
1128
- jsonbPathQueryFirst: encryptedJsonbPathQueryFirst,
1129
- jsonbGet: encryptedJsonbGet,
1130
- jsonbPathExists: encryptedJsonbPathExists,
1131
- // Array operators
1132
- inArray: encryptedInArray,
1133
- notInArray: encryptedNotInArray,
1134
- // Sorting operators
1135
- asc: encryptedAsc,
1136
- desc: encryptedDesc,
1137
- // AND operator - batches encryption operations
1138
- and: encryptedAnd,
1139
- // OR operator - batches encryption operations
1140
- or: encryptedOr,
1141
- // Operators that don't need encryption (pass through to Drizzle)
1142
- exists,
1143
- notExists,
1144
- isNull,
1145
- isNotNull,
1146
- not,
1147
- // Array operators that work with arrays directly (not encrypted values)
1148
- arrayContains,
1149
- arrayContained,
1150
- arrayOverlaps
1151
- };
1152
- }
1153
-
1154
- // src/drizzle/index.ts
1155
- var EQL_ENCRYPTED_DATA_TYPE = "eql_v2_encrypted";
1156
- var columnConfigMap = /* @__PURE__ */ new Map();
1157
- var encryptedType = (name, config) => {
1158
- const customColumnType = customType({
1159
- dataType() {
1160
- return EQL_ENCRYPTED_DATA_TYPE;
1161
- },
1162
- toDriver(value) {
1163
- const jsonStr = JSON.stringify(value);
1164
- const escaped = jsonStr.replace(/"/g, '""');
1165
- return `("${escaped}")`;
1166
- },
1167
- fromDriver(value) {
1168
- const parseComposite = (str) => {
1169
- if (!str || str === "") return null;
1170
- const trimmed = str.trim();
1171
- if (trimmed.startsWith("(") && trimmed.endsWith(")")) {
1172
- let inner = trimmed.slice(1, -1);
1173
- inner = inner.replace(/""/g, '"');
1174
- if (inner.startsWith('"') && inner.endsWith('"')) {
1175
- const stripped = inner.slice(1, -1);
1176
- return JSON.parse(stripped);
1177
- }
1178
- if (inner.startsWith("{") || inner.startsWith("[")) {
1179
- return JSON.parse(inner);
1180
- }
1181
- return inner;
1182
- }
1183
- return JSON.parse(str);
1184
- };
1185
- return parseComposite(value);
1186
- }
1187
- });
1188
- const column = customColumnType(name);
1189
- const fullConfig = {
1190
- name,
1191
- ...config
1192
- };
1193
- columnConfigMap.set(name, fullConfig);
1194
- column._encryptionConfig = fullConfig;
1195
- return column;
1196
- };
1197
- function getEncryptedColumnConfig(columnName, column) {
1198
- if (column && typeof column === "object") {
1199
- const columnAny = column;
1200
- const isEncryptedTypeString = (value) => value === EQL_ENCRYPTED_DATA_TYPE || value === '"public"."eql_v2_encrypted"';
1201
- const isEncrypted = isEncryptedTypeString(columnAny.sqlName) || isEncryptedTypeString(columnAny.dataType) || columnAny.dataType && typeof columnAny.dataType === "function" && isEncryptedTypeString(columnAny.dataType());
1202
- if (isEncrypted) {
1203
- if (columnAny._encryptionConfig) {
1204
- return columnAny._encryptionConfig;
1205
- }
1206
- const lookupName = columnAny.name || columnName;
1207
- return columnConfigMap.get(lookupName);
1208
- }
1209
- }
1210
- return void 0;
1211
- }
1212
- export {
1213
- EncryptionConfigError,
1214
- EncryptionOperatorError,
1215
- createEncryptionOperators,
1216
- encryptedType,
1217
- extractEncryptionSchema,
1218
- getEncryptedColumnConfig
1219
- };
1220
- //# sourceMappingURL=index.js.map