@usebetterdev/audit-drizzle 0.6.0 → 0.7.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.
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/adapter.ts
2
+ import { encodeCursor, assembleStats } from "@usebetterdev/audit-core";
2
3
  import { and as and2, eq as eq2, gte as gte2, lt as lt2, isNotNull, sql as sql2, desc as desc2 } from "drizzle-orm";
3
4
 
4
5
  // src/schema.ts
@@ -50,23 +51,7 @@ var auditLogs = pgTable(
50
51
  );
51
52
 
52
53
  // src/column-map.ts
53
- var VALID_OPERATIONS = /* @__PURE__ */ new Set([
54
- "INSERT",
55
- "UPDATE",
56
- "DELETE"
57
- ]);
58
- var VALID_SEVERITIES = /* @__PURE__ */ new Set([
59
- "low",
60
- "medium",
61
- "high",
62
- "critical"
63
- ]);
64
- function isAuditOperation(value) {
65
- return VALID_OPERATIONS.has(value);
66
- }
67
- function isAuditSeverity(value) {
68
- return VALID_SEVERITIES.has(value);
69
- }
54
+ import { isAuditOperation, isAuditSeverity } from "@usebetterdev/audit-core";
70
55
  function auditLogToRow(log) {
71
56
  const row = {
72
57
  id: log.id,
@@ -171,7 +156,10 @@ function rowToAuditLog(row) {
171
156
  }
172
157
 
173
158
  // src/query.ts
174
- import { parseDuration } from "@usebetterdev/audit-core";
159
+ import {
160
+ decodeCursor,
161
+ interpretFilters
162
+ } from "@usebetterdev/audit-core";
175
163
  import {
176
164
  and,
177
165
  or,
@@ -186,85 +174,66 @@ import {
186
174
  desc,
187
175
  sql
188
176
  } from "drizzle-orm";
189
- function escapeLikePattern(input) {
190
- return input.replace(/[%_\\]/g, "\\$&");
191
- }
192
- function resolveTimeFilter(filter) {
193
- if ("date" in filter && filter.date !== void 0) {
194
- return filter.date;
195
- }
196
- if ("duration" in filter && filter.duration !== void 0) {
197
- return parseDuration(filter.duration);
198
- }
199
- throw new Error("TimeFilter must have either date or duration");
200
- }
201
- function buildWhereConditions(filters) {
202
- const conditions = [];
203
- if (filters.resource !== void 0) {
204
- conditions.push(eq(auditLogs.tableName, filters.resource.tableName));
205
- if (filters.resource.recordId !== void 0) {
206
- conditions.push(eq(auditLogs.recordId, filters.resource.recordId));
177
+ var FIELD_COLUMNS = {
178
+ tableName: auditLogs.tableName,
179
+ recordId: auditLogs.recordId,
180
+ actorId: auditLogs.actorId,
181
+ severity: auditLogs.severity,
182
+ operation: auditLogs.operation
183
+ };
184
+ function mapCondition(condition) {
185
+ switch (condition.kind) {
186
+ case "eq": {
187
+ return eq(FIELD_COLUMNS[condition.field], condition.value);
207
188
  }
208
- }
209
- if (filters.actorIds !== void 0 && filters.actorIds.length > 0) {
210
- if (filters.actorIds.length === 1) {
211
- conditions.push(eq(auditLogs.actorId, filters.actorIds[0]));
212
- } else {
213
- conditions.push(inArray(auditLogs.actorId, filters.actorIds));
189
+ case "in": {
190
+ return inArray(FIELD_COLUMNS[condition.field], condition.values);
214
191
  }
215
- }
216
- if (filters.severities !== void 0 && filters.severities.length > 0) {
217
- if (filters.severities.length === 1) {
218
- conditions.push(eq(auditLogs.severity, filters.severities[0]));
219
- } else {
220
- conditions.push(inArray(auditLogs.severity, filters.severities));
192
+ case "timestampGte": {
193
+ return gte(auditLogs.timestamp, condition.value);
221
194
  }
222
- }
223
- if (filters.operations !== void 0 && filters.operations.length > 0) {
224
- if (filters.operations.length === 1) {
225
- conditions.push(eq(auditLogs.operation, filters.operations[0]));
226
- } else {
227
- conditions.push(inArray(auditLogs.operation, filters.operations));
195
+ case "timestampLte": {
196
+ return lte(auditLogs.timestamp, condition.value);
228
197
  }
229
- }
230
- if (filters.since !== void 0) {
231
- conditions.push(gte(auditLogs.timestamp, resolveTimeFilter(filters.since)));
232
- }
233
- if (filters.until !== void 0) {
234
- conditions.push(lte(auditLogs.timestamp, resolveTimeFilter(filters.until)));
235
- }
236
- if (filters.searchText !== void 0 && filters.searchText.length > 0) {
237
- const escaped = escapeLikePattern(filters.searchText);
238
- const pattern = `%${escaped}%`;
239
- const searchCondition = or(
240
- ilike(auditLogs.label, pattern),
241
- ilike(auditLogs.description, pattern)
242
- );
243
- if (searchCondition !== void 0) {
244
- conditions.push(searchCondition);
198
+ case "search": {
199
+ return or(
200
+ ilike(auditLogs.label, condition.pattern),
201
+ ilike(auditLogs.description, condition.pattern)
202
+ );
203
+ }
204
+ case "compliance": {
205
+ return sql`${auditLogs.compliance} @> ${JSON.stringify(condition.tags)}::jsonb`;
206
+ }
207
+ case "cursor": {
208
+ const tsCompare = condition.sortOrder === "asc" ? gt : lt;
209
+ const idCompare = condition.sortOrder === "asc" ? gt : lt;
210
+ return or(
211
+ tsCompare(auditLogs.timestamp, condition.timestamp),
212
+ and(
213
+ eq(auditLogs.timestamp, condition.timestamp),
214
+ idCompare(auditLogs.id, condition.id)
215
+ )
216
+ );
245
217
  }
246
218
  }
247
- if (filters.compliance !== void 0 && filters.compliance.length > 0) {
248
- conditions.push(
249
- sql`${auditLogs.compliance} @> ${JSON.stringify(filters.compliance)}::jsonb`
250
- );
219
+ }
220
+ function buildWhereConditions(filters, cursor, sortOrder) {
221
+ const decoded = cursor !== void 0 ? decodeCursor(cursor) : void 0;
222
+ const irConditions = interpretFilters(filters, {
223
+ cursor: decoded,
224
+ sortOrder
225
+ });
226
+ const sqlConditions = [];
227
+ for (const c of irConditions) {
228
+ const mapped = mapCondition(c);
229
+ if (mapped !== void 0) {
230
+ sqlConditions.push(mapped);
231
+ }
251
232
  }
252
- if (conditions.length === 0) {
233
+ if (sqlConditions.length === 0) {
253
234
  return void 0;
254
235
  }
255
- return and(...conditions);
256
- }
257
- function buildCursorCondition(cursor, sortOrder) {
258
- const decoded = decodeCursor(cursor);
259
- const tsCompare = sortOrder === "asc" ? gt : lt;
260
- const idCompare = sortOrder === "asc" ? gt : lt;
261
- return or(
262
- tsCompare(auditLogs.timestamp, decoded.timestamp),
263
- and(
264
- eq(auditLogs.timestamp, decoded.timestamp),
265
- idCompare(auditLogs.id, decoded.id)
266
- )
267
- );
236
+ return and(...sqlConditions);
268
237
  }
269
238
  function buildOrderBy(sortOrder) {
270
239
  if (sortOrder === "asc") {
@@ -272,47 +241,10 @@ function buildOrderBy(sortOrder) {
272
241
  }
273
242
  return [desc(auditLogs.timestamp), desc(auditLogs.id)];
274
243
  }
275
- function encodeCursor(timestamp2, id) {
276
- const payload = JSON.stringify({ t: timestamp2.toISOString(), i: id });
277
- return btoa(payload);
278
- }
279
- var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
280
- function decodeCursor(cursor) {
281
- let parsed;
282
- try {
283
- parsed = JSON.parse(atob(cursor));
284
- } catch {
285
- throw new Error("Invalid cursor: failed to decode");
286
- }
287
- if (typeof parsed !== "object" || parsed === null || !("t" in parsed) || !("i" in parsed)) {
288
- throw new Error("Invalid cursor: missing required fields");
289
- }
290
- const { t, i } = parsed;
291
- if (typeof t !== "string" || typeof i !== "string") {
292
- throw new Error("Invalid cursor: fields must be strings");
293
- }
294
- const timestamp2 = new Date(t);
295
- if (isNaN(timestamp2.getTime())) {
296
- throw new Error("Invalid cursor: invalid timestamp");
297
- }
298
- if (!UUID_PATTERN.test(i)) {
299
- throw new Error("Invalid cursor: id must be a valid UUID");
300
- }
301
- return { timestamp: timestamp2, id: i };
302
- }
303
244
 
304
245
  // src/adapter.ts
305
246
  var DEFAULT_LIMIT = 50;
306
247
  var MAX_LIMIT = 250;
307
- function toCount(value) {
308
- if (typeof value === "number") {
309
- return value;
310
- }
311
- if (typeof value === "string") {
312
- return Number(value);
313
- }
314
- return 0;
315
- }
316
248
  function drizzleAuditAdapter(db) {
317
249
  return {
318
250
  async writeLog(log) {
@@ -322,9 +254,7 @@ function drizzleAuditAdapter(db) {
322
254
  async queryLogs(spec) {
323
255
  const sortOrder = spec.sortOrder ?? "desc";
324
256
  const limit = Math.min(spec.limit ?? DEFAULT_LIMIT, MAX_LIMIT);
325
- const whereCondition = buildWhereConditions(spec.filters);
326
- const cursorCondition = spec.cursor !== void 0 ? buildCursorCondition(spec.cursor, sortOrder) : void 0;
327
- const combined = and2(whereCondition, cursorCondition);
257
+ const combined = buildWhereConditions(spec.filters, spec.cursor, sortOrder);
328
258
  const fetchLimit = limit + 1;
329
259
  const orderColumns = buildOrderBy(sortOrder);
330
260
  const query = db.select().from(auditLogs).where(combined).orderBy(...orderColumns).limit(fetchLimit);
@@ -419,42 +349,9 @@ function drizzleAuditAdapter(db) {
419
349
  }
420
350
  };
421
351
  }
422
- function assembleStats(summaryRows, eventsPerDayRows, topActorsRows, topTablesRows, operationRows, severityRows) {
423
- const summary = summaryRows[0];
424
- const totalLogs = summary !== void 0 ? toCount(summary.totalLogs) : 0;
425
- const tablesAudited = summary !== void 0 ? toCount(summary.tablesAudited) : 0;
426
- const eventsPerDay = eventsPerDayRows.map((row) => ({
427
- date: row.date instanceof Date ? row.date.toISOString().split("T")[0] : String(row.date),
428
- count: toCount(row.count)
429
- }));
430
- const topActors = topActorsRows.map((row) => ({
431
- actorId: String(row.actorId),
432
- count: toCount(row.count)
433
- }));
434
- const topTables = topTablesRows.map((row) => ({
435
- tableName: String(row.tableName),
436
- count: toCount(row.count)
437
- }));
438
- const operationBreakdown = {};
439
- for (const row of operationRows) {
440
- operationBreakdown[String(row.operation)] = toCount(row.count);
441
- }
442
- const severityBreakdown = {};
443
- for (const row of severityRows) {
444
- severityBreakdown[String(row.severity)] = toCount(row.count);
445
- }
446
- return {
447
- totalLogs,
448
- tablesAudited,
449
- eventsPerDay,
450
- topActors,
451
- topTables,
452
- operationBreakdown,
453
- severityBreakdown
454
- };
455
- }
456
352
 
457
353
  // src/sqlite-adapter.ts
354
+ import { encodeCursor as encodeCursor2, toCount, assembleStats as assembleStats2 } from "@usebetterdev/audit-core";
458
355
  import { and as and4, eq as eq4, gte as gte4, lt as lt4, isNotNull as isNotNull2, sql as sql4, desc as desc4 } from "drizzle-orm";
459
356
 
460
357
  // src/sqlite-schema.ts
@@ -503,23 +400,7 @@ var sqliteAuditLogs = sqliteTable(
503
400
  );
504
401
 
505
402
  // src/sqlite-column-map.ts
506
- var VALID_OPERATIONS2 = /* @__PURE__ */ new Set([
507
- "INSERT",
508
- "UPDATE",
509
- "DELETE"
510
- ]);
511
- var VALID_SEVERITIES2 = /* @__PURE__ */ new Set([
512
- "low",
513
- "medium",
514
- "high",
515
- "critical"
516
- ]);
517
- function isAuditOperation2(value) {
518
- return VALID_OPERATIONS2.has(value);
519
- }
520
- function isAuditSeverity2(value) {
521
- return VALID_SEVERITIES2.has(value);
522
- }
403
+ import { isAuditOperation as isAuditOperation2, isAuditSeverity as isAuditSeverity2 } from "@usebetterdev/audit-core";
523
404
  function sqliteAuditLogToRow(log) {
524
405
  const row = {
525
406
  id: log.id,
@@ -624,7 +505,10 @@ function sqliteRowToAuditLog(row) {
624
505
  }
625
506
 
626
507
  // src/sqlite-query.ts
627
- import { parseDuration as parseDuration2 } from "@usebetterdev/audit-core";
508
+ import {
509
+ decodeCursor as decodeCursor2,
510
+ interpretFilters as interpretFilters2
511
+ } from "@usebetterdev/audit-core";
628
512
  import {
629
513
  and as and3,
630
514
  or as or2,
@@ -639,87 +523,72 @@ import {
639
523
  desc as desc3,
640
524
  sql as sql3
641
525
  } from "drizzle-orm";
642
- function escapeLikePattern2(input) {
643
- return input.replace(/[%_\\]/g, "\\$&");
644
- }
645
- function resolveTimeFilter2(filter) {
646
- if ("date" in filter && filter.date !== void 0) {
647
- return filter.date;
648
- }
649
- if ("duration" in filter && filter.duration !== void 0) {
650
- return parseDuration2(filter.duration);
651
- }
652
- throw new Error("TimeFilter must have either date or duration");
653
- }
654
- function buildSqliteWhereConditions(filters) {
655
- const conditions = [];
656
- if (filters.resource !== void 0) {
657
- conditions.push(eq3(sqliteAuditLogs.tableName, filters.resource.tableName));
658
- if (filters.resource.recordId !== void 0) {
659
- conditions.push(eq3(sqliteAuditLogs.recordId, filters.resource.recordId));
526
+ var FIELD_COLUMNS2 = {
527
+ tableName: sqliteAuditLogs.tableName,
528
+ recordId: sqliteAuditLogs.recordId,
529
+ actorId: sqliteAuditLogs.actorId,
530
+ severity: sqliteAuditLogs.severity,
531
+ operation: sqliteAuditLogs.operation
532
+ };
533
+ function mapCondition2(condition) {
534
+ switch (condition.kind) {
535
+ case "eq": {
536
+ return eq3(FIELD_COLUMNS2[condition.field], condition.value);
660
537
  }
661
- }
662
- if (filters.actorIds !== void 0 && filters.actorIds.length > 0) {
663
- if (filters.actorIds.length === 1) {
664
- conditions.push(eq3(sqliteAuditLogs.actorId, filters.actorIds[0]));
665
- } else {
666
- conditions.push(inArray2(sqliteAuditLogs.actorId, filters.actorIds));
538
+ case "in": {
539
+ return inArray2(FIELD_COLUMNS2[condition.field], condition.values);
667
540
  }
668
- }
669
- if (filters.severities !== void 0 && filters.severities.length > 0) {
670
- if (filters.severities.length === 1) {
671
- conditions.push(eq3(sqliteAuditLogs.severity, filters.severities[0]));
672
- } else {
673
- conditions.push(inArray2(sqliteAuditLogs.severity, filters.severities));
541
+ case "timestampGte": {
542
+ return gte3(sqliteAuditLogs.timestamp, condition.value);
674
543
  }
675
- }
676
- if (filters.operations !== void 0 && filters.operations.length > 0) {
677
- if (filters.operations.length === 1) {
678
- conditions.push(eq3(sqliteAuditLogs.operation, filters.operations[0]));
679
- } else {
680
- conditions.push(inArray2(sqliteAuditLogs.operation, filters.operations));
544
+ case "timestampLte": {
545
+ return lte2(sqliteAuditLogs.timestamp, condition.value);
681
546
  }
682
- }
683
- if (filters.since !== void 0) {
684
- conditions.push(gte3(sqliteAuditLogs.timestamp, resolveTimeFilter2(filters.since)));
685
- }
686
- if (filters.until !== void 0) {
687
- conditions.push(lte2(sqliteAuditLogs.timestamp, resolveTimeFilter2(filters.until)));
688
- }
689
- if (filters.searchText !== void 0 && filters.searchText.length > 0) {
690
- const escaped = escapeLikePattern2(filters.searchText);
691
- const pattern = `%${escaped}%`;
692
- const searchCondition = or2(
693
- like(sqliteAuditLogs.label, pattern),
694
- like(sqliteAuditLogs.description, pattern)
695
- );
696
- if (searchCondition !== void 0) {
697
- conditions.push(searchCondition);
547
+ case "search": {
548
+ return or2(
549
+ like(sqliteAuditLogs.label, condition.pattern),
550
+ like(sqliteAuditLogs.description, condition.pattern)
551
+ );
698
552
  }
699
- }
700
- if (filters.compliance !== void 0 && filters.compliance.length > 0) {
701
- for (const tag of filters.compliance) {
702
- conditions.push(
703
- sql3`EXISTS (SELECT 1 FROM json_each(${sqliteAuditLogs.compliance}) WHERE value = ${tag})`
553
+ case "compliance": {
554
+ const tagConditions = [];
555
+ for (const tag of condition.tags) {
556
+ tagConditions.push(
557
+ sql3`EXISTS (SELECT 1 FROM json_each(${sqliteAuditLogs.compliance}) WHERE value = ${tag})`
558
+ );
559
+ }
560
+ return and3(...tagConditions);
561
+ }
562
+ case "cursor": {
563
+ const tsCompare = condition.sortOrder === "asc" ? gt2 : lt3;
564
+ const idCompare = condition.sortOrder === "asc" ? gt2 : lt3;
565
+ return or2(
566
+ tsCompare(sqliteAuditLogs.timestamp, condition.timestamp),
567
+ and3(
568
+ eq3(sqliteAuditLogs.timestamp, condition.timestamp),
569
+ idCompare(sqliteAuditLogs.id, condition.id)
570
+ )
704
571
  );
705
572
  }
706
573
  }
707
- if (conditions.length === 0) {
574
+ }
575
+ function buildSqliteWhereConditions(filters, cursor, sortOrder) {
576
+ const decoded = cursor !== void 0 ? decodeCursor2(cursor) : void 0;
577
+ const irConditions = interpretFilters2(filters, {
578
+ cursor: decoded,
579
+ sortOrder
580
+ });
581
+ const sqlConditions = [];
582
+ for (const c of irConditions) {
583
+ const mapped = mapCondition2(c);
584
+ if (mapped !== void 0) {
585
+ sqlConditions.push(mapped);
586
+ }
587
+ }
588
+ if (sqlConditions.length === 0) {
708
589
  return void 0;
709
590
  }
710
- return and3(...conditions);
711
- }
712
- function buildSqliteCursorCondition(cursor, sortOrder) {
713
- const decoded = decodeSqliteCursor(cursor);
714
- const tsCompare = sortOrder === "asc" ? gt2 : lt3;
715
- const idCompare = sortOrder === "asc" ? gt2 : lt3;
716
- return or2(
717
- tsCompare(sqliteAuditLogs.timestamp, decoded.timestamp),
718
- and3(
719
- eq3(sqliteAuditLogs.timestamp, decoded.timestamp),
720
- idCompare(sqliteAuditLogs.id, decoded.id)
721
- )
722
- );
591
+ return and3(...sqlConditions);
723
592
  }
724
593
  function buildSqliteOrderBy(sortOrder) {
725
594
  if (sortOrder === "asc") {
@@ -727,47 +596,10 @@ function buildSqliteOrderBy(sortOrder) {
727
596
  }
728
597
  return [desc3(sqliteAuditLogs.timestamp), desc3(sqliteAuditLogs.id)];
729
598
  }
730
- function encodeSqliteCursor(timestamp2, id) {
731
- const payload = JSON.stringify({ t: timestamp2.toISOString(), i: id });
732
- return btoa(payload);
733
- }
734
- var UUID_PATTERN2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
735
- function decodeSqliteCursor(cursor) {
736
- let parsed;
737
- try {
738
- parsed = JSON.parse(atob(cursor));
739
- } catch {
740
- throw new Error("Invalid cursor: failed to decode");
741
- }
742
- if (typeof parsed !== "object" || parsed === null || !("t" in parsed) || !("i" in parsed)) {
743
- throw new Error("Invalid cursor: missing required fields");
744
- }
745
- const { t, i } = parsed;
746
- if (typeof t !== "string" || typeof i !== "string") {
747
- throw new Error("Invalid cursor: fields must be strings");
748
- }
749
- const timestamp2 = new Date(t);
750
- if (isNaN(timestamp2.getTime())) {
751
- throw new Error("Invalid cursor: invalid timestamp");
752
- }
753
- if (!UUID_PATTERN2.test(i)) {
754
- throw new Error("Invalid cursor: id must be a valid UUID");
755
- }
756
- return { timestamp: timestamp2, id: i };
757
- }
758
599
 
759
600
  // src/sqlite-adapter.ts
760
601
  var DEFAULT_LIMIT2 = 50;
761
602
  var MAX_LIMIT2 = 250;
762
- function toCount2(value) {
763
- if (typeof value === "number") {
764
- return value;
765
- }
766
- if (typeof value === "string") {
767
- return Number(value);
768
- }
769
- return 0;
770
- }
771
603
  function drizzleSqliteAuditAdapter(db) {
772
604
  return {
773
605
  async writeLog(log) {
@@ -777,9 +609,7 @@ function drizzleSqliteAuditAdapter(db) {
777
609
  async queryLogs(spec) {
778
610
  const sortOrder = spec.sortOrder ?? "desc";
779
611
  const limit = Math.min(spec.limit ?? DEFAULT_LIMIT2, MAX_LIMIT2);
780
- const whereCondition = buildSqliteWhereConditions(spec.filters);
781
- const cursorCondition = spec.cursor !== void 0 ? buildSqliteCursorCondition(spec.cursor, sortOrder) : void 0;
782
- const combined = and4(whereCondition, cursorCondition);
612
+ const combined = buildSqliteWhereConditions(spec.filters, spec.cursor, sortOrder);
783
613
  const fetchLimit = limit + 1;
784
614
  const orderColumns = buildSqliteOrderBy(sortOrder);
785
615
  const query = db.select().from(sqliteAuditLogs).where(combined).orderBy(...orderColumns).limit(fetchLimit);
@@ -789,7 +619,7 @@ function drizzleSqliteAuditAdapter(db) {
789
619
  const entries = resultRows.map(sqliteRowToAuditLog);
790
620
  const lastRow = resultRows[resultRows.length - 1];
791
621
  if (hasNextPage && lastRow !== void 0) {
792
- return { entries, nextCursor: encodeSqliteCursor(lastRow.timestamp, lastRow.id) };
622
+ return { entries, nextCursor: encodeCursor2(lastRow.timestamp, lastRow.id) };
793
623
  }
794
624
  return { entries };
795
625
  },
@@ -812,7 +642,7 @@ function drizzleSqliteAuditAdapter(db) {
812
642
  }
813
643
  await db.delete(sqliteAuditLogs).where(and4(...conditions));
814
644
  const changesResult = await db.select({ count: sql4`changes()` }).from(sqliteAuditLogs);
815
- const deletedCount = changesResult[0] !== void 0 ? toCount2(changesResult[0].count) : 0;
645
+ const deletedCount = changesResult[0] !== void 0 ? toCount(changesResult[0].count) : 0;
816
646
  return { deletedCount };
817
647
  },
818
648
  async getStats(options) {
@@ -868,40 +698,6 @@ function drizzleSqliteAuditAdapter(db) {
868
698
  }
869
699
  };
870
700
  }
871
- function assembleStats2(summaryRows, eventsPerDayRows, topActorsRows, topTablesRows, operationRows, severityRows) {
872
- const summary = summaryRows[0];
873
- const totalLogs = summary !== void 0 ? toCount2(summary.totalLogs) : 0;
874
- const tablesAudited = summary !== void 0 ? toCount2(summary.tablesAudited) : 0;
875
- const eventsPerDay = eventsPerDayRows.map((row) => ({
876
- date: String(row.date),
877
- count: toCount2(row.count)
878
- }));
879
- const topActors = topActorsRows.map((row) => ({
880
- actorId: String(row.actorId),
881
- count: toCount2(row.count)
882
- }));
883
- const topTables = topTablesRows.map((row) => ({
884
- tableName: String(row.tableName),
885
- count: toCount2(row.count)
886
- }));
887
- const operationBreakdown = {};
888
- for (const row of operationRows) {
889
- operationBreakdown[String(row.operation)] = toCount2(row.count);
890
- }
891
- const severityBreakdown = {};
892
- for (const row of severityRows) {
893
- severityBreakdown[String(row.severity)] = toCount2(row.count);
894
- }
895
- return {
896
- totalLogs,
897
- tablesAudited,
898
- eventsPerDay,
899
- topActors,
900
- topTables,
901
- operationBreakdown,
902
- severityBreakdown
903
- };
904
- }
905
701
 
906
702
  // src/proxy.ts
907
703
  import { getTableName } from "drizzle-orm";
@@ -1394,15 +1190,17 @@ async function fireCaptureLog(result, ctx, state) {
1394
1190
  }
1395
1191
  }
1396
1192
  }
1193
+
1194
+ // src/index.ts
1195
+ import { encodeCursor as encodeCursor3, decodeCursor as decodeCursor3 } from "@usebetterdev/audit-core";
1397
1196
  export {
1398
1197
  auditLogs,
1399
- buildCursorCondition,
1400
1198
  buildOrderBy,
1401
1199
  buildWhereConditions,
1402
- decodeCursor,
1200
+ decodeCursor3 as decodeCursor,
1403
1201
  drizzleAuditAdapter,
1404
1202
  drizzleSqliteAuditAdapter,
1405
- encodeCursor,
1203
+ encodeCursor3 as encodeCursor,
1406
1204
  sqliteAuditLogs,
1407
1205
  withAuditProxy
1408
1206
  };