@geekmidas/audit 0.0.4 → 0.0.5

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.
@@ -1,8 +1,125 @@
1
1
  import { InferStandardSchema } from "@geekmidas/schema";
2
2
  import { StandardSchemaV1 } from "@standard-schema/spec";
3
3
 
4
+ //#region src/storage.d.ts
5
+ /**
6
+ * Options for querying audit records.
7
+ */
8
+ interface AuditQueryOptions {
9
+ /** Filter by audit type */
10
+ type?: string | string[];
11
+ /** Filter by entity ID */
12
+ entityId?: string | Record<string, unknown>;
13
+ /** Filter by table name */
14
+ table?: string;
15
+ /** Filter by actor ID */
16
+ actorId?: string;
17
+ /** Filter by date range (start) */
18
+ from?: Date;
19
+ /** Filter by date range (end) */
20
+ to?: Date;
21
+ /** Limit number of results */
22
+ limit?: number;
23
+ /** Offset for pagination */
24
+ offset?: number;
25
+ /** Sort order */
26
+ orderBy?: 'timestamp' | 'type';
27
+ /** Sort direction */
28
+ orderDirection?: 'asc' | 'desc';
29
+ }
30
+ /**
31
+ * Interface for audit storage backends.
32
+ * Implement this to store audits in your preferred location.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // Same database storage (recommended for transactions)
37
+ * const auditStorage: AuditStorage = {
38
+ * async write(records, trx) {
39
+ * const db = trx ?? getDatabase();
40
+ * await db.insertInto('audit_logs').values(records).execute();
41
+ * },
42
+ * };
43
+ *
44
+ * // External audit service
45
+ * const externalAuditStorage: AuditStorage = {
46
+ * async write(records) {
47
+ * await fetch('https://audit.example.com/api/audits', {
48
+ * method: 'POST',
49
+ * body: JSON.stringify({ records }),
50
+ * });
51
+ * },
52
+ * };
53
+ * ```
54
+ *
55
+ * @template TAuditAction - Optional type parameter for type-safe audit actions.
56
+ * When provided, this type is preserved in the Service definition and can be
57
+ * extracted by EndpointBuilder to provide type inference for `.audit([...])`.
58
+ */
59
+ interface AuditStorage<TAuditAction extends AuditableAction<string, unknown> = AuditableAction<string, unknown>> {
60
+ /** @internal Type marker for extracting audit action type */
61
+ readonly __auditActionType?: TAuditAction;
62
+ /**
63
+ * Write audit records to storage.
64
+ * Called by Auditor.flush() to persist collected audits.
65
+ *
66
+ * @param records - The audit records to write
67
+ * @param trx - Optional transaction context (for same-DB storage)
68
+ */
69
+ write(records: AuditRecord[], trx?: unknown): Promise<void>;
70
+ /**
71
+ * Optional: Query audit records for retrieval.
72
+ * Implement this for audit log viewing/searching.
73
+ *
74
+ * @param options - Query filters and pagination
75
+ * @returns Matching audit records
76
+ */
77
+ query?(options: AuditQueryOptions): Promise<AuditRecord[]>;
78
+ /**
79
+ * Optional: Count audit records matching filters.
80
+ * Useful for pagination.
81
+ *
82
+ * @param options - Query filters (limit/offset ignored)
83
+ * @returns Count of matching records
84
+ */
85
+ count?(options: Omit<AuditQueryOptions, 'limit' | 'offset'>): Promise<number>;
86
+ /**
87
+ * Optional: Get the database connection for transactional audit writes.
88
+ * When implemented, the endpoint adaptor can automatically wrap handlers
89
+ * in a transaction, ensuring audits are atomic with other database operations.
90
+ *
91
+ * @returns Database connection (e.g., Kysely instance)
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * class KyselyAuditStorage implements AuditStorage {
96
+ * constructor(private db: Kysely<DB>) {}
97
+ *
98
+ * getDatabase() {
99
+ * return this.db;
100
+ * }
101
+ * }
102
+ * ```
103
+ */
104
+ getDatabase?(): unknown;
105
+ /**
106
+ * Optional: The service name of the database service used by this storage.
107
+ * When set, endpoint adaptors will automatically use the audit transaction as `db`
108
+ * in the handler context if the endpoint's database service has the same name.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const storage = new KyselyAuditStorage({
113
+ * db,
114
+ * tableName: 'audit_logs',
115
+ * databaseServiceName: 'database', // Matches databaseService.serviceName
116
+ * });
117
+ * ```
118
+ */
119
+ databaseServiceName?: string;
120
+ }
121
+ //#endregion
4
122
  //#region src/types.d.ts
