@geekmidas/audit 0.0.8 → 0.2.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 (64) hide show
  1. package/README.md +397 -0
  2. package/dist/{Auditor-D3me-qKX.d.mts → Auditor-_Dn2dp8d.d.mts} +46 -1
  3. package/dist/Auditor-_Dn2dp8d.d.mts.map +1 -0
  4. package/dist/{Auditor-QYUMGJCH.d.cts → Auditor-sW7YAJIA.d.cts} +46 -1
  5. package/dist/Auditor-sW7YAJIA.d.cts.map +1 -0
  6. package/dist/Auditor.d.cts +1 -1
  7. package/dist/Auditor.d.mts +1 -1
  8. package/dist/DefaultAuditor-BAVnNmRh.mjs.map +1 -1
  9. package/dist/{DefaultAuditor-BTuMMiWh.d.cts → DefaultAuditor-BSYMwojG.d.cts} +3 -2
  10. package/dist/DefaultAuditor-BSYMwojG.d.cts.map +1 -0
  11. package/dist/{DefaultAuditor-C1FWrJg6.d.mts → DefaultAuditor-CYE-uAry.d.mts} +3 -2
  12. package/dist/DefaultAuditor-CYE-uAry.d.mts.map +1 -0
  13. package/dist/DefaultAuditor-JbZ_BQfh.cjs.map +1 -1
  14. package/dist/DefaultAuditor.d.cts +2 -2
  15. package/dist/DefaultAuditor.d.mts +2 -2
  16. package/dist/cache-2VI80Vao.d.mts +96 -0
  17. package/dist/cache-2VI80Vao.d.mts.map +1 -0
  18. package/dist/cache-BbIl31RL.mjs +167 -0
  19. package/dist/cache-BbIl31RL.mjs.map +1 -0
  20. package/dist/cache-CDHqXqcl.d.cts +96 -0
  21. package/dist/cache-CDHqXqcl.d.cts.map +1 -0
  22. package/dist/cache-l7jAptBl.cjs +173 -0
  23. package/dist/cache-l7jAptBl.cjs.map +1 -0
  24. package/dist/cache.cjs +3 -0
  25. package/dist/cache.d.cts +3 -0
  26. package/dist/cache.d.mts +3 -0
  27. package/dist/cache.mjs +3 -0
  28. package/dist/index.d.cts +2 -2
  29. package/dist/index.d.mts +2 -2
  30. package/dist/kysely.cjs +24 -0
  31. package/dist/kysely.cjs.map +1 -1
  32. package/dist/kysely.d.cts +11 -1
  33. package/dist/kysely.d.cts.map +1 -0
  34. package/dist/kysely.d.mts +11 -1
  35. package/dist/kysely.d.mts.map +1 -0
  36. package/dist/kysely.mjs +24 -0
  37. package/dist/kysely.mjs.map +1 -1
  38. package/dist/memory.cjs +49 -0
  39. package/dist/memory.cjs.map +1 -0
  40. package/dist/memory.d.cts +44 -0
  41. package/dist/memory.d.cts.map +1 -0
  42. package/dist/memory.d.mts +44 -0
  43. package/dist/memory.d.mts.map +1 -0
  44. package/dist/memory.mjs +48 -0
  45. package/dist/memory.mjs.map +1 -0
  46. package/dist/storage.d.cts +1 -1
  47. package/dist/storage.d.mts +1 -1
  48. package/dist/types.d.cts +1 -1
  49. package/dist/types.d.mts +1 -1
  50. package/package.json +33 -5
  51. package/src/Auditor.ts +121 -121
  52. package/src/DefaultAuditor.ts +91 -91
  53. package/src/__tests__/CacheAuditStorage.spec.ts +382 -0
  54. package/src/__tests__/DefaultAuditor.spec.ts +520 -462
  55. package/src/__tests__/InMemoryAuditStorage.spec.ts +317 -0
  56. package/src/__tests__/KyselyAuditStorage.integration.spec.ts +500 -496
  57. package/src/__tests__/KyselyAuditStorage.spec.ts +433 -433
  58. package/src/cache.ts +263 -0
  59. package/src/index.ts +14 -15
  60. package/src/kysely.ts +292 -259
  61. package/src/memory.ts +50 -0
  62. package/src/storage.ts +132 -85
  63. package/src/types.ts +73 -74
  64. package/tsconfig.json +9 -0
