@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.cjs +129 -338
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -42
- package/dist/index.d.ts +40 -42
- package/dist/index.js +128 -330
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -21,19 +21,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
auditLogs: () => auditLogs,
|
|
24
|
-
buildCursorCondition: () => buildCursorCondition,
|
|
25
24
|
buildOrderBy: () => buildOrderBy,
|
|
26
25
|
buildWhereConditions: () => buildWhereConditions,
|
|
27
|
-
decodeCursor: () => decodeCursor,
|
|
26
|
+
decodeCursor: () => import_audit_core7.decodeCursor,
|
|
28
27
|
drizzleAuditAdapter: () => drizzleAuditAdapter,
|
|
29
28
|
drizzleSqliteAuditAdapter: () => drizzleSqliteAuditAdapter,
|
|
30
|
-
encodeCursor: () => encodeCursor,
|
|
29
|
+
encodeCursor: () => import_audit_core7.encodeCursor,
|
|
31
30
|
sqliteAuditLogs: () => sqliteAuditLogs,
|
|
32
31
|
withAuditProxy: () => withAuditProxy
|
|
33
32
|
});
|
|
34
33
|
module.exports = __toCommonJS(index_exports);
|
|
35
34
|
|
|
36
35
|
// src/adapter.ts
|
|
36
|
+
var import_audit_core3 = require("@usebetterdev/audit-core");
|
|
37
37
|
var import_drizzle_orm2 = require("drizzle-orm");
|
|
38
38
|
|
|
39
39
|
// src/schema.ts
|
|
@@ -77,23 +77,7 @@ var auditLogs = (0, import_pg_core.pgTable)(
|
|
|
77
77
|
);
|
|
78
78
|
|
|
79
79
|
// src/column-map.ts
|
|
80
|
-
var
|
|
81
|
-
"INSERT",
|
|
82
|
-
"UPDATE",
|
|
83
|
-
"DELETE"
|
|
84
|
-
]);
|
|
85
|
-
var VALID_SEVERITIES = /* @__PURE__ */ new Set([
|
|
86
|
-
"low",
|
|
87
|
-
"medium",
|
|
88
|
-
"high",
|
|
89
|
-
"critical"
|
|
90
|
-
]);
|
|
91
|
-
function isAuditOperation(value) {
|
|
92
|
-
return VALID_OPERATIONS.has(value);
|
|
93
|
-
}
|
|
94
|
-
function isAuditSeverity(value) {
|
|
95
|
-
return VALID_SEVERITIES.has(value);
|
|
96
|
-
}
|
|
80
|
+
var import_audit_core = require("@usebetterdev/audit-core");
|
|
97
81
|
function auditLogToRow(log) {
|
|
98
82
|
const row = {
|
|
99
83
|
id: log.id,
|
|
@@ -141,7 +125,7 @@ function auditLogToRow(log) {
|
|
|
141
125
|
return row;
|
|
142
126
|
}
|
|
143
127
|
function rowToAuditLog(row) {
|
|
144
|
-
if (!isAuditOperation(row.operation)) {
|
|
128
|
+
if (!(0, import_audit_core.isAuditOperation)(row.operation)) {
|
|
145
129
|
throw new Error(
|
|
146
130
|
`Invalid audit operation: "${row.operation}". Expected one of: INSERT, UPDATE, DELETE`
|
|
147
131
|
);
|
|
@@ -172,7 +156,7 @@ function rowToAuditLog(row) {
|
|
|
172
156
|
log.description = row.description;
|
|
173
157
|
}
|
|
174
158
|
if (row.severity !== null && row.severity !== void 0) {
|
|
175
|
-
if (!isAuditSeverity(row.severity)) {
|
|
159
|
+
if (!(0, import_audit_core.isAuditSeverity)(row.severity)) {
|
|
176
160
|
throw new Error(
|
|
177
161
|
`Invalid audit severity: "${row.severity}". Expected one of: low, medium, high, critical`
|
|
178
162
|
);
|
|
@@ -198,87 +182,68 @@ function rowToAuditLog(row) {
|
|
|
198
182
|
}
|
|
199
183
|
|
|
200
184
|
// src/query.ts
|
|
201
|
-
var
|
|
185
|
+
var import_audit_core2 = require("@usebetterdev/audit-core");
|
|
202
186
|
var import_drizzle_orm = require("drizzle-orm");
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
function buildWhereConditions(filters) {
|
|
216
|
-
const conditions = [];
|
|
217
|
-
if (filters.resource !== void 0) {
|
|
218
|
-
conditions.push((0, import_drizzle_orm.eq)(auditLogs.tableName, filters.resource.tableName));
|
|
219
|
-
if (filters.resource.recordId !== void 0) {
|
|
220
|
-
conditions.push((0, import_drizzle_orm.eq)(auditLogs.recordId, filters.resource.recordId));
|
|
187
|
+
var FIELD_COLUMNS = {
|
|
188
|
+
tableName: auditLogs.tableName,
|
|
189
|
+
recordId: auditLogs.recordId,
|
|
190
|
+
actorId: auditLogs.actorId,
|
|
191
|
+
severity: auditLogs.severity,
|
|
192
|
+
operation: auditLogs.operation
|
|
193
|
+
};
|
|
194
|
+
function mapCondition(condition) {
|
|
195
|
+
switch (condition.kind) {
|
|
196
|
+
case "eq": {
|
|
197
|
+
return (0, import_drizzle_orm.eq)(FIELD_COLUMNS[condition.field], condition.value);
|
|
221
198
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if (filters.actorIds.length === 1) {
|
|
225
|
-
conditions.push((0, import_drizzle_orm.eq)(auditLogs.actorId, filters.actorIds[0]));
|
|
226
|
-
} else {
|
|
227
|
-
conditions.push((0, import_drizzle_orm.inArray)(auditLogs.actorId, filters.actorIds));
|
|
199
|
+
case "in": {
|
|
200
|
+
return (0, import_drizzle_orm.inArray)(FIELD_COLUMNS[condition.field], condition.values);
|
|
228
201
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (filters.severities.length === 1) {
|
|
232
|
-
conditions.push((0, import_drizzle_orm.eq)(auditLogs.severity, filters.severities[0]));
|
|
233
|
-
} else {
|
|
234
|
-
conditions.push((0, import_drizzle_orm.inArray)(auditLogs.severity, filters.severities));
|
|
202
|
+
case "timestampGte": {
|
|
203
|
+
return (0, import_drizzle_orm.gte)(auditLogs.timestamp, condition.value);
|
|
235
204
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (filters.operations.length === 1) {
|
|
239
|
-
conditions.push((0, import_drizzle_orm.eq)(auditLogs.operation, filters.operations[0]));
|
|
240
|
-
} else {
|
|
241
|
-
conditions.push((0, import_drizzle_orm.inArray)(auditLogs.operation, filters.operations));
|
|
205
|
+
case "timestampLte": {
|
|
206
|
+
return (0, import_drizzle_orm.lte)(auditLogs.timestamp, condition.value);
|
|
242
207
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
(0, import_drizzle_orm.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
208
|
+
case "search": {
|
|
209
|
+
return (0, import_drizzle_orm.or)(
|
|
210
|
+
(0, import_drizzle_orm.ilike)(auditLogs.label, condition.pattern),
|
|
211
|
+
(0, import_drizzle_orm.ilike)(auditLogs.description, condition.pattern)
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
case "compliance": {
|
|
215
|
+
return import_drizzle_orm.sql`${auditLogs.compliance} @> ${JSON.stringify(condition.tags)}::jsonb`;
|
|
216
|
+
}
|
|
217
|
+
case "cursor": {
|
|
218
|
+
const tsCompare = condition.sortOrder === "asc" ? import_drizzle_orm.gt : import_drizzle_orm.lt;
|
|
219
|
+
const idCompare = condition.sortOrder === "asc" ? import_drizzle_orm.gt : import_drizzle_orm.lt;
|
|
220
|
+
return (0, import_drizzle_orm.or)(
|
|
221
|
+
tsCompare(auditLogs.timestamp, condition.timestamp),
|
|
222
|
+
(0, import_drizzle_orm.and)(
|
|
223
|
+
(0, import_drizzle_orm.eq)(auditLogs.timestamp, condition.timestamp),
|
|
224
|
+
idCompare(auditLogs.id, condition.id)
|
|
225
|
+
)
|
|
226
|
+
);
|
|
259
227
|
}
|
|
260
228
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
229
|
+
}
|
|
230
|
+
function buildWhereConditions(filters, cursor, sortOrder) {
|
|
231
|
+
const decoded = cursor !== void 0 ? (0, import_audit_core2.decodeCursor)(cursor) : void 0;
|
|
232
|
+
const irConditions = (0, import_audit_core2.interpretFilters)(filters, {
|
|
233
|
+
cursor: decoded,
|
|
234
|
+
sortOrder
|
|
235
|
+
});
|
|
236
|
+
const sqlConditions = [];
|
|
237
|
+
for (const c of irConditions) {
|
|
238
|
+
const mapped = mapCondition(c);
|
|
239
|
+
if (mapped !== void 0) {
|
|
240
|
+
sqlConditions.push(mapped);
|
|
241
|
+
}
|
|
265
242
|
}
|
|
266
|
-
if (
|
|
243
|
+
if (sqlConditions.length === 0) {
|
|
267
244
|
return void 0;
|
|
268
245
|
}
|
|
269
|
-
return (0, import_drizzle_orm.and)(...
|
|
270
|
-
}
|
|
271
|
-
function buildCursorCondition(cursor, sortOrder) {
|
|
272
|
-
const decoded = decodeCursor(cursor);
|
|
273
|
-
const tsCompare = sortOrder === "asc" ? import_drizzle_orm.gt : import_drizzle_orm.lt;
|
|
274
|
-
const idCompare = sortOrder === "asc" ? import_drizzle_orm.gt : import_drizzle_orm.lt;
|
|
275
|
-
return (0, import_drizzle_orm.or)(
|
|
276
|
-
tsCompare(auditLogs.timestamp, decoded.timestamp),
|
|
277
|
-
(0, import_drizzle_orm.and)(
|
|
278
|
-
(0, import_drizzle_orm.eq)(auditLogs.timestamp, decoded.timestamp),
|
|
279
|
-
idCompare(auditLogs.id, decoded.id)
|
|
280
|
-
)
|
|
281
|
-
);
|
|
246
|
+
return (0, import_drizzle_orm.and)(...sqlConditions);
|
|
282
247
|
}
|
|
283
248
|
function buildOrderBy(sortOrder) {
|
|
284
249
|
if (sortOrder === "asc") {
|
|
@@ -286,47 +251,10 @@ function buildOrderBy(sortOrder) {
|
|
|
286
251
|
}
|
|
287
252
|
return [(0, import_drizzle_orm.desc)(auditLogs.timestamp), (0, import_drizzle_orm.desc)(auditLogs.id)];
|
|
288
253
|
}
|
|
289
|
-
function encodeCursor(timestamp2, id) {
|
|
290
|
-
const payload = JSON.stringify({ t: timestamp2.toISOString(), i: id });
|
|
291
|
-
return btoa(payload);
|
|
292
|
-
}
|
|
293
|
-
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
294
|
-
function decodeCursor(cursor) {
|
|
295
|
-
let parsed;
|
|
296
|
-
try {
|
|
297
|
-
parsed = JSON.parse(atob(cursor));
|
|
298
|
-
} catch {
|
|
299
|
-
throw new Error("Invalid cursor: failed to decode");
|
|
300
|
-
}
|
|
301
|
-
if (typeof parsed !== "object" || parsed === null || !("t" in parsed) || !("i" in parsed)) {
|
|
302
|
-
throw new Error("Invalid cursor: missing required fields");
|
|
303
|
-
}
|
|
304
|
-
const { t, i } = parsed;
|
|
305
|
-
if (typeof t !== "string" || typeof i !== "string") {
|
|
306
|
-
throw new Error("Invalid cursor: fields must be strings");
|
|
307
|
-
}
|
|
308
|
-
const timestamp2 = new Date(t);
|
|
309
|
-
if (isNaN(timestamp2.getTime())) {
|
|
310
|
-
throw new Error("Invalid cursor: invalid timestamp");
|
|
311
|
-
}
|
|
312
|
-
if (!UUID_PATTERN.test(i)) {
|
|
313
|
-
throw new Error("Invalid cursor: id must be a valid UUID");
|
|
314
|
-
}
|
|
315
|
-
return { timestamp: timestamp2, id: i };
|
|
316
|
-
}
|
|
317
254
|
|
|
318
255
|
// src/adapter.ts
|
|
319
256
|
var DEFAULT_LIMIT = 50;
|
|
320
257
|
var MAX_LIMIT = 250;
|
|
321
|
-
function toCount(value) {
|
|
322
|
-
if (typeof value === "number") {
|
|
323
|
-
return value;
|
|
324
|
-
}
|
|
325
|
-
if (typeof value === "string") {
|
|
326
|
-
return Number(value);
|
|
327
|
-
}
|
|
328
|
-
return 0;
|
|
329
|
-
}
|
|
330
258
|
function drizzleAuditAdapter(db) {
|
|
331
259
|
return {
|
|
332
260
|
async writeLog(log) {
|
|
@@ -336,9 +264,7 @@ function drizzleAuditAdapter(db) {
|
|
|
336
264
|
async queryLogs(spec) {
|
|
337
265
|
const sortOrder = spec.sortOrder ?? "desc";
|
|
338
266
|
const limit = Math.min(spec.limit ?? DEFAULT_LIMIT, MAX_LIMIT);
|
|
339
|
-
const
|
|
340
|
-
const cursorCondition = spec.cursor !== void 0 ? buildCursorCondition(spec.cursor, sortOrder) : void 0;
|
|
341
|
-
const combined = (0, import_drizzle_orm2.and)(whereCondition, cursorCondition);
|
|
267
|
+
const combined = buildWhereConditions(spec.filters, spec.cursor, sortOrder);
|
|
342
268
|
const fetchLimit = limit + 1;
|
|
343
269
|
const orderColumns = buildOrderBy(sortOrder);
|
|
344
270
|
const query = db.select().from(auditLogs).where(combined).orderBy(...orderColumns).limit(fetchLimit);
|
|
@@ -348,7 +274,7 @@ function drizzleAuditAdapter(db) {
|
|
|
348
274
|
const entries = resultRows.map(rowToAuditLog);
|
|
349
275
|
const lastRow = resultRows[resultRows.length - 1];
|
|
350
276
|
if (hasNextPage && lastRow !== void 0) {
|
|
351
|
-
return { entries, nextCursor: encodeCursor(lastRow.timestamp, lastRow.id) };
|
|
277
|
+
return { entries, nextCursor: (0, import_audit_core3.encodeCursor)(lastRow.timestamp, lastRow.id) };
|
|
352
278
|
}
|
|
353
279
|
return { entries };
|
|
354
280
|
},
|
|
@@ -422,7 +348,7 @@ function drizzleAuditAdapter(db) {
|
|
|
422
348
|
operationRows,
|
|
423
349
|
severityRows
|
|
424
350
|
] = results;
|
|
425
|
-
return assembleStats(
|
|
351
|
+
return (0, import_audit_core3.assembleStats)(
|
|
426
352
|
summaryRows,
|
|
427
353
|
eventsPerDayRows,
|
|
428
354
|
topActorsRows,
|
|
@@ -433,42 +359,9 @@ function drizzleAuditAdapter(db) {
|
|
|
433
359
|
}
|
|
434
360
|
};
|
|
435
361
|
}
|
|
436
|
-
function assembleStats(summaryRows, eventsPerDayRows, topActorsRows, topTablesRows, operationRows, severityRows) {
|
|
437
|
-
const summary = summaryRows[0];
|
|
438
|
-
const totalLogs = summary !== void 0 ? toCount(summary.totalLogs) : 0;
|
|
439
|
-
const tablesAudited = summary !== void 0 ? toCount(summary.tablesAudited) : 0;
|
|
440
|
-
const eventsPerDay = eventsPerDayRows.map((row) => ({
|
|
441
|
-
date: row.date instanceof Date ? row.date.toISOString().split("T")[0] : String(row.date),
|
|
442
|
-
count: toCount(row.count)
|
|
443
|
-
}));
|
|
444
|
-
const topActors = topActorsRows.map((row) => ({
|
|
445
|
-
actorId: String(row.actorId),
|
|
446
|
-
count: toCount(row.count)
|
|
447
|
-
}));
|
|
448
|
-
const topTables = topTablesRows.map((row) => ({
|
|
449
|
-
tableName: String(row.tableName),
|
|
450
|
-
count: toCount(row.count)
|
|
451
|
-
}));
|
|
452
|
-
const operationBreakdown = {};
|
|
453
|
-
for (const row of operationRows) {
|
|
454
|
-
operationBreakdown[String(row.operation)] = toCount(row.count);
|
|
455
|
-
}
|
|
456
|
-
const severityBreakdown = {};
|
|
457
|
-
for (const row of severityRows) {
|
|
458
|
-
severityBreakdown[String(row.severity)] = toCount(row.count);
|
|
459
|
-
}
|
|
460
|
-
return {
|
|
461
|
-
totalLogs,
|
|
462
|
-
tablesAudited,
|
|
463
|
-
eventsPerDay,
|
|
464
|
-
topActors,
|
|
465
|
-
topTables,
|
|
466
|
-
operationBreakdown,
|
|
467
|
-
severityBreakdown
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
362
|
|
|
471
363
|
// src/sqlite-adapter.ts
|
|
364
|
+
var import_audit_core6 = require("@usebetterdev/audit-core");
|
|
472
365
|
var import_drizzle_orm4 = require("drizzle-orm");
|
|
473
366
|
|
|
474
367
|
// src/sqlite-schema.ts
|
|
@@ -512,23 +405,7 @@ var sqliteAuditLogs = (0, import_sqlite_core.sqliteTable)(
|
|
|
512
405
|
);
|
|
513
406
|
|
|
514
407
|
// src/sqlite-column-map.ts
|
|
515
|
-
var
|
|
516
|
-
"INSERT",
|
|
517
|
-
"UPDATE",
|
|
518
|
-
"DELETE"
|
|
519
|
-
]);
|
|
520
|
-
var VALID_SEVERITIES2 = /* @__PURE__ */ new Set([
|
|
521
|
-
"low",
|
|
522
|
-
"medium",
|
|
523
|
-
"high",
|
|
524
|
-
"critical"
|
|
525
|
-
]);
|
|
526
|
-
function isAuditOperation2(value) {
|
|
527
|
-
return VALID_OPERATIONS2.has(value);
|
|
528
|
-
}
|
|
529
|
-
function isAuditSeverity2(value) {
|
|
530
|
-
return VALID_SEVERITIES2.has(value);
|
|
531
|
-
}
|
|
408
|
+
var import_audit_core4 = require("@usebetterdev/audit-core");
|
|
532
409
|
function sqliteAuditLogToRow(log) {
|
|
533
410
|
const row = {
|
|
534
411
|
id: log.id,
|
|
@@ -576,7 +453,7 @@ function sqliteAuditLogToRow(log) {
|
|
|
576
453
|
return row;
|
|
577
454
|
}
|
|
578
455
|
function sqliteRowToAuditLog(row) {
|
|
579
|
-
if (!
|
|
456
|
+
if (!(0, import_audit_core4.isAuditOperation)(row.operation)) {
|
|
580
457
|
throw new Error(
|
|
581
458
|
`Invalid audit operation: "${row.operation}". Expected one of: INSERT, UPDATE, DELETE`
|
|
582
459
|
);
|
|
@@ -607,7 +484,7 @@ function sqliteRowToAuditLog(row) {
|
|
|
607
484
|
log.description = row.description;
|
|
608
485
|
}
|
|
609
486
|
if (row.severity !== null && row.severity !== void 0) {
|
|
610
|
-
if (!
|
|
487
|
+
if (!(0, import_audit_core4.isAuditSeverity)(row.severity)) {
|
|
611
488
|
throw new Error(
|
|
612
489
|
`Invalid audit severity: "${row.severity}". Expected one of: low, medium, high, critical`
|
|
613
490
|
);
|
|
@@ -633,89 +510,74 @@ function sqliteRowToAuditLog(row) {
|
|
|
633
510
|
}
|
|
634
511
|
|
|
635
512
|
// src/sqlite-query.ts
|
|
636
|
-
var
|
|
513
|
+
var import_audit_core5 = require("@usebetterdev/audit-core");
|
|
637
514
|
var import_drizzle_orm3 = require("drizzle-orm");
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
650
|
-
function buildSqliteWhereConditions(filters) {
|
|
651
|
-
const conditions = [];
|
|
652
|
-
if (filters.resource !== void 0) {
|
|
653
|
-
conditions.push((0, import_drizzle_orm3.eq)(sqliteAuditLogs.tableName, filters.resource.tableName));
|
|
654
|
-
if (filters.resource.recordId !== void 0) {
|
|
655
|
-
conditions.push((0, import_drizzle_orm3.eq)(sqliteAuditLogs.recordId, filters.resource.recordId));
|
|
515
|
+
var FIELD_COLUMNS2 = {
|
|
516
|
+
tableName: sqliteAuditLogs.tableName,
|
|
517
|
+
recordId: sqliteAuditLogs.recordId,
|
|
518
|
+
actorId: sqliteAuditLogs.actorId,
|
|
519
|
+
severity: sqliteAuditLogs.severity,
|
|
520
|
+
operation: sqliteAuditLogs.operation
|
|
521
|
+
};
|
|
522
|
+
function mapCondition2(condition) {
|
|
523
|
+
switch (condition.kind) {
|
|
524
|
+
case "eq": {
|
|
525
|
+
return (0, import_drizzle_orm3.eq)(FIELD_COLUMNS2[condition.field], condition.value);
|
|
656
526
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
if (filters.actorIds.length === 1) {
|
|
660
|
-
conditions.push((0, import_drizzle_orm3.eq)(sqliteAuditLogs.actorId, filters.actorIds[0]));
|
|
661
|
-
} else {
|
|
662
|
-
conditions.push((0, import_drizzle_orm3.inArray)(sqliteAuditLogs.actorId, filters.actorIds));
|
|
527
|
+
case "in": {
|
|
528
|
+
return (0, import_drizzle_orm3.inArray)(FIELD_COLUMNS2[condition.field], condition.values);
|
|
663
529
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
if (filters.severities.length === 1) {
|
|
667
|
-
conditions.push((0, import_drizzle_orm3.eq)(sqliteAuditLogs.severity, filters.severities[0]));
|
|
668
|
-
} else {
|
|
669
|
-
conditions.push((0, import_drizzle_orm3.inArray)(sqliteAuditLogs.severity, filters.severities));
|
|
530
|
+
case "timestampGte": {
|
|
531
|
+
return (0, import_drizzle_orm3.gte)(sqliteAuditLogs.timestamp, condition.value);
|
|
670
532
|
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
if (filters.operations.length === 1) {
|
|
674
|
-
conditions.push((0, import_drizzle_orm3.eq)(sqliteAuditLogs.operation, filters.operations[0]));
|
|
675
|
-
} else {
|
|
676
|
-
conditions.push((0, import_drizzle_orm3.inArray)(sqliteAuditLogs.operation, filters.operations));
|
|
533
|
+
case "timestampLte": {
|
|
534
|
+
return (0, import_drizzle_orm3.lte)(sqliteAuditLogs.timestamp, condition.value);
|
|
677
535
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
conditions.push((0, import_drizzle_orm3.lte)(sqliteAuditLogs.timestamp, resolveTimeFilter2(filters.until)));
|
|
684
|
-
}
|
|
685
|
-
if (filters.searchText !== void 0 && filters.searchText.length > 0) {
|
|
686
|
-
const escaped = escapeLikePattern2(filters.searchText);
|
|
687
|
-
const pattern = `%${escaped}%`;
|
|
688
|
-
const searchCondition = (0, import_drizzle_orm3.or)(
|
|
689
|
-
(0, import_drizzle_orm3.like)(sqliteAuditLogs.label, pattern),
|
|
690
|
-
(0, import_drizzle_orm3.like)(sqliteAuditLogs.description, pattern)
|
|
691
|
-
);
|
|
692
|
-
if (searchCondition !== void 0) {
|
|
693
|
-
conditions.push(searchCondition);
|
|
536
|
+
case "search": {
|
|
537
|
+
return (0, import_drizzle_orm3.or)(
|
|
538
|
+
(0, import_drizzle_orm3.like)(sqliteAuditLogs.label, condition.pattern),
|
|
539
|
+
(0, import_drizzle_orm3.like)(sqliteAuditLogs.description, condition.pattern)
|
|
540
|
+
);
|
|
694
541
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
542
|
+
case "compliance": {
|
|
543
|
+
const tagConditions = [];
|
|
544
|
+
for (const tag of condition.tags) {
|
|
545
|
+
tagConditions.push(
|
|
546
|
+
import_drizzle_orm3.sql`EXISTS (SELECT 1 FROM json_each(${sqliteAuditLogs.compliance}) WHERE value = ${tag})`
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
return (0, import_drizzle_orm3.and)(...tagConditions);
|
|
550
|
+
}
|
|
551
|
+
case "cursor": {
|
|
552
|
+
const tsCompare = condition.sortOrder === "asc" ? import_drizzle_orm3.gt : import_drizzle_orm3.lt;
|
|
553
|
+
const idCompare = condition.sortOrder === "asc" ? import_drizzle_orm3.gt : import_drizzle_orm3.lt;
|
|
554
|
+
return (0, import_drizzle_orm3.or)(
|
|
555
|
+
tsCompare(sqliteAuditLogs.timestamp, condition.timestamp),
|
|
556
|
+
(0, import_drizzle_orm3.and)(
|
|
557
|
+
(0, import_drizzle_orm3.eq)(sqliteAuditLogs.timestamp, condition.timestamp),
|
|
558
|
+
idCompare(sqliteAuditLogs.id, condition.id)
|
|
559
|
+
)
|
|
700
560
|
);
|
|
701
561
|
}
|
|
702
562
|
}
|
|
703
|
-
|
|
563
|
+
}
|
|
564
|
+
function buildSqliteWhereConditions(filters, cursor, sortOrder) {
|
|
565
|
+
const decoded = cursor !== void 0 ? (0, import_audit_core5.decodeCursor)(cursor) : void 0;
|
|
566
|
+
const irConditions = (0, import_audit_core5.interpretFilters)(filters, {
|
|
567
|
+
cursor: decoded,
|
|
568
|
+
sortOrder
|
|
569
|
+
});
|
|
570
|
+
const sqlConditions = [];
|
|
571
|
+
for (const c of irConditions) {
|
|
572
|
+
const mapped = mapCondition2(c);
|
|
573
|
+
if (mapped !== void 0) {
|
|
574
|
+
sqlConditions.push(mapped);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
if (sqlConditions.length === 0) {
|
|
704
578
|
return void 0;
|
|
705
579
|
}
|
|
706
|
-
return (0, import_drizzle_orm3.and)(...
|
|
707
|
-
}
|
|
708
|
-
function buildSqliteCursorCondition(cursor, sortOrder) {
|
|
709
|
-
const decoded = decodeSqliteCursor(cursor);
|
|
710
|
-
const tsCompare = sortOrder === "asc" ? import_drizzle_orm3.gt : import_drizzle_orm3.lt;
|
|
711
|
-
const idCompare = sortOrder === "asc" ? import_drizzle_orm3.gt : import_drizzle_orm3.lt;
|
|
712
|
-
return (0, import_drizzle_orm3.or)(
|
|
713
|
-
tsCompare(sqliteAuditLogs.timestamp, decoded.timestamp),
|
|
714
|
-
(0, import_drizzle_orm3.and)(
|
|
715
|
-
(0, import_drizzle_orm3.eq)(sqliteAuditLogs.timestamp, decoded.timestamp),
|
|
716
|
-
idCompare(sqliteAuditLogs.id, decoded.id)
|
|
717
|
-
)
|
|
718
|
-
);
|
|
580
|
+
return (0, import_drizzle_orm3.and)(...sqlConditions);
|
|
719
581
|
}
|
|
720
582
|
function buildSqliteOrderBy(sortOrder) {
|
|
721
583
|
if (sortOrder === "asc") {
|
|
@@ -723,47 +585,10 @@ function buildSqliteOrderBy(sortOrder) {
|
|
|
723
585
|
}
|
|
724
586
|
return [(0, import_drizzle_orm3.desc)(sqliteAuditLogs.timestamp), (0, import_drizzle_orm3.desc)(sqliteAuditLogs.id)];
|
|
725
587
|
}
|
|
726
|
-
function encodeSqliteCursor(timestamp2, id) {
|
|
727
|
-
const payload = JSON.stringify({ t: timestamp2.toISOString(), i: id });
|
|
728
|
-
return btoa(payload);
|
|
729
|
-
}
|
|
730
|
-
var UUID_PATTERN2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
731
|
-
function decodeSqliteCursor(cursor) {
|
|
732
|
-
let parsed;
|
|
733
|
-
try {
|
|
734
|
-
parsed = JSON.parse(atob(cursor));
|
|
735
|
-
} catch {
|
|
736
|
-
throw new Error("Invalid cursor: failed to decode");
|
|
737
|
-
}
|
|
738
|
-
if (typeof parsed !== "object" || parsed === null || !("t" in parsed) || !("i" in parsed)) {
|
|
739
|
-
throw new Error("Invalid cursor: missing required fields");
|
|
740
|
-
}
|
|
741
|
-
const { t, i } = parsed;
|
|
742
|
-
if (typeof t !== "string" || typeof i !== "string") {
|
|
743
|
-
throw new Error("Invalid cursor: fields must be strings");
|
|
744
|
-
}
|
|
745
|
-
const timestamp2 = new Date(t);
|
|
746
|
-
if (isNaN(timestamp2.getTime())) {
|
|
747
|
-
throw new Error("Invalid cursor: invalid timestamp");
|
|
748
|
-
}
|
|
749
|
-
if (!UUID_PATTERN2.test(i)) {
|
|
750
|
-
throw new Error("Invalid cursor: id must be a valid UUID");
|
|
751
|
-
}
|
|
752
|
-
return { timestamp: timestamp2, id: i };
|
|
753
|
-
}
|
|
754
588
|
|
|
755
589
|
// src/sqlite-adapter.ts
|
|
756
590
|
var DEFAULT_LIMIT2 = 50;
|
|
757
591
|
var MAX_LIMIT2 = 250;
|
|
758
|
-
function toCount2(value) {
|
|
759
|
-
if (typeof value === "number") {
|
|
760
|
-
return value;
|
|
761
|
-
}
|
|
762
|
-
if (typeof value === "string") {
|
|
763
|
-
return Number(value);
|
|
764
|
-
}
|
|
765
|
-
return 0;
|
|
766
|
-
}
|
|
767
592
|
function drizzleSqliteAuditAdapter(db) {
|
|
768
593
|
return {
|
|
769
594
|
async writeLog(log) {
|
|
@@ -773,9 +598,7 @@ function drizzleSqliteAuditAdapter(db) {
|
|
|
773
598
|
async queryLogs(spec) {
|
|
774
599
|
const sortOrder = spec.sortOrder ?? "desc";
|
|
775
600
|
const limit = Math.min(spec.limit ?? DEFAULT_LIMIT2, MAX_LIMIT2);
|
|
776
|
-
const
|
|
777
|
-
const cursorCondition = spec.cursor !== void 0 ? buildSqliteCursorCondition(spec.cursor, sortOrder) : void 0;
|
|
778
|
-
const combined = (0, import_drizzle_orm4.and)(whereCondition, cursorCondition);
|
|
601
|
+
const combined = buildSqliteWhereConditions(spec.filters, spec.cursor, sortOrder);
|
|
779
602
|
const fetchLimit = limit + 1;
|
|
780
603
|
const orderColumns = buildSqliteOrderBy(sortOrder);
|
|
781
604
|
const query = db.select().from(sqliteAuditLogs).where(combined).orderBy(...orderColumns).limit(fetchLimit);
|
|
@@ -785,7 +608,7 @@ function drizzleSqliteAuditAdapter(db) {
|
|
|
785
608
|
const entries = resultRows.map(sqliteRowToAuditLog);
|
|
786
609
|
const lastRow = resultRows[resultRows.length - 1];
|
|
787
610
|
if (hasNextPage && lastRow !== void 0) {
|
|
788
|
-
return { entries, nextCursor:
|
|
611
|
+
return { entries, nextCursor: (0, import_audit_core6.encodeCursor)(lastRow.timestamp, lastRow.id) };
|
|
789
612
|
}
|
|
790
613
|
return { entries };
|
|
791
614
|
},
|
|
@@ -808,7 +631,7 @@ function drizzleSqliteAuditAdapter(db) {
|
|
|
808
631
|
}
|
|
809
632
|
await db.delete(sqliteAuditLogs).where((0, import_drizzle_orm4.and)(...conditions));
|
|
810
633
|
const changesResult = await db.select({ count: import_drizzle_orm4.sql`changes()` }).from(sqliteAuditLogs);
|
|
811
|
-
const deletedCount = changesResult[0] !== void 0 ?
|
|
634
|
+
const deletedCount = changesResult[0] !== void 0 ? (0, import_audit_core6.toCount)(changesResult[0].count) : 0;
|
|
812
635
|
return { deletedCount };
|
|
813
636
|
},
|
|
814
637
|
async getStats(options) {
|
|
@@ -853,7 +676,7 @@ function drizzleSqliteAuditAdapter(db) {
|
|
|
853
676
|
operationRows,
|
|
854
677
|
severityRows
|
|
855
678
|
] = results;
|
|
856
|
-
return
|
|
679
|
+
return (0, import_audit_core6.assembleStats)(
|
|
857
680
|
summaryRows,
|
|
858
681
|
eventsPerDayRows,
|
|
859
682
|
topActorsRows,
|
|
@@ -864,40 +687,6 @@ function drizzleSqliteAuditAdapter(db) {
|
|
|
864
687
|
}
|
|
865
688
|
};
|
|
866
689
|
}
|
|
867
|
-
function assembleStats2(summaryRows, eventsPerDayRows, topActorsRows, topTablesRows, operationRows, severityRows) {
|
|
868
|
-
const summary = summaryRows[0];
|
|
869
|
-
const totalLogs = summary !== void 0 ? toCount2(summary.totalLogs) : 0;
|
|
870
|
-
const tablesAudited = summary !== void 0 ? toCount2(summary.tablesAudited) : 0;
|
|
871
|
-
const eventsPerDay = eventsPerDayRows.map((row) => ({
|
|
872
|
-
date: String(row.date),
|
|
873
|
-
count: toCount2(row.count)
|
|
874
|
-
}));
|
|
875
|
-
const topActors = topActorsRows.map((row) => ({
|
|
876
|
-
actorId: String(row.actorId),
|
|
877
|
-
count: toCount2(row.count)
|
|
878
|
-
}));
|
|
879
|
-
const topTables = topTablesRows.map((row) => ({
|
|
880
|
-
tableName: String(row.tableName),
|
|
881
|
-
count: toCount2(row.count)
|
|
882
|
-
}));
|
|
883
|
-
const operationBreakdown = {};
|
|
884
|
-
for (const row of operationRows) {
|
|
885
|
-
operationBreakdown[String(row.operation)] = toCount2(row.count);
|
|
886
|
-
}
|
|
887
|
-
const severityBreakdown = {};
|
|
888
|
-
for (const row of severityRows) {
|
|
889
|
-
severityBreakdown[String(row.severity)] = toCount2(row.count);
|
|
890
|
-
}
|
|
891
|
-
return {
|
|
892
|
-
totalLogs,
|
|
893
|
-
tablesAudited,
|
|
894
|
-
eventsPerDay,
|
|
895
|
-
topActors,
|
|
896
|
-
topTables,
|
|
897
|
-
operationBreakdown,
|
|
898
|
-
severityBreakdown
|
|
899
|
-
};
|
|
900
|
-
}
|
|
901
690
|
|
|
902
691
|
// src/proxy.ts
|
|
903
692
|
var import_drizzle_orm5 = require("drizzle-orm");
|
|
@@ -1390,10 +1179,12 @@ async function fireCaptureLog(result, ctx, state) {
|
|
|
1390
1179
|
}
|
|
1391
1180
|
}
|
|
1392
1181
|
}
|
|
1182
|
+
|
|
1183
|
+
// src/index.ts
|
|
1184
|
+
var import_audit_core7 = require("@usebetterdev/audit-core");
|
|
1393
1185
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1394
1186
|
0 && (module.exports = {
|
|
1395
1187
|
auditLogs,
|
|
1396
|
-
buildCursorCondition,
|
|
1397
1188
|
buildOrderBy,
|
|
1398
1189
|
buildWhereConditions,
|
|
1399
1190
|
decodeCursor,
|