@usebetterdev/audit-core 0.4.0-beta.4 → 0.5.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 +350 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -1
- package/dist/index.d.ts +83 -1
- package/dist/index.js +348 -31
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -25,6 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
betterAudit: () => betterAudit,
|
|
26
26
|
createAuditApi: () => createAuditApi,
|
|
27
27
|
createAuditConsoleEndpoints: () => createAuditConsoleEndpoints,
|
|
28
|
+
createExportResponse: () => createExportResponse,
|
|
28
29
|
fromBearerToken: () => fromBearerToken,
|
|
29
30
|
fromCookie: () => fromCookie,
|
|
30
31
|
fromHeader: () => fromHeader,
|
|
@@ -33,6 +34,7 @@ __export(index_exports, {
|
|
|
33
34
|
mergeAuditContext: () => mergeAuditContext,
|
|
34
35
|
normalizeInput: () => normalizeInput,
|
|
35
36
|
parseDuration: () => parseDuration,
|
|
37
|
+
runExport: () => runExport,
|
|
36
38
|
runWithAuditContext: () => runWithAuditContext
|
|
37
39
|
});
|
|
38
40
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -559,38 +561,214 @@ var AuditQueryBuilder = class _AuditQueryBuilder {
|
|
|
559
561
|
}
|
|
560
562
|
};
|
|
561
563
|
|
|
562
|
-
// src/
|
|
563
|
-
var
|
|
564
|
+
// src/export.ts
|
|
565
|
+
var DEFAULT_BATCH_SIZE = 500;
|
|
566
|
+
var DEFAULT_CSV_DELIMITER = ",";
|
|
567
|
+
var CSV_COLUMNS = [
|
|
564
568
|
"id",
|
|
565
569
|
"timestamp",
|
|
566
570
|
"tableName",
|
|
567
571
|
"operation",
|
|
568
572
|
"recordId",
|
|
569
573
|
"actorId",
|
|
570
|
-
"
|
|
574
|
+
"beforeData",
|
|
575
|
+
"afterData",
|
|
576
|
+
"diff",
|
|
571
577
|
"label",
|
|
572
|
-
"description"
|
|
578
|
+
"description",
|
|
579
|
+
"severity",
|
|
580
|
+
"compliance",
|
|
581
|
+
"notify",
|
|
582
|
+
"reason",
|
|
583
|
+
"metadata",
|
|
584
|
+
"redactedFields"
|
|
573
585
|
];
|
|
574
|
-
|
|
575
|
-
|
|
586
|
+
var JSON_FIELDS = /* @__PURE__ */ new Set([
|
|
587
|
+
"beforeData",
|
|
588
|
+
"afterData",
|
|
589
|
+
"diff",
|
|
590
|
+
"compliance",
|
|
591
|
+
"metadata",
|
|
592
|
+
"redactedFields"
|
|
593
|
+
]);
|
|
594
|
+
function escapeCsvField(value, delimiter) {
|
|
595
|
+
if (value.includes('"') || value.includes(delimiter) || value.includes("\n") || value.includes("\r")) {
|
|
576
596
|
return `"${value.replace(/"/g, '""')}"`;
|
|
577
597
|
}
|
|
578
598
|
return value;
|
|
579
599
|
}
|
|
580
|
-
function
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
600
|
+
function formatCsvValue(log, field, delimiter) {
|
|
601
|
+
const value = log[field];
|
|
602
|
+
if (value === void 0 || value === null) {
|
|
603
|
+
return "";
|
|
604
|
+
}
|
|
605
|
+
if (JSON_FIELDS.has(field)) {
|
|
606
|
+
return escapeCsvField(JSON.stringify(value), delimiter);
|
|
607
|
+
}
|
|
608
|
+
if (value instanceof Date) {
|
|
609
|
+
return escapeCsvField(value.toISOString(), delimiter);
|
|
610
|
+
}
|
|
611
|
+
if (typeof value === "boolean") {
|
|
612
|
+
return value ? "true" : "false";
|
|
613
|
+
}
|
|
614
|
+
return escapeCsvField(String(value), delimiter);
|
|
615
|
+
}
|
|
616
|
+
function createStringSink() {
|
|
617
|
+
const chunks = [];
|
|
618
|
+
return {
|
|
619
|
+
async write(chunk) {
|
|
620
|
+
chunks.push(chunk);
|
|
621
|
+
},
|
|
622
|
+
async finish() {
|
|
623
|
+
return chunks.join("");
|
|
624
|
+
},
|
|
625
|
+
async abort() {
|
|
626
|
+
}
|
|
627
|
+
};
|
|
593
628
|
}
|
|
629
|
+
function createStreamSink(stream) {
|
|
630
|
+
const writer = stream.getWriter();
|
|
631
|
+
return {
|
|
632
|
+
async write(chunk) {
|
|
633
|
+
await writer.write(chunk);
|
|
634
|
+
},
|
|
635
|
+
async finish() {
|
|
636
|
+
await writer.close();
|
|
637
|
+
return void 0;
|
|
638
|
+
},
|
|
639
|
+
async abort(error) {
|
|
640
|
+
await writer.abort(error);
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
async function runExport(executor, options) {
|
|
645
|
+
const batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
646
|
+
if (batchSize <= 0) {
|
|
647
|
+
throw new Error(`batchSize must be greater than 0, got ${batchSize}`);
|
|
648
|
+
}
|
|
649
|
+
const delimiter = options.csvDelimiter ?? DEFAULT_CSV_DELIMITER;
|
|
650
|
+
if (delimiter.length !== 1) {
|
|
651
|
+
throw new Error("csvDelimiter must be exactly one character");
|
|
652
|
+
}
|
|
653
|
+
const jsonStyle = options.jsonStyle ?? "ndjson";
|
|
654
|
+
const sink = options.output === "string" ? createStringSink() : createStreamSink(options.output);
|
|
655
|
+
const isStringSink = options.output === "string";
|
|
656
|
+
const baseSpec = options.query !== void 0 ? options.query.toSpec() : { filters: {} };
|
|
657
|
+
const totalLimit = baseSpec.limit;
|
|
658
|
+
const spec = { ...baseSpec, limit: batchSize };
|
|
659
|
+
let rowCount = 0;
|
|
660
|
+
try {
|
|
661
|
+
if (options.format === "csv") {
|
|
662
|
+
const header = CSV_COLUMNS.map((col) => escapeCsvField(col, delimiter)).join(delimiter);
|
|
663
|
+
await sink.write(header + "\n");
|
|
664
|
+
let cursor;
|
|
665
|
+
for (; ; ) {
|
|
666
|
+
const currentSpec = cursor !== void 0 ? { ...spec, cursor } : spec;
|
|
667
|
+
const result = await executor(currentSpec);
|
|
668
|
+
if (isStringSink) {
|
|
669
|
+
const lines = [];
|
|
670
|
+
for (const entry of result.entries) {
|
|
671
|
+
if (totalLimit !== void 0 && rowCount >= totalLimit) {
|
|
672
|
+
break;
|
|
673
|
+
}
|
|
674
|
+
const row = CSV_COLUMNS.map((col) => formatCsvValue(entry, col, delimiter)).join(delimiter);
|
|
675
|
+
lines.push(row + "\n");
|
|
676
|
+
rowCount++;
|
|
677
|
+
}
|
|
678
|
+
if (lines.length > 0) {
|
|
679
|
+
await sink.write(lines.join(""));
|
|
680
|
+
}
|
|
681
|
+
} else {
|
|
682
|
+
for (const entry of result.entries) {
|
|
683
|
+
if (totalLimit !== void 0 && rowCount >= totalLimit) {
|
|
684
|
+
break;
|
|
685
|
+
}
|
|
686
|
+
const row = CSV_COLUMNS.map((col) => formatCsvValue(entry, col, delimiter)).join(delimiter);
|
|
687
|
+
await sink.write(row + "\n");
|
|
688
|
+
rowCount++;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
if (totalLimit !== void 0 && rowCount >= totalLimit) {
|
|
692
|
+
break;
|
|
693
|
+
}
|
|
694
|
+
if (result.nextCursor === void 0) {
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
697
|
+
cursor = result.nextCursor;
|
|
698
|
+
}
|
|
699
|
+
} else {
|
|
700
|
+
if (jsonStyle === "array") {
|
|
701
|
+
let cursor;
|
|
702
|
+
const entries = [];
|
|
703
|
+
for (; ; ) {
|
|
704
|
+
const currentSpec = cursor !== void 0 ? { ...spec, cursor } : spec;
|
|
705
|
+
const result = await executor(currentSpec);
|
|
706
|
+
for (const entry of result.entries) {
|
|
707
|
+
if (totalLimit !== void 0 && rowCount >= totalLimit) {
|
|
708
|
+
break;
|
|
709
|
+
}
|
|
710
|
+
entries.push(entry);
|
|
711
|
+
rowCount++;
|
|
712
|
+
}
|
|
713
|
+
if (totalLimit !== void 0 && rowCount >= totalLimit) {
|
|
714
|
+
break;
|
|
715
|
+
}
|
|
716
|
+
if (result.nextCursor === void 0) {
|
|
717
|
+
break;
|
|
718
|
+
}
|
|
719
|
+
cursor = result.nextCursor;
|
|
720
|
+
}
|
|
721
|
+
await sink.write(JSON.stringify(entries, null, 2) + "\n");
|
|
722
|
+
} else {
|
|
723
|
+
let cursor;
|
|
724
|
+
for (; ; ) {
|
|
725
|
+
const currentSpec = cursor !== void 0 ? { ...spec, cursor } : spec;
|
|
726
|
+
const result = await executor(currentSpec);
|
|
727
|
+
if (isStringSink) {
|
|
728
|
+
const lines = [];
|
|
729
|
+
for (const entry of result.entries) {
|
|
730
|
+
if (totalLimit !== void 0 && rowCount >= totalLimit) {
|
|
731
|
+
break;
|
|
732
|
+
}
|
|
733
|
+
lines.push(JSON.stringify(entry) + "\n");
|
|
734
|
+
rowCount++;
|
|
735
|
+
}
|
|
736
|
+
if (lines.length > 0) {
|
|
737
|
+
await sink.write(lines.join(""));
|
|
738
|
+
}
|
|
739
|
+
} else {
|
|
740
|
+
for (const entry of result.entries) {
|
|
741
|
+
if (totalLimit !== void 0 && rowCount >= totalLimit) {
|
|
742
|
+
break;
|
|
743
|
+
}
|
|
744
|
+
await sink.write(JSON.stringify(entry) + "\n");
|
|
745
|
+
rowCount++;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
if (totalLimit !== void 0 && rowCount >= totalLimit) {
|
|
749
|
+
break;
|
|
750
|
+
}
|
|
751
|
+
if (result.nextCursor === void 0) {
|
|
752
|
+
break;
|
|
753
|
+
}
|
|
754
|
+
cursor = result.nextCursor;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
} catch (error) {
|
|
759
|
+
await sink.abort(error);
|
|
760
|
+
throw error;
|
|
761
|
+
}
|
|
762
|
+
const data = await sink.finish();
|
|
763
|
+
if (data !== void 0) {
|
|
764
|
+
return { rowCount, data };
|
|
765
|
+
}
|
|
766
|
+
return { rowCount };
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// src/audit-api.ts
|
|
770
|
+
var VALID_SEVERITIES = /* @__PURE__ */ new Set(["low", "medium", "high", "critical"]);
|
|
771
|
+
var VALID_OPERATIONS = /* @__PURE__ */ new Set(["INSERT", "UPDATE", "DELETE"]);
|
|
594
772
|
function toTimeFilter(date) {
|
|
595
773
|
return { date };
|
|
596
774
|
}
|
|
@@ -607,13 +785,24 @@ function buildQuerySpec(filters, effectiveLimit) {
|
|
|
607
785
|
spec.filters.actorIds = [filters.actorId];
|
|
608
786
|
}
|
|
609
787
|
if (filters.severity !== void 0) {
|
|
788
|
+
if (!VALID_SEVERITIES.has(filters.severity)) {
|
|
789
|
+
throw new Error(
|
|
790
|
+
`Invalid severity "${filters.severity}". Must be one of: low, medium, high, critical`
|
|
791
|
+
);
|
|
792
|
+
}
|
|
610
793
|
spec.filters.severities = [filters.severity];
|
|
611
794
|
}
|
|
612
795
|
if (filters.compliance !== void 0) {
|
|
613
796
|
spec.filters.compliance = [filters.compliance];
|
|
614
797
|
}
|
|
615
798
|
if (filters.operation !== void 0) {
|
|
616
|
-
|
|
799
|
+
const normalized = filters.operation.toUpperCase();
|
|
800
|
+
if (!VALID_OPERATIONS.has(normalized)) {
|
|
801
|
+
throw new Error(
|
|
802
|
+
`Invalid operation "${filters.operation}". Must be one of: INSERT, UPDATE, DELETE`
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
spec.filters.operations = [normalized];
|
|
617
806
|
}
|
|
618
807
|
if (filters.since !== void 0) {
|
|
619
808
|
spec.filters.since = toTimeFilter(filters.since);
|
|
@@ -714,17 +903,28 @@ function createAuditApi(adapter, registry, maxQueryLimit) {
|
|
|
714
903
|
return summaries;
|
|
715
904
|
}
|
|
716
905
|
async function exportLogs(filters, format) {
|
|
906
|
+
const queryFn = requireQueryLogs();
|
|
717
907
|
const exportFormat = format ?? "json";
|
|
718
|
-
const
|
|
719
|
-
const
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
908
|
+
const spec = buildQuerySpec(filters ?? {}, effectiveLimit);
|
|
909
|
+
const queryBuilder = new AuditQueryBuilder(
|
|
910
|
+
(s) => queryFn(s),
|
|
911
|
+
spec.filters,
|
|
912
|
+
spec.limit,
|
|
913
|
+
void 0,
|
|
914
|
+
effectiveLimit,
|
|
915
|
+
spec.sortOrder
|
|
916
|
+
);
|
|
917
|
+
const exportOptions = {
|
|
918
|
+
format: exportFormat,
|
|
919
|
+
query: queryBuilder,
|
|
920
|
+
output: "string",
|
|
921
|
+
...exportFormat === "json" && { jsonStyle: "array" }
|
|
922
|
+
};
|
|
923
|
+
const result = await runExport(
|
|
924
|
+
(s) => queryFn(s),
|
|
925
|
+
exportOptions
|
|
926
|
+
);
|
|
927
|
+
return result.data ?? "";
|
|
728
928
|
}
|
|
729
929
|
async function purgeLogs(options) {
|
|
730
930
|
const purgeFn = requirePurgeLogs();
|
|
@@ -960,14 +1160,113 @@ function createAuditConsoleEndpoints(api) {
|
|
|
960
1160
|
];
|
|
961
1161
|
}
|
|
962
1162
|
|
|
1163
|
+
// src/export-response.ts
|
|
1164
|
+
function contentTypeForFormat(format, jsonStyle) {
|
|
1165
|
+
if (format === "csv") {
|
|
1166
|
+
return "text/csv; charset=utf-8";
|
|
1167
|
+
}
|
|
1168
|
+
if (jsonStyle === "ndjson") {
|
|
1169
|
+
return "application/x-ndjson; charset=utf-8";
|
|
1170
|
+
}
|
|
1171
|
+
return "application/json; charset=utf-8";
|
|
1172
|
+
}
|
|
1173
|
+
function fileExtensionForFormat(format, jsonStyle) {
|
|
1174
|
+
if (format === "csv") {
|
|
1175
|
+
return ".csv";
|
|
1176
|
+
}
|
|
1177
|
+
if (jsonStyle === "ndjson") {
|
|
1178
|
+
return ".ndjson";
|
|
1179
|
+
}
|
|
1180
|
+
return ".json";
|
|
1181
|
+
}
|
|
1182
|
+
function formatDate(date) {
|
|
1183
|
+
const year = date.getFullYear();
|
|
1184
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
1185
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
1186
|
+
return `${year}-${month}-${day}`;
|
|
1187
|
+
}
|
|
1188
|
+
function sanitiseFilename(name) {
|
|
1189
|
+
return name.replace(/["\\\r\n\x00-\x1f]/g, "");
|
|
1190
|
+
}
|
|
1191
|
+
function createExportResponse(executor, options = {}) {
|
|
1192
|
+
const format = options.format ?? "csv";
|
|
1193
|
+
const jsonStyle = options.jsonStyle ?? "ndjson";
|
|
1194
|
+
const stem = options.filename ?? `audit-export-${formatDate(/* @__PURE__ */ new Date())}`;
|
|
1195
|
+
const extension = fileExtensionForFormat(format, jsonStyle);
|
|
1196
|
+
const fullFilename = sanitiseFilename(`${stem}${extension}`);
|
|
1197
|
+
const contentType = contentTypeForFormat(format, jsonStyle);
|
|
1198
|
+
const transform = new TransformStream();
|
|
1199
|
+
const encoder = new TextEncoderStream();
|
|
1200
|
+
const readable = transform.readable.pipeThrough(encoder);
|
|
1201
|
+
runExport(executor, {
|
|
1202
|
+
format,
|
|
1203
|
+
jsonStyle,
|
|
1204
|
+
output: transform.writable,
|
|
1205
|
+
...options.batchSize !== void 0 && { batchSize: options.batchSize },
|
|
1206
|
+
...options.csvDelimiter !== void 0 && {
|
|
1207
|
+
csvDelimiter: options.csvDelimiter
|
|
1208
|
+
},
|
|
1209
|
+
...options.query !== void 0 && { query: options.query }
|
|
1210
|
+
}).catch(() => {
|
|
1211
|
+
});
|
|
1212
|
+
return new Response(readable, {
|
|
1213
|
+
status: 200,
|
|
1214
|
+
headers: {
|
|
1215
|
+
"Content-Type": contentType,
|
|
1216
|
+
"Content-Disposition": `attachment; filename="${fullFilename}"`,
|
|
1217
|
+
"Cache-Control": "no-cache"
|
|
1218
|
+
}
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
// src/retention.ts
|
|
1223
|
+
function validateRetentionPolicy(policy) {
|
|
1224
|
+
if (!Number.isInteger(policy.days) || !Number.isFinite(policy.days) || policy.days <= 0) {
|
|
1225
|
+
throw new Error(
|
|
1226
|
+
`retention: 'days' must be a positive integer, got ${String(policy.days)}`
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
1229
|
+
if (policy.tables !== void 0) {
|
|
1230
|
+
if (!Array.isArray(policy.tables) || policy.tables.length === 0 || policy.tables.some((t) => typeof t !== "string" || t === "")) {
|
|
1231
|
+
throw new Error(
|
|
1232
|
+
"retention: 'tables' must be a non-empty array of non-empty strings"
|
|
1233
|
+
);
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
|
|
963
1238
|
// src/better-audit.ts
|
|
964
1239
|
function withContext(context, fn) {
|
|
965
1240
|
return runWithAuditContext(context, fn);
|
|
966
1241
|
}
|
|
967
1242
|
function betterAudit(config) {
|
|
1243
|
+
if (config.retention !== void 0) {
|
|
1244
|
+
validateRetentionPolicy(config.retention);
|
|
1245
|
+
}
|
|
968
1246
|
const { database } = config;
|
|
969
1247
|
const auditTables = new Set(config.auditTables);
|
|
1248
|
+
if (config.retention?.tables !== void 0) {
|
|
1249
|
+
const unknown = config.retention.tables.filter((t) => !auditTables.has(t));
|
|
1250
|
+
if (unknown.length > 0) {
|
|
1251
|
+
throw new Error(
|
|
1252
|
+
`retention: 'tables' contains table(s) not in auditTables: ${unknown.join(", ")}. Registered tables: ${[...auditTables].join(", ")}`
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
970
1256
|
const registry = new EnrichmentRegistry();
|
|
1257
|
+
const resolvedRetention = config.retention !== void 0 ? {
|
|
1258
|
+
...config.retention,
|
|
1259
|
+
...config.retention.tables !== void 0 && { tables: [...config.retention.tables] }
|
|
1260
|
+
} : void 0;
|
|
1261
|
+
function retentionPolicy() {
|
|
1262
|
+
if (resolvedRetention === void 0) {
|
|
1263
|
+
return void 0;
|
|
1264
|
+
}
|
|
1265
|
+
return {
|
|
1266
|
+
...resolvedRetention,
|
|
1267
|
+
...resolvedRetention.tables !== void 0 && { tables: [...resolvedRetention.tables] }
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
971
1270
|
const beforeLogHooks = config.beforeLog !== void 0 ? [...config.beforeLog] : [];
|
|
972
1271
|
const afterLogHooks = config.afterLog !== void 0 ? [...config.afterLog] : [];
|
|
973
1272
|
function enrich(table, operation, enrichmentConfig) {
|
|
@@ -1075,6 +1374,24 @@ function betterAudit(config) {
|
|
|
1075
1374
|
config.maxQueryLimit
|
|
1076
1375
|
);
|
|
1077
1376
|
}
|
|
1377
|
+
async function exportLogs(options) {
|
|
1378
|
+
if (database.queryLogs === void 0) {
|
|
1379
|
+
throw new Error(
|
|
1380
|
+
"audit.export() requires a database adapter that implements queryLogs(). Check that your ORM adapter supports querying."
|
|
1381
|
+
);
|
|
1382
|
+
}
|
|
1383
|
+
const queryLogs = database.queryLogs;
|
|
1384
|
+
return runExport((spec) => queryLogs(spec), options);
|
|
1385
|
+
}
|
|
1386
|
+
function exportResponse(options) {
|
|
1387
|
+
if (database.queryLogs === void 0) {
|
|
1388
|
+
throw new Error(
|
|
1389
|
+
"audit.exportResponse() requires a database adapter that implements queryLogs(). Check that your ORM adapter supports querying."
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
const queryLogs = database.queryLogs;
|
|
1393
|
+
return createExportResponse((spec) => queryLogs(spec), options);
|
|
1394
|
+
}
|
|
1078
1395
|
if (config.console) {
|
|
1079
1396
|
const api = createAuditApi(database, registry, config.maxQueryLimit);
|
|
1080
1397
|
const endpoints = createAuditConsoleEndpoints(api);
|
|
@@ -1084,7 +1401,7 @@ function betterAudit(config) {
|
|
|
1084
1401
|
endpoints
|
|
1085
1402
|
});
|
|
1086
1403
|
}
|
|
1087
|
-
return { captureLog, query, withContext, enrich, onBeforeLog, onAfterLog };
|
|
1404
|
+
return { captureLog, query, export: exportLogs, exportResponse, withContext, enrich, onBeforeLog, onAfterLog, retentionPolicy };
|
|
1088
1405
|
}
|
|
1089
1406
|
|
|
1090
1407
|
// src/audit-log-schema.ts
|
|
@@ -1293,6 +1610,7 @@ async function handleMiddleware(extractor, request, next, options = {}) {
|
|
|
1293
1610
|
betterAudit,
|
|
1294
1611
|
createAuditApi,
|
|
1295
1612
|
createAuditConsoleEndpoints,
|
|
1613
|
+
createExportResponse,
|
|
1296
1614
|
fromBearerToken,
|
|
1297
1615
|
fromCookie,
|
|
1298
1616
|
fromHeader,
|
|
@@ -1301,6 +1619,7 @@ async function handleMiddleware(extractor, request, next, options = {}) {
|
|
|
1301
1619
|
mergeAuditContext,
|
|
1302
1620
|
normalizeInput,
|
|
1303
1621
|
parseDuration,
|
|
1622
|
+
runExport,
|
|
1304
1623
|
runWithAuditContext
|
|
1305
1624
|
});
|
|
1306
1625
|
//# sourceMappingURL=index.cjs.map
|