package/README.md ADDED
@@ -0,0 +1,397 @@
1
+ # @geekmidas/audit
2
+
3
+ > Type-safe audit logging with database integration for tracking application events and user actions
4
+
5
+ ## Overview
6
+
7
+ `@geekmidas/audit` provides a comprehensive solution for recording and persisting audit trails in your application. It supports type-safe audit actions, transactional writes, and flexible storage backends.
8
+
9
+ ## Features
10
+
11
+ - **Type-safe Audit Actions**: Define audit types with TypeScript for compile-time safety
12
+ - **Transactional Support**: Flush audits atomically within database transactions
13
+ - **Flexible Storage**: Pluggable storage interface (Kysely, in-memory, cache)
14
+ - **Actor Tracking**: Record who performed each action (users, services, systems)
15
+ - **Rich Metadata**: Attach request context, entity references, and custom data
16
+ - **Query Support**: Query audit logs with filters, pagination, and sorting
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @geekmidas/audit
22
+ # or
23
+ pnpm add @geekmidas/audit
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ### 1. Define Your Audit Actions
29
+
30
+ ```typescript
31
+ import type { AuditableAction } from '@geekmidas/audit';
32
+
33
+ // Define type-safe audit actions
34
+ type AppAuditAction =
35
+ | AuditableAction<'user.created', { userId: string; email: string }>
36
+ | AuditableAction<'user.updated', { userId: string; changes: string[] }>
37
+ | AuditableAction<'order.placed', { orderId: string; total: number }>;
38
+ ```
39
+
40
+ ### 2. Set Up Storage
41
+
42
+ **For Development/Testing (InMemoryAuditStorage):**
43
+
44
+ ```typescript
45
+ import { InMemoryAuditStorage } from '@geekmidas/audit/memory';
46
+
47
+ const storage = new InMemoryAuditStorage<AppAuditAction>();
48
+
49
+ // Query stored records
50
+ const records = await storage.query({ type: 'user.created' });
51
+
52
+ // Clear all records (useful in tests)
53
+ storage.clear();
54
+ ```
55
+
56
+ **For Production (KyselyAuditStorage):**
57
+
58
+ ```typescript
59
+ import { KyselyAuditStorage } from '@geekmidas/audit/kysely';
60
+
61
+ // Define your database schema
62
+ interface Database {
63
+ audit_logs: AuditLogTable;
64
+ // ... other tables
65
+ }
66
+
67
+ const storage = new KyselyAuditStorage<Database>({
68
+ db: kyselyDb,
69
+ tableName: 'audit_logs',
70
+ });
71
+ ```
72
+
73
+ ### 3. Create an Auditor
74
+
75
+ ```typescript
76
+ import { DefaultAuditor } from '@geekmidas/audit';
77
+
78
+ const auditor = new DefaultAuditor<AppAuditAction>({
79
+ actor: { id: 'user-123', type: 'user' },
80
+ storage,
81
+ metadata: {
82
+ requestId: 'req-456',
83
+ endpoint: '/api/users',
84
+ },
85
+ });
86
+ ```
87
+
88
+ ### 4. Record Audits
89
+
90
+ ```typescript
91
+ // Type-safe audit calls - TypeScript enforces correct payload shapes
92
+ auditor.audit('user.created', {
93
+ userId: '789',
94
+ email: 'test@example.com',
95
+ }); // OK
96
+
97
+ auditor.audit('user.created', {
98
+ orderId: '123', // Type error - wrong payload shape
99
+ });
100
+
101
+ // Flush to storage
102
+ await auditor.flush();
103
+ ```
104
+
105
+ ## Transactional Audits
106
+
107
+ Use `withAuditableTransaction` to ensure audits are atomic with your database operations:
108
+
109
+ ```typescript
110
+ import { withAuditableTransaction } from '@geekmidas/audit/kysely';
111
+
112
+ const result = await withAuditableTransaction(
113
+ db,
114
+ auditor,
115
+ async (trx) => {
116
+ // Database operations
117
+ const user = await trx
118
+ .insertInto('users')
119
+ .values({ name: 'John', email: 'john@example.com' })
120
+ .returningAll()
121
+ .executeTakeFirstOrThrow();
122
+
123
+ // Audit is recorded
124
+ auditor.audit('user.created', {
125
+ userId: user.id,
126
+ email: user.email,
127
+ });
128
+
129
+ return user;
130
+ },
131
+ );
132
+ // Audits are automatically flushed before transaction commits
133
+ // If flush fails, the entire transaction rolls back
134
+ ```
135
+
136
+ ## API Reference
137
+
138
+ ### Core Types
139
+
140
+ #### `AuditableAction<TType, TPayload>`
141
+
142
+ Defines an auditable action with a type and payload:
143
+
144
+ ```typescript
145
+ type UserAction = AuditableAction<'user.created', { userId: string }>;
146
+ ```
147
+
148
+ #### `AuditRecord`
149
+
150
+ Complete audit record with all metadata:
151
+
152
+ ```typescript
153
+ interface AuditRecord<TPayload = unknown> {
154
+ id: string;
155
+ type: string;
156
+ operation: AuditOperation;
157
+ table?: string;
158
+ entityId?: string | Record<string, unknown>;
159
+ oldValues?: Record<string, unknown>;
160
+ newValues?: Record<string, unknown>;
161
+ payload?: TPayload;
162
+ timestamp: Date;
163
+ actor?: AuditActor;
164
+ metadata?: AuditMetadata;
165
+ }
166
+ ```
167
+
168
+ #### `AuditActor`
169
+
170
+ Represents who performed the action:
171
+
172
+ ```typescript
173
+ interface AuditActor {
174
+ id?: string;
175
+ type?: string;
176
+ [key: string]: unknown;
177
+ }
178
+ ```
179
+
180
+ #### `AuditMetadata`
181
+
182
+ Request context and additional data:
183
+
184
+ ```typescript
185
+ interface AuditMetadata {
186
+ requestId?: string;
187
+ endpoint?: string;
188
+ method?: string;
189
+ ip?: string;
190
+ userAgent?: string;
191
+ [key: string]: unknown;
192
+ }
193
+ ```
194
+
195
+ ### `Auditor` Interface
196
+
197
+ ```typescript
198
+ interface Auditor<TAuditAction, TTransaction> {
199
+ readonly actor: AuditActor;
200
+
201
+ // Type-safe audit recording
202
+ audit<TType extends ExtractAuditType<TAuditAction>>(
203
+ type: TType,
204
+ payload: ExtractAuditPayload<TAuditAction, TType>,
205
+ options?: AuditOptions,
206
+ ): void;
207
+
208
+ // Raw record insertion
209
+ record(record: Omit<AuditRecord, 'id' | 'timestamp' | 'actor'>): void;
210
+
211
+ // Get collected records
212
+ getRecords(): AuditRecord[];
213
+
214
+ // Flush to storage
215
+ flush(trx?: TTransaction): Promise<void>;
216
+
217
+ // Clear without flushing
218
+ clear(): void;
219
+
220
+ // Add metadata to future records
221
+ addMetadata(metadata: AuditMetadata): void;
222
+
223
+ // Transaction management
224
+ setTransaction(trx: TTransaction): void;
225
+ getTransaction(): TTransaction | undefined;
226
+ }
227
+ ```
228
+
229
+ ### `AuditStorage` Interface
230
+
231
+ Implement this interface for custom storage backends:
232
+
233
+ ```typescript
234
+ interface AuditStorage<TAuditAction> {
235
+ // Required: Write records
236
+ write(records: AuditRecord[], trx?: unknown): Promise<void>;
237
+
238
+ // Optional: Query records
239
+ query?(options: AuditQueryOptions): Promise<AuditRecord[]>;
240
+
241
+ // Optional: Count records
242
+ count?(options: Omit<AuditQueryOptions, 'limit' | 'offset'>): Promise<number>;
243
+
244
+ // Optional: Get database for transactions
245
+ getDatabase?(): unknown;
246
+ }
247
+ ```
248
+
249
+ ### `KyselyAuditStorage`
250
+
251
+ Built-in Kysely storage implementation:
252
+
253
+ ```typescript
254
+ const storage = new KyselyAuditStorage({
255
+ db: kyselyDb,
256
+ tableName: 'audit_logs',
257
+ databaseServiceName: 'database', // Optional: for automatic transaction injection
258
+ autoId: false, // Optional: let database generate IDs
259
+ });
260
+
261
+ // Query audits
262
+ const audits = await storage.query({
263
+ type: 'user.created',
264
+ actorId: 'user-123',
265
+ from: new Date('2024-01-01'),
266
+ limit: 100,
267
+ orderBy: 'timestamp',
268
+ orderDirection: 'desc',
269
+ });
270
+
271
+ // Count audits
272
+ const count = await storage.count({
273
+ type: ['user.created', 'user.updated'],
274
+ actorId: 'user-123',
275
+ });
276
+ ```
277
+
278
+ ### `InMemoryAuditStorage`
279
+
280
+ Convenience wrapper around `CacheAuditStorage` with `InMemoryCache`. Useful for testing and development:
281
+
282
+ ```typescript
283
+ import { InMemoryAuditStorage } from '@geekmidas/audit/memory';
284
+
285
+ const storage = new InMemoryAuditStorage<AppAuditAction>();
286
+
287
+ // Query audits (same API as other storages)
288
+ const audits = await storage.query({
289
+ type: 'user.created',
290
+ limit: 10,
291
+ });
292
+
293
+ // Get all records (for assertions in tests)
294
+ const allRecords = await storage.getRecords();
295
+
296
+ // Clear all records (reset for next test)
297
+ await storage.clear();
298
+ ```
299
+
300
+ ### `CacheAuditStorage`
301
+
302
+ Cache-based storage using any `@geekmidas/cache` implementation:
303
+
304
+ ```typescript
305
+ import { CacheAuditStorage } from '@geekmidas/audit/cache';
306
+ import { InMemoryCache } from '@geekmidas/cache/memory';
307
+ import { UpstashCache } from '@geekmidas/cache/upstash';
308
+
309
+ // With in-memory cache (development/testing)
310
+ const storage = new CacheAuditStorage({
311
+ cache: new InMemoryCache(),
312
+ ttl: 86400, // 24 hours
313
+ });
314
+
315
+ // With Upstash Redis (production - distributed systems)
316
+ const storage = new CacheAuditStorage({
317
+ cache: new UpstashCache({
318
+ url: process.env.UPSTASH_REDIS_URL,
319
+ token: process.env.UPSTASH_REDIS_TOKEN,
320
+ }),
321
+ prefix: 'audit', // Optional key prefix
322
+ ttl: 604800, // 7 days
323
+ });
324
+
325
+ // Query and count work the same as other storages
326
+ const audits = await storage.query({ type: 'user.created' });
327
+ const count = await storage.count({ actorId: 'user-123' });
328
+
329
+ // Clear all records
330
+ await storage.clear();
331
+ ```
332
+
333
+ ## Database Schema
334
+
335
+ Create an `audit_logs` table for `KyselyAuditStorage`:
336
+
337
+ ```sql
338
+ CREATE TABLE audit_logs (
339
+ id VARCHAR(21) PRIMARY KEY, -- or use gen_random_uuid() with autoId: true
340
+ type VARCHAR(255) NOT NULL,
341
+ operation VARCHAR(20) NOT NULL,
342
+ "table" VARCHAR(255),
343
+ "entityId" VARCHAR(255),
344
+ "oldValues" JSONB,
345
+ "newValues" JSONB,
346
+ payload JSONB,
347
+ timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
348
+ "actorId" VARCHAR(255),
349
+ "actorType" VARCHAR(50),
350
+ "actorData" JSONB,
351
+ metadata JSONB
352
+ );
353
+
354
+ -- Recommended indexes
355
+ CREATE INDEX idx_audit_logs_type ON audit_logs(type);
356
+ CREATE INDEX idx_audit_logs_timestamp ON audit_logs(timestamp);
357
+ CREATE INDEX idx_audit_logs_actor_id ON audit_logs("actorId");
358
+ CREATE INDEX idx_audit_logs_entity_id ON audit_logs("entityId");
359
+ ```
360
+
361
+ ## Integration with @geekmidas/constructs
362
+
363
+ The audit package integrates seamlessly with `@geekmidas/constructs` endpoints:
364
+
365
+ ```typescript
366
+ import { e } from '@geekmidas/constructs/endpoints';
367
+
368
+ const endpoint = e
369
+ .post('/users')
370
+ .body(UserSchema)
371
+ .output(UserResponseSchema)
372
+ .audit([
373
+ {
374
+ type: 'user.created',
375
+ payload: (response) => ({
376
+ userId: response.id,
377
+ email: response.email,
378
+ }),
379
+ },
380
+ ])
381
+ .handle(async ({ body, auditor }) => {
382
+ // Audits are automatically recorded and flushed
383
+ return { id: '123', ...body };
384
+ });
385
+ ```
386
+
387
+ ## Best Practices
388
+
389
+ 1. **Define all audit actions upfront**: Create a union type of all possible audit actions for your application
390
+ 2. **Use transactions**: Wrap database operations and audits in transactions for consistency
391
+ 3. **Include entity references**: Use `entityId` and `table` options for easier querying
392
+ 4. **Add request context**: Include request IDs, endpoints, and IPs in metadata
393
+ 5. **Use meaningful types**: Name audit types with domain context (e.g., `order.shipped` not `update`)
394
+
395
+ ## License
396
+
397
+ MIT
@@ -117,7 +117,50 @@ interface AuditStorage<TAuditAction extends AuditableAction<string, unknown> = A
117
117
  * ```
118
118
  */
119
119
  databaseServiceName?: string;
120
+ /**
121
+ * Optional: Execute a callback within a database transaction.
122
+ * The auditor is registered with the transaction and audits are flushed
123
+ * before the transaction commits.
124
+ *
125
+ * This is database-agnostic - each storage implementation provides its own
126
+ * transaction handling based on the underlying database.
127
+ *
128
+ * If a database connection is provided, it should be used instead of the
129
+ * storage's internal connection. If the connection is already a transaction,
130
+ * it should be reused instead of creating a nested transaction.
131
+ *
132
+ * @param auditor - The auditor to register with the transaction
133
+ * @param callback - The callback to execute within the transaction
134
+ * @param db - Optional database connection (may already be a transaction)
135
+ * @returns The result of the callback
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * // KyselyAuditStorage implementation
140
+ * async withTransaction<T>(auditor, callback, db) {
141
+ * const connection = db ?? this.db;
142
+ * if (connection.isTransaction) {
143
+ * // Reuse existing transaction
144
+ * auditor.setTransaction(connection);
145
+ * const result = await callback();
146
+ * await auditor.flush(connection);
147
+ * return result;
148
+ * }
149
+ * return connection.transaction().execute(async (trx) => {
150
+ * auditor.setTransaction(trx);
151
+ * const result = await callback();
152
+ * await auditor.flush(trx);
153
+ * return result;
154
+ * });
155
+ * }
156
+ * ```
157
+ */
158
+ withTransaction?<T>(auditor: {
159
+ setTransaction(trx: unknown): void;
160
+ flush(trx?: unknown): Promise<void>;
161
+ }, callback: () => Promise<T>, db?: unknown): Promise<T>;
120
162
  }
