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