5
-
6
123
  /**
7
124
  * Represents an auditable action with a type and payload.
8
125
  * Similar to PublishableMessage in @geekmidas/events.
@@ -124,6 +241,10 @@ interface MappedAudit<TAuditAction extends AuditableAction<string, unknown>, TOu
124
241
  * Extract the AuditableAction type from an Auditor.
125
242
  */
126
243
  type ExtractAuditorAction<T> = T extends Auditor<infer A> ? A : never;
244
+ /**
245
+ * Extract the AuditableAction type from an AuditStorage.
246
+ */
247
+ type ExtractStorageAuditAction<T> = T extends AuditStorage<infer A> ? A : AuditableAction<string, unknown>;
127
248
  //#endregion
128
249
  //#region src/Auditor.d.ts
129
250
  /**
@@ -256,5 +377,5 @@ interface Auditor<TAuditAction extends AuditableAction<string, unknown> = Audita
256
377
  getTransaction(): TTransaction | undefined;
257
378
  }
258
379
  //#endregion
259
- export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, MappedAudit };
260
- //# sourceMappingURL=Auditor-CZ8lkASv.d.cts.map
380
+ export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditQueryOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit };
381
+ //# sourceMappingURL=Auditor-D3me-qKX.d.mts.map
@@ -1,8 +1,125 @@
1
1
  import { InferStandardSchema } from "@geekmidas/schema";
2
2
  import { StandardSchemaV1 } from "@standard-schema/spec";
3
3
 
4
+ //#region src/storage.d.ts
5
+ /**
6
+ * Options for querying audit records.
7
+ */
8
+ interface AuditQueryOptions {
9
+ /** Filter by audit type */
10
+ type?: string | string[];
11
+ /** Filter by entity ID */
12
+ entityId?: string | Record<string, unknown>;
13
+ /** Filter by table name */
14
+ table?: string;
15
+ /** Filter by actor ID */
16
+ actorId?: string;
17
+ /** Filter by date range (start) */
18
+ from?: Date;
19
+ /** Filter by date range (end) */
20
+ to?: Date;
21
+ /** Limit number of results */
22
+ limit?: number;
23
+ /** Offset for pagination */
24
+ offset?: number;
25
+ /** Sort order */
26
+ orderBy?: 'timestamp' | 'type';
27
+ /** Sort direction */
28
+ orderDirection?: 'asc' | 'desc';
29
+ }
30
+ /**
31
+ * Interface for audit storage backends.
32
+ * Implement this to store audits in your preferred location.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // Same database storage (recommended for transactions)
37
+ * const auditStorage: AuditStorage = {
38
+ * async write(records, trx) {
39
+ * const db = trx ?? getDatabase();
40
+ * await db.insertInto('audit_logs').values(records).execute();
41
+ * },
42
+ * };
43
+ *
44
+ * // External audit service
45
+ * const externalAuditStorage: AuditStorage = {
46
+ * async write(records) {
47
+ * await fetch('https://audit.example.com/api/audits', {
48
+ * method: 'POST',
49
+ * body: JSON.stringify({ records }),
50
+ * });
51
+ * },
52
+ * };
53
+ * ```
54
+ *
55
+ * @template TAuditAction - Optional type parameter for type-safe audit actions.
56
+ * When provided, this type is preserved in the Service definition and can be
57
+ * extracted by EndpointBuilder to provide type inference for `.audit([...])`.
58
+ */
59
+ interface AuditStorage<TAuditAction extends AuditableAction<string, unknown> = AuditableAction<string, unknown>> {
60
+ /** @internal Type marker for extracting audit action type */
61
+ readonly __auditActionType?: TAuditAction;
62
+ /**
63
+ * Write audit records to storage.
64
+ * Called by Auditor.flush() to persist collected audits.
65
+ *
66
+ * @param records - The audit records to write
67
+ * @param trx - Optional transaction context (for same-DB storage)
68
+ */
69
+ write(records: AuditRecord[], trx?: unknown): Promise<void>;
70
+ /**
71
+ * Optional: Query audit records for retrieval.
72
+ * Implement this for audit log viewing/searching.
73
+ *
74
+ * @param options - Query filters and pagination
75
+ * @returns Matching audit records
76
+ */
77
+ query?(options: AuditQueryOptions): Promise<AuditRecord[]>;
78
+ /**
79
+ * Optional: Count audit records matching filters.
80
+ * Useful for pagination.
81
+ *
82
+ * @param options - Query filters (limit/offset ignored)
83
+ * @returns Count of matching records
84
+ */
85
+ count?(options: Omit<AuditQueryOptions, 'limit' | 'offset'>): Promise<number>;
86
+ /**
87
+ * Optional: Get the database connection for transactional audit writes.
88
+ * When implemented, the endpoint adaptor can automatically wrap handlers
89
+ * in a transaction, ensuring audits are atomic with other database operations.
90
+ *
91
+ * @returns Database connection (e.g., Kysely instance)
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * class KyselyAuditStorage implements AuditStorage {
96
+ * constructor(private db: Kysely<DB>) {}
97
+ *
98
+ * getDatabase() {
99
+ * return this.db;
100
+ * }
101
+ * }
102
+ * ```
103
+ */
104
+ getDatabase?(): unknown;
105
+ /**
106
+ * Optional: The service name of the database service used by this storage.
107
+ * When set, endpoint adaptors will automatically use the audit transaction as `db`
108
+ * in the handler context if the endpoint's database service has the same name.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const storage = new KyselyAuditStorage({
113
+ * db,
114
+ * tableName: 'audit_logs',
115
+ * databaseServiceName: 'database', // Matches databaseService.serviceName
116
+ * });
117
+ * ```
118
+ */
119
+ databaseServiceName?: string;
120
+ }
121
+ //#endregion
4
122
  //#region src/types.d.ts