163
+ //# sourceMappingURL=storage.d.ts.map
121
164
  //#endregion
122
165
  //#region src/types.d.ts
123
166
  /**
@@ -376,6 +419,8 @@ interface Auditor<TAuditAction extends AuditableAction<string, unknown> = Audita
376
419
  */
377
420
  getTransaction(): TTransaction | undefined;
378
421
  }
422
+ //# sourceMappingURL=Auditor.d.ts.map
423
+
379
424
  //#endregion
380
425
  export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditQueryOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit };
381
- //# sourceMappingURL=Auditor-D3me-qKX.d.mts.map
426
+ //# sourceMappingURL=Auditor-_Dn2dp8d.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Auditor-_Dn2dp8d.d.mts","names":[],"sources":["../src/storage.ts","../src/types.ts","../src/Auditor.ts"],"sourcesContent":[],"mappings":"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"}
@@ -117,7 +117,50 @@ interface AuditStorage<TAuditAction extends AuditableAction<string, unknown> = A
117
117
  * ```
118
118
  */
119
119
  databaseServiceName?: string;
120
+ /**
121
+ * Optional: Execute a callback within a database transaction.
122
+ * The auditor is registered with the transaction and audits are flushed
123
+ * before the transaction commits.
124
+ *
125
+ * This is database-agnostic - each storage implementation provides its own
126
+ * transaction handling based on the underlying database.
127
+ *
128
+ * If a database connection is provided, it should be used instead of the
129
+ * storage's internal connection. If the connection is already a transaction,
130
+ * it should be reused instead of creating a nested transaction.
131
+ *
132
+ * @param auditor - The auditor to register with the transaction
133
+ * @param callback - The callback to execute within the transaction
134
+ * @param db - Optional database connection (may already be a transaction)
135
+ * @returns The result of the callback
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * // KyselyAuditStorage implementation
140
+ * async withTransaction<T>(auditor, callback, db) {
141
+ * const connection = db ?? this.db;
142
+ * if (connection.isTransaction) {
143
+ * // Reuse existing transaction
144
+ * auditor.setTransaction(connection);
145
+ * const result = await callback();
146
+ * await auditor.flush(connection);
147
+ * return result;
148
+ * }
149
+ * return connection.transaction().execute(async (trx) => {
150
+ * auditor.setTransaction(trx);
151
+ * const result = await callback();
152
+ * await auditor.flush(trx);
153
+ * return result;
154
+ * });
155
+ * }
156
+ * ```
157
+ */
158
+ withTransaction?<T>(auditor: {
159
+ setTransaction(trx: unknown): void;
160
+ flush(trx?: unknown): Promise<void>;
161
+ }, callback: () => Promise<T>, db?: unknown): Promise<T>;
120
162
  }
