@usebetterdev/audit-core 0.5.0-beta.1 → 0.6.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 +76 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -10
- package/dist/index.d.ts +39 -10
- package/dist/index.js +75 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { RetentionPolicy } from '@usebetterdev/contract/config-types';
|
|
2
|
+
export { RetentionPolicy } from '@usebetterdev/contract/config-types';
|
|
3
|
+
import { ConsoleRegistration, ConsoleProductEndpoint } from '@usebetterdev/contract';
|
|
4
|
+
export { ConsoleRegistration } from '@usebetterdev/contract';
|
|
3
5
|
|
|
4
6
|
/** Identifies a specific resource (table + optional record). */
|
|
5
7
|
interface ResourceFilter {
|
|
@@ -104,14 +106,33 @@ declare class AuditQueryBuilder {
|
|
|
104
106
|
list(): Promise<AuditQueryResult>;
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
/** Options for `createExportResponse()`. */
|
|
110
|
+
interface ExportResponseOptions {
|
|
111
|
+
/** Output format. Default: `"csv"`. */
|
|
112
|
+
format?: "csv" | "json";
|
|
113
|
+
/** JSON output style. Default: `"ndjson"`. */
|
|
114
|
+
jsonStyle?: "ndjson" | "array";
|
|
115
|
+
/** Rows per database round-trip. */
|
|
116
|
+
batchSize?: number;
|
|
117
|
+
/** CSV delimiter character. */
|
|
118
|
+
csvDelimiter?: string;
|
|
119
|
+
/** Optional query builder to filter exported entries. */
|
|
120
|
+
query?: AuditQueryBuilder;
|
|
121
|
+
/** Custom filename stem (without extension). Default: `"audit-export-YYYY-MM-DD"`. */
|
|
122
|
+
filename?: string;
|
|
114
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Create a streaming `Response` from the audit export engine.
|
|
126
|
+
*
|
|
127
|
+
* Uses `TransformStream` + `TextEncoderStream` to bridge the string-based
|
|
128
|
+
* `runExport()` output to a binary `ReadableStream` suitable for `new Response()`.
|
|
129
|
+
* The export runs asynchronously — the Response is returned immediately so the
|
|
130
|
+
* first byte can arrive before all rows are read.
|
|
131
|
+
*/
|
|
132
|
+
declare function createExportResponse(executor: QueryExecutor, options?: ExportResponseOptions): Response;
|
|
133
|
+
|
|
134
|
+
type AuditOperation = "INSERT" | "UPDATE" | "DELETE";
|
|
135
|
+
|
|
115
136
|
type AuditSeverity = "low" | "medium" | "high" | "critical";
|
|
116
137
|
/** A single audit log entry as stored in the database. */
|
|
117
138
|
interface AuditLog {
|
|
@@ -333,6 +354,14 @@ interface BetterAuditInstance {
|
|
|
333
354
|
* regardless of export size. Requires `queryLogs` on the database adapter.
|
|
334
355
|
*/
|
|
335
356
|
export(options: ExportOptions): Promise<ExportResult>;
|
|
357
|
+
/**
|
|
358
|
+
* Create a streaming HTTP `Response` for downloading audit logs.
|
|
359
|
+
*
|
|
360
|
+
* Returns a standard `Response` with correct Content-Type, Content-Disposition,
|
|
361
|
+
* and Cache-Control headers. The body is a streaming `ReadableStream` backed
|
|
362
|
+
* by the export engine. Requires `queryLogs` on the database adapter.
|
|
363
|
+
*/
|
|
364
|
+
exportResponse(options?: ExportResponseOptions): Response;
|
|
336
365
|
withContext<T>(context: AuditContext, fn: () => Promise<T>): Promise<T>;
|
|
337
366
|
/**
|
|
338
367
|
* Register an enrichment config for a table/operation pair.
|
|
@@ -568,4 +597,4 @@ declare function fromHeader(headerName: string): ValueExtractor;
|
|
|
568
597
|
*/
|
|
569
598
|
declare function handleMiddleware(extractor: ContextExtractor, request: Request, next: () => Promise<void>, options?: MiddlewareHandlerOptions): Promise<void>;
|
|
570
599
|
|
|
571
|
-
export { AUDIT_LOG_SCHEMA, type AfterLogHook, type AuditApi, type AuditContext, type AuditDatabaseAdapter, type AuditLog, type AuditLogColumnName, type AuditLogSchema, type AuditOperation, AuditQueryBuilder, type AuditQueryFilters, type AuditQueryResult, type AuditQuerySpec, type AuditSeverity, type AuditStats, type BeforeLogHook, type BetterAuditConfig, type BetterAuditInstance, type CaptureLogInput, type ColumnDefinition, type ColumnType, type ConsoleQueryFilters, type ConsoleQueryResult, type ContextExtractor, type EnrichmentConfig, type EnrichmentDescriptionContext, type EnrichmentSummary, type ExportOptions, type ExportResult, type MiddlewareHandlerOptions, type QueryExecutor, type ResourceFilter, type
|
|
600
|
+
export { AUDIT_LOG_SCHEMA, type AfterLogHook, type AuditApi, type AuditContext, type AuditDatabaseAdapter, type AuditLog, type AuditLogColumnName, type AuditLogSchema, type AuditOperation, AuditQueryBuilder, type AuditQueryFilters, type AuditQueryResult, type AuditQuerySpec, type AuditSeverity, type AuditStats, type BeforeLogHook, type BetterAuditConfig, type BetterAuditInstance, type CaptureLogInput, type ColumnDefinition, type ColumnType, type ConsoleQueryFilters, type ConsoleQueryResult, type ContextExtractor, type EnrichmentConfig, type EnrichmentDescriptionContext, type EnrichmentSummary, type ExportOptions, type ExportResponseOptions, type ExportResult, type MiddlewareHandlerOptions, type QueryExecutor, type ResourceFilter, type TimeFilter, type ValueExtractor, betterAudit, createAuditApi, createAuditConsoleEndpoints, createExportResponse, fromBearerToken, fromCookie, fromHeader, getAuditContext, handleMiddleware, mergeAuditContext, normalizeInput, parseDuration, runExport, runWithAuditContext };
|
package/dist/index.js
CHANGED
|
@@ -1119,6 +1119,65 @@ function createAuditConsoleEndpoints(api) {
|
|
|
1119
1119
|
];
|
|
1120
1120
|
}
|
|
1121
1121
|
|
|
1122
|
+
// src/export-response.ts
|
|
1123
|
+
function contentTypeForFormat(format, jsonStyle) {
|
|
1124
|
+
if (format === "csv") {
|
|
1125
|
+
return "text/csv; charset=utf-8";
|
|
1126
|
+
}
|
|
1127
|
+
if (jsonStyle === "ndjson") {
|
|
1128
|
+
return "application/x-ndjson; charset=utf-8";
|
|
1129
|
+
}
|
|
1130
|
+
return "application/json; charset=utf-8";
|
|
1131
|
+
}
|
|
1132
|
+
function fileExtensionForFormat(format, jsonStyle) {
|
|
1133
|
+
if (format === "csv") {
|
|
1134
|
+
return ".csv";
|
|
1135
|
+
}
|
|
1136
|
+
if (jsonStyle === "ndjson") {
|
|
1137
|
+
return ".ndjson";
|
|
1138
|
+
}
|
|
1139
|
+
return ".json";
|
|
1140
|
+
}
|
|
1141
|
+
function formatDate(date) {
|
|
1142
|
+
const year = date.getFullYear();
|
|
1143
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
1144
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
1145
|
+
return `${year}-${month}-${day}`;
|
|
1146
|
+
}
|
|
1147
|
+
function sanitiseFilename(name) {
|
|
1148
|
+
return name.replace(/["\\\r\n\x00-\x1f]/g, "");
|
|
1149
|
+
}
|
|
1150
|
+
function createExportResponse(executor, options = {}) {
|
|
1151
|
+
const format = options.format ?? "csv";
|
|
1152
|
+
const jsonStyle = options.jsonStyle ?? "ndjson";
|
|
1153
|
+
const stem = options.filename ?? `audit-export-${formatDate(/* @__PURE__ */ new Date())}`;
|
|
1154
|
+
const extension = fileExtensionForFormat(format, jsonStyle);
|
|
1155
|
+
const fullFilename = sanitiseFilename(`${stem}${extension}`);
|
|
1156
|
+
const contentType = contentTypeForFormat(format, jsonStyle);
|
|
1157
|
+
const transform = new TransformStream();
|
|
1158
|
+
const encoder = new TextEncoderStream();
|
|
1159
|
+
const readable = transform.readable.pipeThrough(encoder);
|
|
1160
|
+
runExport(executor, {
|
|
1161
|
+
format,
|
|
1162
|
+
jsonStyle,
|
|
1163
|
+
output: transform.writable,
|
|
1164
|
+
...options.batchSize !== void 0 && { batchSize: options.batchSize },
|
|
1165
|
+
...options.csvDelimiter !== void 0 && {
|
|
1166
|
+
csvDelimiter: options.csvDelimiter
|
|
1167
|
+
},
|
|
1168
|
+
...options.query !== void 0 && { query: options.query }
|
|
1169
|
+
}).catch(() => {
|
|
1170
|
+
});
|
|
1171
|
+
return new Response(readable, {
|
|
1172
|
+
status: 200,
|
|
1173
|
+
headers: {
|
|
1174
|
+
"Content-Type": contentType,
|
|
1175
|
+
"Content-Disposition": `attachment; filename="${fullFilename}"`,
|
|
1176
|
+
"Cache-Control": "no-cache"
|
|
1177
|
+
}
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1122
1181
|
// src/retention.ts
|
|
1123
1182
|
function validateRetentionPolicy(policy) {
|
|
1124
1183
|
if (!Number.isInteger(policy.days) || !Number.isFinite(policy.days) || policy.days <= 0) {
|
|
@@ -1143,6 +1202,11 @@ function betterAudit(config) {
|
|
|
1143
1202
|
if (config.retention !== void 0) {
|
|
1144
1203
|
validateRetentionPolicy(config.retention);
|
|
1145
1204
|
}
|
|
1205
|
+
if (config.asyncWrite === true && config.onError === void 0) {
|
|
1206
|
+
console.warn(
|
|
1207
|
+
"audit: asyncWrite is enabled without onError \u2014 write failures will only log to console.error. Set onError to route failures to your error tracking system."
|
|
1208
|
+
);
|
|
1209
|
+
}
|
|
1146
1210
|
const { database } = config;
|
|
1147
1211
|
const auditTables = new Set(config.auditTables);
|
|
1148
1212
|
if (config.retention?.tables !== void 0) {
|
|
@@ -1283,6 +1347,15 @@ function betterAudit(config) {
|
|
|
1283
1347
|
const queryLogs = database.queryLogs;
|
|
1284
1348
|
return runExport((spec) => queryLogs(spec), options);
|
|
1285
1349
|
}
|
|
1350
|
+
function exportResponse(options) {
|
|
1351
|
+
if (database.queryLogs === void 0) {
|
|
1352
|
+
throw new Error(
|
|
1353
|
+
"audit.exportResponse() requires a database adapter that implements queryLogs(). Check that your ORM adapter supports querying."
|
|
1354
|
+
);
|
|
1355
|
+
}
|
|
1356
|
+
const queryLogs = database.queryLogs;
|
|
1357
|
+
return createExportResponse((spec) => queryLogs(spec), options);
|
|
1358
|
+
}
|
|
1286
1359
|
if (config.console) {
|
|
1287
1360
|
const api = createAuditApi(database, registry, config.maxQueryLimit);
|
|
1288
1361
|
const endpoints = createAuditConsoleEndpoints(api);
|
|
@@ -1292,7 +1365,7 @@ function betterAudit(config) {
|
|
|
1292
1365
|
endpoints
|
|
1293
1366
|
});
|
|
1294
1367
|
}
|
|
1295
|
-
return { captureLog, query, export: exportLogs, withContext, enrich, onBeforeLog, onAfterLog, retentionPolicy };
|
|
1368
|
+
return { captureLog, query, export: exportLogs, exportResponse, withContext, enrich, onBeforeLog, onAfterLog, retentionPolicy };
|
|
1296
1369
|
}
|
|
1297
1370
|
|
|
1298
1371
|
// src/audit-log-schema.ts
|
|
@@ -1500,6 +1573,7 @@ export {
|
|
|
1500
1573
|
betterAudit,
|
|
1501
1574
|
createAuditApi,
|
|
1502
1575
|
createAuditConsoleEndpoints,
|
|
1576
|
+
createExportResponse,
|
|
1503
1577
|
fromBearerToken,
|
|
1504
1578
|
fromCookie,
|
|
1505
1579
|
fromHeader,
|