5
-
6
123
  /**
7
124
  * Represents an auditable action with a type and payload.
8
125
  * Similar to PublishableMessage in @geekmidas/events.
@@ -124,6 +241,10 @@ interface MappedAudit<TAuditAction extends AuditableAction<string, unknown>, TOu
124
241
  * Extract the AuditableAction type from an Auditor.
125
242
  */
126
243
  type ExtractAuditorAction<T> = T extends Auditor<infer A> ? A : never;
244
+ /**
245
+ * Extract the AuditableAction type from an AuditStorage.
246
+ */
247
+ type ExtractStorageAuditAction<T> = T extends AuditStorage<infer A> ? A : AuditableAction<string, unknown>;
127
248
  //#endregion
128
249
  //#region src/Auditor.d.ts
129
250
  /**
@@ -256,5 +377,5 @@ interface Auditor<TAuditAction extends AuditableAction<string, unknown> = Audita
256
377
  getTransaction(): TTransaction | undefined;
257
378
  }
258
379
  //#endregion
259
- export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, MappedAudit };
260
- //# sourceMappingURL=Auditor-ii62d_pF.d.mts.map
380
+ export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditQueryOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit };
381
+ //# sourceMappingURL=Auditor-QYUMGJCH.d.cts.map
@@ -1,2 +1,2 @@
1
- import { Auditor } from "./Auditor-CZ8lkASv.cjs";
1
+ import { Auditor } from "./Auditor-QYUMGJCH.cjs";
2
2
  export { Auditor };
@@ -1,2 +1,2 @@
1
- import { Auditor } from "./Auditor-ii62d_pF.mjs";
1
+ import { Auditor } from "./Auditor-D3me-qKX.mjs";
2
2
  export { Auditor };
@@ -1,5 +1,4 @@
1
- import { AuditActor, AuditMetadata, AuditOptions, AuditRecord, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType } from "./Auditor-ii62d_pF.mjs";
2
- import { AuditStorage } from "./storage-BmA3SESr.mjs";
1
+ import { AuditActor, AuditMetadata, AuditOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType } from "./Auditor-QYUMGJCH.cjs";
3
2
 
4
3
  //#region src/DefaultAuditor.d.ts
5
4
 
@@ -56,4 +55,4 @@ declare class DefaultAuditor<TAuditAction extends AuditableAction<string, unknow
56
55
  }
57
56
  //#endregion
58
57
  export { DefaultAuditor, DefaultAuditorConfig };
59
- //# sourceMappingURL=DefaultAuditor-B-YEyT3q.d.mts.map
58
+ //# sourceMappingURL=DefaultAuditor-BTuMMiWh.d.cts.map
@@ -1,5 +1,4 @@
1
- import { AuditActor, AuditMetadata, AuditOptions, AuditRecord, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType } from "./Auditor-CZ8lkASv.cjs";
2
- import { AuditStorage } from "./storage-ndQzIcWK.cjs";
1
+ import { AuditActor, AuditMetadata, AuditOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType } from "./Auditor-D3me-qKX.mjs";
3
2
 
4
3
  //#region src/DefaultAuditor.d.ts
5
4
 
@@ -56,4 +55,4 @@ declare class DefaultAuditor<TAuditAction extends AuditableAction<string, unknow
56
55
  }
57
56
  //#endregion
58
57
  export { DefaultAuditor, DefaultAuditorConfig };
59
- //# sourceMappingURL=DefaultAuditor-RC-F_fTc.d.cts.map
58
+ //# sourceMappingURL=DefaultAuditor-C1FWrJg6.d.mts.map
@@ -1,4 +1,3 @@
1
- import "./Auditor-CZ8lkASv.cjs";
2
- import "./storage-ndQzIcWK.cjs";
3
- import { DefaultAuditor, DefaultAuditorConfig } from "./DefaultAuditor-RC-F_fTc.cjs";
1
+ import "./Auditor-QYUMGJCH.cjs";
2
+ import { DefaultAuditor, DefaultAuditorConfig } from "./DefaultAuditor-BTuMMiWh.cjs";
4
3
  export { DefaultAuditor, DefaultAuditorConfig };
@@ -1,4 +1,3 @@
1
- import "./Auditor-ii62d_pF.mjs";
2
- import "./storage-BmA3SESr.mjs";
3
- import { DefaultAuditor, DefaultAuditorConfig } from "./DefaultAuditor-B-YEyT3q.mjs";
1
+ import "./Auditor-D3me-qKX.mjs";
2
+ import { DefaultAuditor, DefaultAuditorConfig } from "./DefaultAuditor-C1FWrJg6.mjs";
4
3
  export { DefaultAuditor, DefaultAuditorConfig };
package/dist/index.d.cts CHANGED
@@ -1,4 +1,3 @@
1
- import { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, MappedAudit } from "./Auditor-CZ8lkASv.cjs";
2
- import { AuditQueryOptions, AuditStorage } from "./storage-ndQzIcWK.cjs";
3
- import { DefaultAuditor, DefaultAuditorConfig } from "./DefaultAuditor-RC-F_fTc.cjs";
4
- export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditQueryOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, DefaultAuditor, DefaultAuditorConfig, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, MappedAudit };
1
+ import { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditQueryOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit } from "./Auditor-QYUMGJCH.cjs";
2
+ import { DefaultAuditor, DefaultAuditorConfig } from "./DefaultAuditor-BTuMMiWh.cjs";
3
+ export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditQueryOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, DefaultAuditor, DefaultAuditorConfig, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,3 @@
1
- import { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, MappedAudit } from "./Auditor-ii62d_pF.mjs";
2
- import { AuditQueryOptions, AuditStorage } from "./storage-BmA3SESr.mjs";
3
- import { DefaultAuditor, DefaultAuditorConfig } from "./DefaultAuditor-B-YEyT3q.mjs";
4
- export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditQueryOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, DefaultAuditor, DefaultAuditorConfig, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, MappedAudit };
1
+ import { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditQueryOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit } from "./Auditor-D3me-qKX.mjs";
2
+ import { DefaultAuditor, DefaultAuditorConfig } from "./DefaultAuditor-C1FWrJg6.mjs";
3
+ export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditQueryOptions, AuditRecord, AuditStorage, AuditableAction, Auditor, DefaultAuditor, DefaultAuditorConfig, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit };
package/dist/kysely.d.cts CHANGED
@@ -1,5 +1,4 @@
1
- import { AuditRecord } from "./Auditor-CZ8lkASv.cjs";
2
- import { AuditQueryOptions, AuditStorage } from "./storage-ndQzIcWK.cjs";
1
+ import { AuditQueryOptions, AuditRecord, AuditStorage } from "./Auditor-QYUMGJCH.cjs";
3
2
  import { ControlledTransaction, IsolationLevel, Kysely, Transaction } from "kysely";
4
3
 
5
4
  //#region src/kysely.d.ts
package/dist/kysely.d.mts CHANGED
@@ -1,5 +1,4 @@
1
- import { AuditRecord } from "./Auditor-ii62d_pF.mjs";
2
- import { AuditQueryOptions, AuditStorage } from "./storage-BmA3SESr.mjs";
1
+ import { AuditQueryOptions, AuditRecord, AuditStorage } from "./Auditor-D3me-qKX.mjs";
3
2
  import { ControlledTransaction, IsolationLevel, Kysely, Transaction } from "kysely";
4
3
 
5
4
  //#region src/kysely.d.ts
@@ -1,3 +1,2 @@
1
- import "./Auditor-CZ8lkASv.cjs";
2
- import { AuditQueryOptions, AuditStorage } from "./storage-ndQzIcWK.cjs";
1
+ import { AuditQueryOptions, AuditStorage } from "./Auditor-QYUMGJCH.cjs";
3
2
  export { AuditQueryOptions, AuditStorage };
@@ -1,3 +1,2 @@
1
- import "./Auditor-ii62d_pF.mjs";
2
- import { AuditQueryOptions, AuditStorage } from "./storage-BmA3SESr.mjs";
1
+ import { AuditQueryOptions, AuditStorage } from "./Auditor-D3me-qKX.mjs";
3
2
  export { AuditQueryOptions, AuditStorage };
package/dist/types.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, MappedAudit } from "./Auditor-CZ8lkASv.cjs";
2
- export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, MappedAudit };
1
+ import { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit } from "./Auditor-QYUMGJCH.cjs";
2
+ export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit };
package/dist/types.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, MappedAudit } from "./Auditor-ii62d_pF.mjs";
2
- export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, MappedAudit };
1
+ import { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit } from "./Auditor-D3me-qKX.mjs";
2
+ export { AuditActor, AuditMetadata, AuditOperation, AuditOptions, AuditRecord, AuditableAction, ExtractAuditPayload, ExtractAuditType, ExtractAuditorAction, ExtractStorageAuditAction, MappedAudit };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekmidas/audit",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ export type {
9
9
  ExtractAuditPayload,
10
10
  ExtractAuditType,
11
11
  ExtractAuditorAction,
12
+ ExtractStorageAuditAction,
12
13
  MappedAudit,
13
14
  } from './types';
14
15
 
package/src/storage.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AuditRecord } from './types';
1
+ import type { AuditableAction, AuditRecord } from './types';
2
2
 
3
3
  /**
4
4
  * Options for querying audit records.
@@ -50,8 +50,19 @@ export interface AuditQueryOptions {
50
50
  * },
51
51
  * };
52
52
  * ```
53
+ *
54
+ * @template TAuditAction - Optional type parameter for type-safe audit actions.
55
+ * When provided, this type is preserved in the Service definition and can be
56
+ * extracted by EndpointBuilder to provide type inference for `.audit([...])`.
53
57
  */