163
+ //# sourceMappingURL=storage.d.ts.map
121
164
  //#endregion
122
165
  //#region src/types.d.ts
123
166
  /**
@@ -376,6 +419,8 @@ interface Auditor<TAuditAction extends AuditableAction<string, unknown> = Audita
376
419
  */
377
420
  getTransaction(): TTransaction | undefined;
378
421
  }
422
+ //# sourceMappingURL=Auditor.d.ts.map
423
+
379
424
  //#endregion
380
425
  export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditQueryOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit };
381
- //# sourceMappingURL=Auditor-QYUMGJCH.d.cts.map
426
+ //# sourceMappingURL=Auditor-sW7YAJIA.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Auditor-sW7YAJIA.d.cts","names":[],"sources":["../src/storage.ts","../src/types.ts","../src/Auditor.ts"],"sourcesContent":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { Auditor } from "./Auditor-QYUMGJCH.cjs";
1
+ import { Auditor } from "./Auditor-sW7YAJIA.cjs";
2
2
  export { Auditor };
@@ -1,2 +1,2 @@
1
- import { Auditor } from "./Auditor-D3me-qKX.mjs";
1
+ import { Auditor } from "./Auditor-_Dn2dp8d.mjs";
2
2
  export { Auditor };
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultAuditor-BAVnNmRh.mjs","names":["config: DefaultAuditorConfig","type: TType","payload: ExtractAuditPayload<TAuditAction, TType>","options?: AuditOptions","record: AuditRecord","record: Omit<AuditRecord, 'id' | 'timestamp' | 'actor'>","fullRecord: AuditRecord","trx?: TTransaction","trx: TTransaction","metadata: AuditMetadata"],"sources":["../src/DefaultAuditor.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\nimport type { Auditor } from './Auditor';\nimport type { AuditStorage } from './storage';\nimport type {\n AuditActor,\n AuditMetadata,\n AuditOptions,\n AuditRecord,\n AuditableAction,\n ExtractAuditPayload,\n ExtractAuditType,\n} from './types';\n\n/**\n * Configuration for DefaultAuditor.\n */\nexport interface DefaultAuditorConfig {\n /** The actor performing audits (set at construction, immutable) */\n actor: AuditActor;\n /** Storage backend for persisting audits */\n storage: AuditStorage;\n /** Optional metadata to attach to all audits */\n metadata?: AuditMetadata;\n /** Optional custom ID generator (defaults to nanoid) */\n generateId?: () => string;\n}\n\n/**\n * Default implementation of the Auditor interface.\n * Collects audit records in memory and flushes to storage.\n *\n * @template TAuditAction - Union of all allowed audit action types\n * @template TTransaction - Transaction type (e.g., Kysely Transaction)\n *\n * @example\n * ```typescript\n * const auditor = new DefaultAuditor<AppAuditAction>({\n * actor: { id: 'user-123', type: 'user' },\n * storage: auditStorage,\n * metadata: { requestId: 'req-456', endpoint: '/users' },\n * });\n *\n * auditor.audit('user.created', { userId: '789', email: 'test@example.com' });\n *\n * // Flush inside transaction\n * await auditor.flush(trx);\n * ```\n */\nexport class DefaultAuditor<\n TAuditAction extends AuditableAction<string, unknown> = AuditableAction<\n string,\n unknown\n >,\n TTransaction = unknown,\n> implements Auditor<TAuditAction, TTransaction>\n{\n readonly actor: AuditActor;\n private readonly storage: AuditStorage;\n private metadata?: AuditMetadata;\n private readonly generateId: () => string;\n private records: AuditRecord[] = [];\n private transaction?: TTransaction;\n\n constructor(config: DefaultAuditorConfig) {\n this.actor = config.actor;\n this.storage = config.storage;\n this.metadata = config.metadata;\n this.generateId = config.generateId ?? (() => nanoid());\n }\n\n audit<TType extends ExtractAuditType<TAuditAction>>(\n type: TType,\n payload: ExtractAuditPayload<TAuditAction, TType>,\n options?: AuditOptions,\n ): void {\n const record: AuditRecord = {\n id: this.generateId(),\n type,\n operation: options?.operation ?? 'CUSTOM',\n table: options?.table,\n entityId: options?.entityId,\n oldValues: options?.oldValues,\n newValues: options?.newValues,\n payload,\n timestamp: new Date(),\n actor: this.actor,\n metadata: this.metadata,\n };\n\n this.records.push(record);\n }\n\n record(record: Omit<AuditRecord, 'id' | 'timestamp' | 'actor'>): void {\n const fullRecord: AuditRecord = {\n ...record,\n id: this.generateId(),\n timestamp: new Date(),\n actor: this.actor,\n metadata: this.metadata\n ? { ...this.metadata, ...record.metadata }\n : record.metadata,\n };\n\n this.records.push(fullRecord);\n }\n\n getRecords(): AuditRecord[] {\n return [...this.records];\n }\n\n async flush(trx?: TTransaction): Promise<void> {\n if (this.records.length === 0) {\n return;\n }\n\n const recordsToFlush = [...this.records];\n this.records = [];\n\n // Use explicitly passed transaction, or fall back to stored transaction\n const transactionToUse = trx ?? this.transaction;\n await this.storage.write(recordsToFlush, transactionToUse);\n }\n\n setTransaction(trx: TTransaction): void {\n this.transaction = trx;\n }\n\n getTransaction(): TTransaction | undefined {\n return this.transaction;\n }\n\n clear(): void {\n this.records = [];\n }\n\n addMetadata(metadata: AuditMetadata): void {\n this.metadata = this.metadata\n ? { ...this.metadata, ...metadata }\n : metadata;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAgDA,IAAa,iBAAb,MAOA;CACE,AAAS;CACT,AAAiB;CACjB,AAAQ;CACR,AAAiB;CACjB,AAAQ,UAAyB,CAAE;CACnC,AAAQ;CAER,YAAYA,QAA8B;AACxC,OAAK,QAAQ,OAAO;AACpB,OAAK,UAAU,OAAO;AACtB,OAAK,WAAW,OAAO;AACvB,OAAK,aAAa,OAAO,eAAe,MAAM,QAAQ;CACvD;CAED,MACEC,MACAC,SACAC,SACM;EACN,MAAMC,SAAsB;GAC1B,IAAI,KAAK,YAAY;GACrB;GACA,WAAW,SAAS,aAAa;GACjC,OAAO,SAAS;GAChB,UAAU,SAAS;GACnB,WAAW,SAAS;GACpB,WAAW,SAAS;GACpB;GACA,2BAAW,IAAI;GACf,OAAO,KAAK;GACZ,UAAU,KAAK;EAChB;AAED,OAAK,QAAQ,KAAK,OAAO;CAC1B;CAED,OAAOC,QAA+D;EACpE,MAAMC,aAA0B;GAC9B,GAAG;GACH,IAAI,KAAK,YAAY;GACrB,2BAAW,IAAI;GACf,OAAO,KAAK;GACZ,UAAU,KAAK,WACX;IAAE,GAAG,KAAK;IAAU,GAAG,OAAO;GAAU,IACxC,OAAO;EACZ;AAED,OAAK,QAAQ,KAAK,WAAW;CAC9B;CAED,aAA4B;AAC1B,SAAO,CAAC,GAAG,KAAK,OAAQ;CACzB;CAED,MAAM,MAAMC,KAAmC;AAC7C,MAAI,KAAK,QAAQ,WAAW,EAC1B;EAGF,MAAM,iBAAiB,CAAC,GAAG,KAAK,OAAQ;AACxC,OAAK,UAAU,CAAE;EAGjB,MAAM,mBAAmB,OAAO,KAAK;AACrC,QAAM,KAAK,QAAQ,MAAM,gBAAgB,iBAAiB;CAC3D;CAED,eAAeC,KAAyB;AACtC,OAAK,cAAc;CACpB;CAED,iBAA2C;AACzC,SAAO,KAAK;CACb;CAED,QAAc;AACZ,OAAK,UAAU,CAAE;CAClB;CAED,YAAYC,UAA+B;AACzC,OAAK,WAAW,KAAK,WACjB;GAAE,GAAG,KAAK;GAAU,GAAG;EAAU,IACjC;CACL;AACF"}
1
+ {"version":3,"file":"DefaultAuditor-BAVnNmRh.mjs","names":["config: DefaultAuditorConfig","type: TType","payload: ExtractAuditPayload<TAuditAction, TType>","options?: AuditOptions","record: AuditRecord","record: Omit<AuditRecord, 'id' | 'timestamp' | 'actor'>","fullRecord: AuditRecord","trx?: TTransaction","trx: TTransaction","metadata: AuditMetadata"],"sources":["../src/DefaultAuditor.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\nimport type { Auditor } from './Auditor';\nimport type { AuditStorage } from './storage';\nimport type {\n\tAuditActor,\n\tAuditableAction,\n\tAuditMetadata,\n\tAuditOptions,\n\tAuditRecord,\n\tExtractAuditPayload,\n\tExtractAuditType,\n} from './types';\n\n/**\n * Configuration for DefaultAuditor.\n */\nexport interface DefaultAuditorConfig {\n\t/** The actor performing audits (set at construction, immutable) */\n\tactor: AuditActor;\n\t/** Storage backend for persisting audits */\n\tstorage: AuditStorage;\n\t/** Optional metadata to attach to all audits */\n\tmetadata?: AuditMetadata;\n\t/** Optional custom ID generator (defaults to nanoid) */\n\tgenerateId?: () => string;\n}\n\n/**\n * Default implementation of the Auditor interface.\n * Collects audit records in memory and flushes to storage.\n *\n * @template TAuditAction - Union of all allowed audit action types\n * @template TTransaction - Transaction type (e.g., Kysely Transaction)\n *\n * @example\n * ```typescript\n * const auditor = new DefaultAuditor<AppAuditAction>({\n * actor: { id: 'user-123', type: 'user' },\n * storage: auditStorage,\n * metadata: { requestId: 'req-456', endpoint: '/users' },\n * });\n *\n * auditor.audit('user.created', { userId: '789', email: 'test@example.com' });\n *\n * // Flush inside transaction\n * await auditor.flush(trx);\n * ```\n */\nexport class DefaultAuditor<\n\tTAuditAction extends AuditableAction<string, unknown> = AuditableAction<\n\t\tstring,\n\t\tunknown\n\t>,\n\tTTransaction = unknown,\n> implements Auditor<TAuditAction, TTransaction>\n{\n\treadonly actor: AuditActor;\n\tprivate readonly storage: AuditStorage;\n\tprivate metadata?: AuditMetadata;\n\tprivate readonly generateId: () => string;\n\tprivate records: AuditRecord[] = [];\n\tprivate transaction?: TTransaction;\n\n\tconstructor(config: DefaultAuditorConfig) {\n\t\tthis.actor = config.actor;\n\t\tthis.storage = config.storage;\n\t\tthis.metadata = config.metadata;\n\t\tthis.generateId = config.generateId ?? (() => nanoid());\n\t}\n\n\taudit<TType extends ExtractAuditType<TAuditAction>>(\n\t\ttype: TType,\n\t\tpayload: ExtractAuditPayload<TAuditAction, TType>,\n\t\toptions?: AuditOptions,\n\t): void {\n\t\tconst record: AuditRecord = {\n\t\t\tid: this.generateId(),\n\t\t\ttype,\n\t\t\toperation: options?.operation ?? 'CUSTOM',\n\t\t\ttable: options?.table,\n\t\t\tentityId: options?.entityId,\n\t\t\toldValues: options?.oldValues,\n\t\t\tnewValues: options?.newValues,\n\t\t\tpayload,\n\t\t\ttimestamp: new Date(),\n\t\t\tactor: this.actor,\n\t\t\tmetadata: this.metadata,\n\t\t};\n\n\t\tthis.records.push(record);\n\t}\n\n\trecord(record: Omit<AuditRecord, 'id' | 'timestamp' | 'actor'>): void {\n\t\tconst fullRecord: AuditRecord = {\n\t\t\t...record,\n\t\t\tid: this.generateId(),\n\t\t\ttimestamp: new Date(),\n\t\t\tactor: this.actor,\n\t\t\tmetadata: this.metadata\n\t\t\t\t? { ...this.metadata, ...record.metadata }\n\t\t\t\t: record.metadata,\n\t\t};\n\n\t\tthis.records.push(fullRecord);\n\t}\n\n\tgetRecords(): AuditRecord[] {\n\t\treturn [...this.records];\n\t}\n\n\tasync flush(trx?: TTransaction): Promise<void> {\n\t\tif (this.records.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst recordsToFlush = [...this.records];\n\t\tthis.records = [];\n\n\t\t// Use explicitly passed transaction, or fall back to stored transaction\n\t\tconst transactionToUse = trx ?? this.transaction;\n\t\tawait this.storage.write(recordsToFlush, transactionToUse);\n\t}\n\n\tsetTransaction(trx: TTransaction): void {\n\t\tthis.transaction = trx;\n\t}\n\n\tgetTransaction(): TTransaction | undefined {\n\t\treturn this.transaction;\n\t}\n\n\tclear(): void {\n\t\tthis.records = [];\n\t}\n\n\taddMetadata(metadata: AuditMetadata): void {\n\t\tthis.metadata = this.metadata\n\t\t\t? { ...this.metadata, ...metadata }\n\t\t\t: metadata;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAgDA,IAAa,iBAAb,MAOA;CACC,AAAS;CACT,AAAiB;CACjB,AAAQ;CACR,AAAiB;CACjB,AAAQ,UAAyB,CAAE;CACnC,AAAQ;CAER,YAAYA,QAA8B;AACzC,OAAK,QAAQ,OAAO;AACpB,OAAK,UAAU,OAAO;AACtB,OAAK,WAAW,OAAO;AACvB,OAAK,aAAa,OAAO,eAAe,MAAM,QAAQ;CACtD;CAED,MACCC,MACAC,SACAC,SACO;EACP,MAAMC,SAAsB;GAC3B,IAAI,KAAK,YAAY;GACrB;GACA,WAAW,SAAS,aAAa;GACjC,OAAO,SAAS;GAChB,UAAU,SAAS;GACnB,WAAW,SAAS;GACpB,WAAW,SAAS;GACpB;GACA,2BAAW,IAAI;GACf,OAAO,KAAK;GACZ,UAAU,KAAK;EACf;AAED,OAAK,QAAQ,KAAK,OAAO;CACzB;CAED,OAAOC,QAA+D;EACrE,MAAMC,aAA0B;GAC/B,GAAG;GACH,IAAI,KAAK,YAAY;GACrB,2BAAW,IAAI;GACf,OAAO,KAAK;GACZ,UAAU,KAAK,WACZ;IAAE,GAAG,KAAK;IAAU,GAAG,OAAO;GAAU,IACxC,OAAO;EACV;AAED,OAAK,QAAQ,KAAK,WAAW;CAC7B;CAED,aAA4B;AAC3B,SAAO,CAAC,GAAG,KAAK,OAAQ;CACxB;CAED,MAAM,MAAMC,KAAmC;AAC9C,MAAI,KAAK,QAAQ,WAAW,EAC3B;EAGD,MAAM,iBAAiB,CAAC,GAAG,KAAK,OAAQ;AACxC,OAAK,UAAU,CAAE;EAGjB,MAAM,mBAAmB,OAAO,KAAK;AACrC,QAAM,KAAK,QAAQ,MAAM,gBAAgB,iBAAiB;CAC1D;CAED,eAAeC,KAAyB;AACvC,OAAK,cAAc;CACnB;CAED,iBAA2C;AAC1C,SAAO,KAAK;CACZ;CAED,QAAc;AACb,OAAK,UAAU,CAAE;CACjB;CAED,YAAYC,UAA+B;AAC1C,OAAK,WAAW,KAAK,WAClB;GAAE,GAAG,KAAK;GAAU,GAAG;EAAU,IACjC;CACH;AACD"}
@@ -1,4 +1,4 @@
1
- import { AuditActor, AuditMetadata, AuditOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType } from "./Auditor-QYUMGJCH.cjs";
1
+ import { AuditActor, AuditMetadata, AuditOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType } from "./Auditor-sW7YAJIA.cjs";
2
2
 
3
3
  //#region src/DefaultAuditor.d.ts
4
4
 
@@ -53,6 +53,7 @@ declare class DefaultAuditor<TAuditAction extends AuditableAction<string, unknow
53
53
  clear(): void;
54
54
  addMetadata(metadata: AuditMetadata): void;
55
55
  }
56
+ //# sourceMappingURL=DefaultAuditor.d.ts.map
56
57
  //#endregion
57
58
  export { DefaultAuditor, DefaultAuditorConfig };
58
- //# sourceMappingURL=DefaultAuditor-BTuMMiWh.d.cts.map
59
+ //# sourceMappingURL=DefaultAuditor-BSYMwojG.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultAuditor-BSYMwojG.d.cts","names":[],"sources":["../src/DefaultAuditor.ts"],"sourcesContent":[],"mappings":";;;;AAgBA;;;AAIU,UAJO,oBAAA,CAIP;EAAY;EAEG,KAAA,EAJjB,UAIiB;EA0BZ;EAAc,OAAA,EA5BjB,YA4BiB;EAAA;EACU,QAAoB,CAAA,EA3B7C,aA2B6C;EAAe;EAKvC,UAAE,CAAA,EAAA,GAAA,GAAA,MAAA;;;;;;;;;;;;;;;;;;;AAAf;;;;cANP,oCACS,mCAAmC,qEAK5C,QAAQ,cAAc;kBAElB;;;;;;sBAOI;sBAOA,iBAAiB,qBAC9B,gBACG,oBAAoB,cAAc,kBACjC;iBAmBI,KAAK;gBAcN;cAII,eAAe;sBAab;oBAIF;;wBAQI"}
@@ -1,4 +1,4 @@
1
- import { AuditActor, AuditMetadata, AuditOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType } from "./Auditor-D3me-qKX.mjs";
1
+ import { AuditActor, AuditMetadata, AuditOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType } from "./Auditor-_Dn2dp8d.mjs";
2
2
 
3
3
  //#region src/DefaultAuditor.d.ts
4
4
 
@@ -53,6 +53,7 @@ declare class DefaultAuditor<TAuditAction extends AuditableAction<string, unknow
53
53
  clear(): void;
54
54
  addMetadata(metadata: AuditMetadata): void;
55
55
  }
56
+ //# sourceMappingURL=DefaultAuditor.d.ts.map
56
57
  //#endregion
57
58
  export { DefaultAuditor, DefaultAuditorConfig };
58
- //# sourceMappingURL=DefaultAuditor-C1FWrJg6.d.mts.map
59
+ //# sourceMappingURL=DefaultAuditor-CYE-uAry.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultAuditor-CYE-uAry.d.mts","names":[],"sources":["../src/DefaultAuditor.ts"],"sourcesContent":[],"mappings":";;;;AAgBA;;;AAIU,UAJO,oBAAA,CAIP;EAAY;EAEG,KAAA,EAJjB,UAIiB;EA0BZ;EAAc,OAAA,EA5BjB,YA4BiB;EAAA;EACU,QAAoB,CAAA,EA3B7C,aA2B6C;EAAe;EAKvC,UAAE,CAAA,EAAA,GAAA,GAAA,MAAA;;;;;;;;;;;;;;;;;;;AAAf;;;;cANP,oCACS,mCAAmC,qEAK5C,QAAQ,cAAc;kBAElB;;;;;;sBAOI;sBAOA,iBAAiB,qBAC9B,gBACG,oBAAoB,cAAc,kBACjC;iBAmBI,KAAK;gBAcN;cAII,eAAe;sBAab;oBAIF;;wBAQI"}
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultAuditor-JbZ_BQfh.cjs","names":["config: DefaultAuditorConfig","type: TType","payload: ExtractAuditPayload<TAuditAction, TType>","options?: AuditOptions","record: AuditRecord","record: Omit<AuditRecord, 'id' | 'timestamp' | 'actor'>","fullRecord: AuditRecord","trx?: TTransaction","trx: TTransaction","metadata: AuditMetadata"],"sources":["../src/DefaultAuditor.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\nimport type { Auditor } from './Auditor';\nimport type { AuditStorage } from './storage';\nimport type {\n AuditActor,\n AuditMetadata,\n AuditOptions,\n AuditRecord,\n AuditableAction,\n ExtractAuditPayload,\n ExtractAuditType,\n} from './types';\n\n/**\n * Configuration for DefaultAuditor.\n */\nexport interface DefaultAuditorConfig {\n /** The actor performing audits (set at construction, immutable) */\n actor: AuditActor;\n /** Storage backend for persisting audits */\n storage: AuditStorage;\n /** Optional metadata to attach to all audits */\n metadata?: AuditMetadata;\n /** Optional custom ID generator (defaults to nanoid) */\n generateId?: () => string;\n}\n\n/**\n * Default implementation of the Auditor interface.\n * Collects audit records in memory and flushes to storage.\n *\n * @template TAuditAction - Union of all allowed audit action types\n * @template TTransaction - Transaction type (e.g., Kysely Transaction)\n *\n * @example\n * ```typescript\n * const auditor = new DefaultAuditor<AppAuditAction>({\n * actor: { id: 'user-123', type: 'user' },\n * storage: auditStorage,\n * metadata: { requestId: 'req-456', endpoint: '/users' },\n * });\n *\n * auditor.audit('user.created', { userId: '789', email: 'test@example.com' });\n *\n * // Flush inside transaction\n * await auditor.flush(trx);\n * ```\n */\nexport class DefaultAuditor<\n TAuditAction extends AuditableAction<string, unknown> = AuditableAction<\n string,\n unknown\n >,\n TTransaction = unknown,\n> implements Auditor<TAuditAction, TTransaction>\n{\n readonly actor: AuditActor;\n private readonly storage: AuditStorage;\n private metadata?: AuditMetadata;\n private readonly generateId: () => string;\n private records: AuditRecord[] = [];\n private transaction?: TTransaction;\n\n constructor(config: DefaultAuditorConfig) {\n this.actor = config.actor;\n this.storage = config.storage;\n this.metadata = config.metadata;\n this.generateId = config.generateId ?? (() => nanoid());\n }\n\n audit<TType extends ExtractAuditType<TAuditAction>>(\n type: TType,\n payload: ExtractAuditPayload<TAuditAction, TType>,\n options?: AuditOptions,\n ): void {\n const record: AuditRecord = {\n id: this.generateId(),\n type,\n operation: options?.operation ?? 'CUSTOM',\n table: options?.table,\n entityId: options?.entityId,\n oldValues: options?.oldValues,\n newValues: options?.newValues,\n payload,\n timestamp: new Date(),\n actor: this.actor,\n metadata: this.metadata,\n };\n\n this.records.push(record);\n }\n\n record(record: Omit<AuditRecord, 'id' | 'timestamp' | 'actor'>): void {\n const fullRecord: AuditRecord = {\n ...record,\n id: this.generateId(),\n timestamp: new Date(),\n actor: this.actor,\n metadata: this.metadata\n ? { ...this.metadata, ...record.metadata }\n : record.metadata,\n };\n\n this.records.push(fullRecord);\n }\n\n getRecords(): AuditRecord[] {\n return [...this.records];\n }\n\n async flush(trx?: TTransaction): Promise<void> {\n if (this.records.length === 0) {\n return;\n }\n\n const recordsToFlush = [...this.records];\n this.records = [];\n\n // Use explicitly passed transaction, or fall back to stored transaction\n const transactionToUse = trx ?? this.transaction;\n await this.storage.write(recordsToFlush, transactionToUse);\n }\n\n setTransaction(trx: TTransaction): void {\n this.transaction = trx;\n }\n\n getTransaction(): TTransaction | undefined {\n return this.transaction;\n }\n\n clear(): void {\n this.records = [];\n }\n\n addMetadata(metadata: AuditMetadata): void {\n this.metadata = this.metadata\n ? { ...this.metadata, ...metadata }\n : metadata;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,IAAa,iBAAb,MAOA;CACE,AAAS;CACT,AAAiB;CACjB,AAAQ;CACR,AAAiB;CACjB,AAAQ,UAAyB,CAAE;CACnC,AAAQ;CAER,YAAYA,QAA8B;AACxC,OAAK,QAAQ,OAAO;AACpB,OAAK,UAAU,OAAO;AACtB,OAAK,WAAW,OAAO;AACvB,OAAK,aAAa,OAAO,eAAe,MAAM,oBAAQ;CACvD;CAED,MACEC,MACAC,SACAC,SACM;EACN,MAAMC,SAAsB;GAC1B,IAAI,KAAK,YAAY;GACrB;GACA,WAAW,SAAS,aAAa;GACjC,OAAO,SAAS;GAChB,UAAU,SAAS;GACnB,WAAW,SAAS;GACpB,WAAW,SAAS;GACpB;GACA,2BAAW,IAAI;GACf,OAAO,KAAK;GACZ,UAAU,KAAK;EAChB;AAED,OAAK,QAAQ,KAAK,OAAO;CAC1B;CAED,OAAOC,QAA+D;EACpE,MAAMC,aAA0B;GAC9B,GAAG;GACH,IAAI,KAAK,YAAY;GACrB,2BAAW,IAAI;GACf,OAAO,KAAK;GACZ,UAAU,KAAK,WACX;IAAE,GAAG,KAAK;IAAU,GAAG,OAAO;GAAU,IACxC,OAAO;EACZ;AAED,OAAK,QAAQ,KAAK,WAAW;CAC9B;CAED,aAA4B;AAC1B,SAAO,CAAC,GAAG,KAAK,OAAQ;CACzB;CAED,MAAM,MAAMC,KAAmC;AAC7C,MAAI,KAAK,QAAQ,WAAW,EAC1B;EAGF,MAAM,iBAAiB,CAAC,GAAG,KAAK,OAAQ;AACxC,OAAK,UAAU,CAAE;EAGjB,MAAM,mBAAmB,OAAO,KAAK;AACrC,QAAM,KAAK,QAAQ,MAAM,gBAAgB,iBAAiB;CAC3D;CAED,eAAeC,KAAyB;AACtC,OAAK,cAAc;CACpB;CAED,iBAA2C;AACzC,SAAO,KAAK;CACb;CAED,QAAc;AACZ,OAAK,UAAU,CAAE;CAClB;CAED,YAAYC,UAA+B;AACzC,OAAK,WAAW,KAAK,WACjB;GAAE,GAAG,KAAK;GAAU,GAAG;EAAU,IACjC;CACL;AACF"}
1
+ {"version":3,"file":"DefaultAuditor-JbZ_BQfh.cjs","names":["config: DefaultAuditorConfig","type: TType","payload: ExtractAuditPayload<TAuditAction, TType>","options?: AuditOptions","record: AuditRecord","record: Omit<AuditRecord, 'id' | 'timestamp' | 'actor'>","fullRecord: AuditRecord","trx?: TTransaction","trx: TTransaction","metadata: AuditMetadata"],"sources":["../src/DefaultAuditor.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\nimport type { Auditor } from './Auditor';\nimport type { AuditStorage } from './storage';\nimport type {\n\tAuditActor,\n\tAuditableAction,\n\tAuditMetadata,\n\tAuditOptions,\n\tAuditRecord,\n\tExtractAuditPayload,\n\tExtractAuditType,\n} from './types';\n\n/**\n * Configuration for DefaultAuditor.\n */\nexport interface DefaultAuditorConfig {\n\t/** The actor performing audits (set at construction, immutable) */\n\tactor: AuditActor;\n\t/** Storage backend for persisting audits */\n\tstorage: AuditStorage;\n\t/** Optional metadata to attach to all audits */\n\tmetadata?: AuditMetadata;\n\t/** Optional custom ID generator (defaults to nanoid) */\n\tgenerateId?: () => string;\n}\n\n/**\n * Default implementation of the Auditor interface.\n * Collects audit records in memory and flushes to storage.\n *\n * @template TAuditAction - Union of all allowed audit action types\n * @template TTransaction - Transaction type (e.g., Kysely Transaction)\n *\n * @example\n * ```typescript\n * const auditor = new DefaultAuditor<AppAuditAction>({\n * actor: { id: 'user-123', type: 'user' },\n * storage: auditStorage,\n * metadata: { requestId: 'req-456', endpoint: '/users' },\n * });\n *\n * auditor.audit('user.created', { userId: '789', email: 'test@example.com' });\n *\n * // Flush inside transaction\n * await auditor.flush(trx);\n * ```\n */\nexport class DefaultAuditor<\n\tTAuditAction extends AuditableAction<string, unknown> = AuditableAction<\n\t\tstring,\n\t\tunknown\n\t>,\n\tTTransaction = unknown,\n> implements Auditor<TAuditAction, TTransaction>\n{\n\treadonly actor: AuditActor;\n\tprivate readonly storage: AuditStorage;\n\tprivate metadata?: AuditMetadata;\n\tprivate readonly generateId: () => string;\n\tprivate records: AuditRecord[] = [];\n\tprivate transaction?: TTransaction;\n\n\tconstructor(config: DefaultAuditorConfig) {\n\t\tthis.actor = config.actor;\n\t\tthis.storage = config.storage;\n\t\tthis.metadata = config.metadata;\n\t\tthis.generateId = config.generateId ?? (() => nanoid());\n\t}\n\n\taudit<TType extends ExtractAuditType<TAuditAction>>(\n\t\ttype: TType,\n\t\tpayload: ExtractAuditPayload<TAuditAction, TType>,\n\t\toptions?: AuditOptions,\n\t): void {\n\t\tconst record: AuditRecord = {\n\t\t\tid: this.generateId(),\n\t\t\ttype,\n\t\t\toperation: options?.operation ?? 'CUSTOM',\n\t\t\ttable: options?.table,\n\t\t\tentityId: options?.entityId,\n\t\t\toldValues: options?.oldValues,\n\t\t\tnewValues: options?.newValues,\n\t\t\tpayload,\n\t\t\ttimestamp: new Date(),\n\t\t\tactor: this.actor,\n\t\t\tmetadata: this.metadata,\n\t\t};\n\n\t\tthis.records.push(record);\n\t}\n\n\trecord(record: Omit<AuditRecord, 'id' | 'timestamp' | 'actor'>): void {\n\t\tconst fullRecord: AuditRecord = {\n\t\t\t...record,\n\t\t\tid: this.generateId(),\n\t\t\ttimestamp: new Date(),\n\t\t\tactor: this.actor,\n\t\t\tmetadata: this.metadata\n\t\t\t\t? { ...this.metadata, ...record.metadata }\n\t\t\t\t: record.metadata,\n\t\t};\n\n\t\tthis.records.push(fullRecord);\n\t}\n\n\tgetRecords(): AuditRecord[] {\n\t\treturn [...this.records];\n\t}\n\n\tasync flush(trx?: TTransaction): Promise<void> {\n\t\tif (this.records.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst recordsToFlush = [...this.records];\n\t\tthis.records = [];\n\n\t\t// Use explicitly passed transaction, or fall back to stored transaction\n\t\tconst transactionToUse = trx ?? this.transaction;\n\t\tawait this.storage.write(recordsToFlush, transactionToUse);\n\t}\n\n\tsetTransaction(trx: TTransaction): void {\n\t\tthis.transaction = trx;\n\t}\n\n\tgetTransaction(): TTransaction | undefined {\n\t\treturn this.transaction;\n\t}\n\n\tclear(): void {\n\t\tthis.records = [];\n\t}\n\n\taddMetadata(metadata: AuditMetadata): void {\n\t\tthis.metadata = this.metadata\n\t\t\t? { ...this.metadata, ...metadata }\n\t\t\t: metadata;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,IAAa,iBAAb,MAOA;CACC,AAAS;CACT,AAAiB;CACjB,AAAQ;CACR,AAAiB;CACjB,AAAQ,UAAyB,CAAE;CACnC,AAAQ;CAER,YAAYA,QAA8B;AACzC,OAAK,QAAQ,OAAO;AACpB,OAAK,UAAU,OAAO;AACtB,OAAK,WAAW,OAAO;AACvB,OAAK,aAAa,OAAO,eAAe,MAAM,oBAAQ;CACtD;CAED,MACCC,MACAC,SACAC,SACO;EACP,MAAMC,SAAsB;GAC3B,IAAI,KAAK,YAAY;GACrB;GACA,WAAW,SAAS,aAAa;GACjC,OAAO,SAAS;GAChB,UAAU,SAAS;GACnB,WAAW,SAAS;GACpB,WAAW,SAAS;GACpB;GACA,2BAAW,IAAI;GACf,OAAO,KAAK;GACZ,UAAU,KAAK;EACf;AAED,OAAK,QAAQ,KAAK,OAAO;CACzB;CAED,OAAOC,QAA+D;EACrE,MAAMC,aAA0B;GAC/B,GAAG;GACH,IAAI,KAAK,YAAY;GACrB,2BAAW,IAAI;GACf,OAAO,KAAK;GACZ,UAAU,KAAK,WACZ;IAAE,GAAG,KAAK;IAAU,GAAG,OAAO;GAAU,IACxC,OAAO;EACV;AAED,OAAK,QAAQ,KAAK,WAAW;CAC7B;CAED,aAA4B;AAC3B,SAAO,CAAC,GAAG,KAAK,OAAQ;CACxB;CAED,MAAM,MAAMC,KAAmC;AAC9C,MAAI,KAAK,QAAQ,WAAW,EAC3B;EAGD,MAAM,iBAAiB,CAAC,GAAG,KAAK,OAAQ;AACxC,OAAK,UAAU,CAAE;EAGjB,MAAM,mBAAmB,OAAO,KAAK;AACrC,QAAM,KAAK,QAAQ,MAAM,gBAAgB,iBAAiB;CAC1D;CAED,eAAeC,KAAyB;AACvC,OAAK,cAAc;CACnB;CAED,iBAA2C;AAC1C,SAAO,KAAK;CACZ;CAED,QAAc;AACb,OAAK,UAAU,CAAE;CACjB;CAED,YAAYC,UAA+B;AAC1C,OAAK,WAAW,KAAK,WAClB;GAAE,GAAG,KAAK;GAAU,GAAG;EAAU,IACjC;CACH;AACD"}
@@ -1,3 +1,3 @@
1
- import "./Auditor-QYUMGJCH.cjs";
2
- import { DefaultAuditor, DefaultAuditorConfig } from "./DefaultAuditor-BTuMMiWh.cjs";
1
+ import "./Auditor-sW7YAJIA.cjs";
2
+ import { DefaultAuditor, DefaultAuditorConfig } from "./DefaultAuditor-BSYMwojG.cjs";
3
3
  export { DefaultAuditor, DefaultAuditorConfig };