54
- export interface AuditStorage {
58
+ export interface AuditStorage<
59
+ TAuditAction extends AuditableAction<string, unknown> = AuditableAction<
60
+ string,
61
+ unknown
62
+ >,
63
+ > {
64
+ /** @internal Type marker for extracting audit action type */
65
+ readonly __auditActionType?: TAuditAction;
55
66
  /**
56
67
  * Write audit records to storage.
57
68
  * Called by Auditor.flush() to persist collected audits.
package/src/types.ts CHANGED
@@ -143,5 +143,13 @@ export interface MappedAudit<
143
143
  */
144
144
  export type ExtractAuditorAction<T> = T extends Auditor<infer A> ? A : never;
145
145
 
146
+ /**
147
+ * Extract the AuditableAction type from an AuditStorage.
148
+ */
149
+ export type ExtractStorageAuditAction<T> = T extends AuditStorage<infer A>
150
+ ? A
151
+ : AuditableAction<string, unknown>;
152
+
146
153
  // Forward declaration for Auditor type extraction
147
154
  import type { Auditor } from './Auditor';
155
+ import type { AuditStorage } from './storage';
@@ -1,117 +0,0 @@
1
- import { AuditRecord } from "./Auditor-ii62d_pF.mjs";
2
-
3
- //#region src/storage.d.ts
4
-
5
- /**
6
- * Options for querying audit records.
7
- */
8
- interface AuditQueryOptions {
9
- /** Filter by audit type */
10
- type?: string | string[];
11
- /** Filter by entity ID */
12
- entityId?: string | Record<string, unknown>;
13
- /** Filter by table name */
14
- table?: string;
15
- /** Filter by actor ID */
16
- actorId?: string;
17
- /** Filter by date range (start) */
18
- from?: Date;
19
- /** Filter by date range (end) */
20
- to?: Date;
21
- /** Limit number of results */
22
- limit?: number;
23
- /** Offset for pagination */
24
- offset?: number;
25
- /** Sort order */
26
- orderBy?: 'timestamp' | 'type';
27
- /** Sort direction */
28
- orderDirection?: 'asc' | 'desc';
29
- }
30
- /**
31
- * Interface for audit storage backends.
32
- * Implement this to store audits in your preferred location.
33
- *
34
- * @example
35
- * ```typescript
36
- * // Same database storage (recommended for transactions)
37
- * const auditStorage: AuditStorage = {
38
- * async write(records, trx) {
39
- * const db = trx ?? getDatabase();
40
- * await db.insertInto('audit_logs').values(records).execute();
41
- * },
42
- * };
43
- *
44
- * // External audit service
45
- * const externalAuditStorage: AuditStorage = {
46
- * async write(records) {
47
- * await fetch('https://audit.example.com/api/audits', {
48
- * method: 'POST',
49
- * body: JSON.stringify({ records }),
50
- * });
51
- * },
52
- * };
53
- * ```
54
- */
55
- interface AuditStorage {
56
- /**
57
- * Write audit records to storage.
58
- * Called by Auditor.flush() to persist collected audits.
59
- *
60
- * @param records - The audit records to write
61
- * @param trx - Optional transaction context (for same-DB storage)
62
- */
63
- write(records: AuditRecord[], trx?: unknown): Promise<void>;
64
- /**
65
- * Optional: Query audit records for retrieval.
66
- * Implement this for audit log viewing/searching.
67
- *
68
- * @param options - Query filters and pagination
69
- * @returns Matching audit records
70
- */
71
- query?(options: AuditQueryOptions): Promise<AuditRecord[]>;
72
- /**
73
- * Optional: Count audit records matching filters.
74
- * Useful for pagination.
75
- *
76
- * @param options - Query filters (limit/offset ignored)
77
- * @returns Count of matching records
78
- */
79
- count?(options: Omit<AuditQueryOptions, 'limit' | 'offset'>): Promise<number>;
80
- /**
81
- * Optional: Get the database connection for transactional audit writes.
82
- * When implemented, the endpoint adaptor can automatically wrap handlers
83
- * in a transaction, ensuring audits are atomic with other database operations.
84
- *
85
- * @returns Database connection (e.g., Kysely instance)
86
- *
87
- * @example
88
- * ```typescript
89
- * class KyselyAuditStorage implements AuditStorage {
90
- * constructor(private db: Kysely<DB>) {}
91
- *
92
- * getDatabase() {
93
- * return this.db;
94
- * }
95
- * }
96
- * ```
97
- */
98
- getDatabase?(): unknown;
99
- /**
100
- * Optional: The service name of the database service used by this storage.
101
- * When set, endpoint adaptors will automatically use the audit transaction as `db`
102
- * in the handler context if the endpoint's database service has the same name.
103
- *
104
- * @example
105
- * ```typescript
106
- * const storage = new KyselyAuditStorage({
107
- * db,
108
- * tableName: 'audit_logs',
109
- * databaseServiceName: 'database', // Matches databaseService.serviceName
110
- * });
111
- * ```
112
- */
113
- databaseServiceName?: string;
114
- }
115
- //#endregion
116
- export { AuditQueryOptions, AuditStorage };
117
- //# sourceMappingURL=storage-BmA3SESr.d.mts.map
@@ -1,117 +0,0 @@
1
- import { AuditRecord } from "./Auditor-CZ8lkASv.cjs";
2
-
3
- //#region src/storage.d.ts
4
-
5
- /**
6
- * Options for querying audit records.
7
- */
8
- interface AuditQueryOptions {
9
- /** Filter by audit type */
10
- type?: string | string[];
11
- /** Filter by entity ID */
12
- entityId?: string | Record<string, unknown>;
13
- /** Filter by table name */
14
- table?: string;
15
- /** Filter by actor ID */
16
- actorId?: string;
17
- /** Filter by date range (start) */
18
- from?: Date;
19
- /** Filter by date range (end) */
20
- to?: Date;
21
- /** Limit number of results */
22
- limit?: number;
23
- /** Offset for pagination */
24
- offset?: number;
25
- /** Sort order */
26
- orderBy?: 'timestamp' | 'type';
27
- /** Sort direction */
28
- orderDirection?: 'asc' | 'desc';
29
- }
30
- /**
31
- * Interface for audit storage backends.
32
- * Implement this to store audits in your preferred location.
33
- *
34
- * @example
35
- * ```typescript
36
- * // Same database storage (recommended for transactions)
37
- * const auditStorage: AuditStorage = {
38
- * async write(records, trx) {
39
- * const db = trx ?? getDatabase();
40
- * await db.insertInto('audit_logs').values(records).execute();
41
- * },
42
- * };
43
- *
44
- * // External audit service
45
- * const externalAuditStorage: AuditStorage = {
46
- * async write(records) {
47
- * await fetch('https://audit.example.com/api/audits', {
48
- * method: 'POST',
49
- * body: JSON.stringify({ records }),
50
- * });
51
- * },
52
- * };
53
- * ```
54
- */
55
- interface AuditStorage {
56
- /**
57
- * Write audit records to storage.
58
- * Called by Auditor.flush() to persist collected audits.
59
- *
60
- * @param records - The audit records to write
61
- * @param trx - Optional transaction context (for same-DB storage)
62
- */
63
- write(records: AuditRecord[], trx?: unknown): Promise<void>;
64
- /**
65
- * Optional: Query audit records for retrieval.
66
- * Implement this for audit log viewing/searching.
67
- *
68
- * @param options - Query filters and pagination
69
- * @returns Matching audit records
70
- */
71
- query?(options: AuditQueryOptions): Promise<AuditRecord[]>;
72
- /**
73
- * Optional: Count audit records matching filters.
74
- * Useful for pagination.
75
- *
76
- * @param options - Query filters (limit/offset ignored)
77
- * @returns Count of matching records
78
- */
79
- count?(options: Omit<AuditQueryOptions, 'limit' | 'offset'>): Promise<number>;
80
- /**
81
- * Optional: Get the database connection for transactional audit writes.
82
- * When implemented, the endpoint adaptor can automatically wrap handlers
83
- * in a transaction, ensuring audits are atomic with other database operations.
84
- *
85
- * @returns Database connection (e.g., Kysely instance)
86
- *
87
- * @example
88
- * ```typescript
89
- * class KyselyAuditStorage implements AuditStorage {
90
- * constructor(private db: Kysely<DB>) {}
91
- *
92
- * getDatabase() {
93
- * return this.db;
94
- * }
95
- * }
96
- * ```
97
- */
98
- getDatabase?(): unknown;
99
- /**
100
- * Optional: The service name of the database service used by this storage.
101
- * When set, endpoint adaptors will automatically use the audit transaction as `db`
102
- * in the handler context if the endpoint's database service has the same name.
103
- *
104
- * @example
105
- * ```typescript
106
- * const storage = new KyselyAuditStorage({
107
- * db,
108
- * tableName: 'audit_logs',
109
- * databaseServiceName: 'database', // Matches databaseService.serviceName
110
- * });
111
- * ```
112
- */
113
- databaseServiceName?: string;
114
- }
115
- //#endregion
116
- export { AuditQueryOptions, AuditStorage };
117
- //# sourceMappingURL=storage-ndQzIcWK.d.cts.map