@cqrs-ddd/pipeline-audit 0.5.2 → 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/audit.behavior.d.ts +10 -13
- package/dist/audit.behavior.d.ts.map +1 -1
- package/dist/audit.behavior.js +40 -51
- package/dist/audit.behavior.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/sinks/postgres.sink.d.ts +2 -8
- package/dist/sinks/postgres.sink.d.ts.map +1 -1
- package/dist/sinks/postgres.sink.js +4 -12
- package/dist/sinks/postgres.sink.js.map +1 -1
- package/package.json +5 -5
package/dist/audit.behavior.d.ts
CHANGED
|
@@ -3,17 +3,9 @@ import type { AuditBehaviorOptions } from './interfaces/audit-options.interface.
|
|
|
3
3
|
import type { AuditRecord, AuditStartRecord } from './interfaces/audit-record.interface.js';
|
|
4
4
|
import type { AuditSink } from './interfaces/audit-sink.interface.js';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* The `context.items` entry that holds the produced {@link AuditRecord}.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* ```ts
|
|
10
|
-
* const record = context.items.get(AUDIT_RECORD_ITEM) as AuditRecord | undefined;
|
|
11
|
-
* ```
|
|
12
|
-
*/
|
|
13
|
-
export declare const AUDIT_RECORD_ITEM: unique symbol;
|
|
14
|
-
/**
|
|
15
|
-
* Typed token for {@link AUDIT_RECORD_ITEM}: the produced audit record. Reads and writes the same
|
|
16
|
-
* `context.items` entry through `getPipelineItem` / `requirePipelineItem`.
|
|
8
|
+
* Read it with `getPipelineItem` or `requirePipelineItem`.
|
|
17
9
|
*/
|
|
18
10
|
export declare const AUDIT_RECORD_ITEM_TOKEN: PipelineItemToken<AuditRecord>;
|
|
19
11
|
/**
|
|
@@ -81,8 +73,8 @@ export declare class AuditBehavior implements IPipelineBehavior, IPipelineBehavi
|
|
|
81
73
|
constructor(sink: AuditSink, defaults?: AuditBehaviorOptions, logger?: PipelineLogger);
|
|
82
74
|
handle(context: IPipelineContext, next: NextDelegate): Promise<unknown>;
|
|
83
75
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
76
|
+
* Builds the start record, stashes it on the context and forwards it to the
|
|
77
|
+
* sink's `begin`. Throws only when failing closed, before the handler runs.
|
|
86
78
|
*/
|
|
87
79
|
private begin;
|
|
88
80
|
/**
|
|
@@ -90,8 +82,13 @@ export declare class AuditBehavior implements IPipelineBehavior, IPipelineBehavi
|
|
|
90
82
|
* caller receives its own error, whatever happens to the audit record.
|
|
91
83
|
*/
|
|
92
84
|
private run;
|
|
93
|
-
/**
|
|
85
|
+
/** Builds the record, stashes it on the context and forwards it to the sink. */
|
|
94
86
|
private record;
|
|
87
|
+
/**
|
|
88
|
+
* One audit emission: a build or a write that fails is logged, and rethrown
|
|
89
|
+
* only when the handler fails closed. Nothing is written after a failed build.
|
|
90
|
+
*/
|
|
91
|
+
private emit;
|
|
95
92
|
/**
|
|
96
93
|
* Rejects a non-function factory option before request execution when
|
|
97
94
|
* `failOpen` is false, and logs it otherwise.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.behavior.d.ts","sourceRoot":"","sources":["../src/audit.behavior.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,gCAAgC,EACrC,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,0BAA0B,EAG1B,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEpB,MAAM,oBAAoB,CAAC;AAM5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EACV,WAAW,EAEX,gBAAgB,EACjB,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEtE
|
|
1
|
+
{"version":3,"file":"audit.behavior.d.ts","sourceRoot":"","sources":["../src/audit.behavior.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,gCAAgC,EACrC,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,0BAA0B,EAG1B,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEpB,MAAM,oBAAoB,CAAC;AAM5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EACV,WAAW,EAEX,gBAAgB,EACjB,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,iBAAiB,CAAC,WAAW,CACb,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,EAAE,iBAAiB,CAAC,gBAAgB,CACb,CAAC;AAUlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,qBAAa,aACX,YACE,iBAAiB,EACjB,gCAAgC,CAAC,oBAAoB,CAAC;IAyBtD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAvBvB,MAAM,CAAC,QAAQ,CAAC,CAAC,0BAA0B,CAAC,EAAE,yBAAyB,CAiBrE;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAEhD,YACmB,IAAI,EAAE,SAAS,EAChC,QAAQ,CAAC,EAAE,oBAAoB,EAC/B,MAAM,CAAC,EAAE,cAAc,EAUxB;IAEK,MAAM,CACV,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,OAAO,CAAC,CA2BlB;IAED;;;OAGG;IACH,OAAO,CAAC,KAAK;IAYb;;;OAGG;YACW,GAAG;IAoCjB,gFAAgF;IAChF,OAAO,CAAC,MAAM;IAgBd;;;OAGG;YACW,IAAI;IAuClB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAQzB,kEAAkE;IAClE,OAAO,CAAC,aAAa;IAarB,4DAA4D;IAC5D,OAAO,CAAC,QAAQ;IAQhB,wEAAwE;IACxE,uBAAuB,CACrB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,oBAAoB,CAGtB;CACF"}
|
package/dist/audit.behavior.js
CHANGED
|
@@ -3,19 +3,11 @@ import { createPipelineItem, PIPELINE_BEHAVIOR_CONTRACT, setPipelineItem, } from
|
|
|
3
3
|
import { uuidv7 } from '@cqrs-ddd/uuidv7';
|
|
4
4
|
import { buildAuditRecord, buildAuditStartRecord, } from './helpers/build-record.js';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* The `context.items` entry that holds the produced {@link AuditRecord}.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* ```ts
|
|
10
|
-
* const record = context.items.get(AUDIT_RECORD_ITEM) as AuditRecord | undefined;
|
|
11
|
-
* ```
|
|
12
|
-
*/
|
|
13
|
-
export const AUDIT_RECORD_ITEM = Symbol('AUDIT_RECORD_ITEM');
|
|
14
|
-
/**
|
|
15
|
-
* Typed token for {@link AUDIT_RECORD_ITEM}: the produced audit record. Reads and writes the same
|
|
16
|
-
* `context.items` entry through `getPipelineItem` / `requirePipelineItem`.
|
|
8
|
+
* Read it with `getPipelineItem` or `requirePipelineItem`.
|
|
17
9
|
*/
|
|
18
|
-
export const AUDIT_RECORD_ITEM_TOKEN = createPipelineItem('AUDIT_RECORD_ITEM'
|
|
10
|
+
export const AUDIT_RECORD_ITEM_TOKEN = createPipelineItem('AUDIT_RECORD_ITEM');
|
|
19
11
|
/**
|
|
20
12
|
* Typed token for the pending {@link AuditStartRecord}, set before the handler
|
|
21
13
|
* runs when a start record is written. A step inside the handler can read it,
|
|
@@ -123,31 +115,16 @@ export class AuditBehavior {
|
|
|
123
115
|
return this.run(next, audited);
|
|
124
116
|
}
|
|
125
117
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
118
|
+
* Builds the start record, stashes it on the context and forwards it to the
|
|
119
|
+
* sink's `begin`. Throws only when failing closed, before the handler runs.
|
|
128
120
|
*/
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const message = `Failed to build audit start record for ${input.context.requestName}: ` +
|
|
137
|
-
`${buildError instanceof Error ? buildError.message : buildError}`;
|
|
138
|
-
this.reportFailure(message, failOpen, buildError);
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
setPipelineItem(input.context, AUDIT_START_RECORD_ITEM_TOKEN, record);
|
|
142
|
-
try {
|
|
143
|
-
await begin(record);
|
|
144
|
-
}
|
|
145
|
-
catch (sinkError) {
|
|
146
|
-
const message = `Failed to write audit start record for ${record.requestName} ` +
|
|
147
|
-
`(correlationId: ${record.correlationId}): ` +
|
|
148
|
-
`${sinkError instanceof Error ? sinkError.message : sinkError}`;
|
|
149
|
-
this.reportFailure(message, failOpen, sinkError);
|
|
150
|
-
}
|
|
121
|
+
begin(begin, input) {
|
|
122
|
+
return this.emit(input, {
|
|
123
|
+
label: 'audit start record',
|
|
124
|
+
build: () => buildAuditStartRecord(input),
|
|
125
|
+
token: AUDIT_START_RECORD_ITEM_TOKEN,
|
|
126
|
+
write: begin,
|
|
127
|
+
});
|
|
151
128
|
}
|
|
152
129
|
/**
|
|
153
130
|
* Times the handler and records its outcome. When the handler fails, the
|
|
@@ -169,7 +146,7 @@ export class AuditBehavior {
|
|
|
169
146
|
});
|
|
170
147
|
}
|
|
171
148
|
catch (recordError) {
|
|
172
|
-
this.diagnose('error', `Audit recording also failed after request error: ${recordError
|
|
149
|
+
this.diagnose('error', `Audit recording also failed after request error: ${errorMessage(recordError)}`);
|
|
173
150
|
}
|
|
174
151
|
throw error;
|
|
175
152
|
}
|
|
@@ -181,28 +158,37 @@ export class AuditBehavior {
|
|
|
181
158
|
});
|
|
182
159
|
return response;
|
|
183
160
|
}
|
|
184
|
-
/**
|
|
185
|
-
|
|
186
|
-
|
|
161
|
+
/** Builds the record, stashes it on the context and forwards it to the sink. */
|
|
162
|
+
record(input) {
|
|
163
|
+
return this.emit(input, {
|
|
164
|
+
label: 'audit record',
|
|
165
|
+
build: () => buildAuditRecord(input),
|
|
166
|
+
token: AUDIT_RECORD_ITEM_TOKEN,
|
|
167
|
+
write: (record) => this.sink.write(record),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* One audit emission: a build or a write that fails is logged, and rethrown
|
|
172
|
+
* only when the handler fails closed. Nothing is written after a failed build.
|
|
173
|
+
*/
|
|
174
|
+
async emit({ context, options }, emission) {
|
|
175
|
+
const { label, build, token, write } = emission;
|
|
176
|
+
const failOpen = options.failOpen ?? true;
|
|
187
177
|
let record;
|
|
188
178
|
try {
|
|
189
|
-
record =
|
|
179
|
+
record = build();
|
|
190
180
|
}
|
|
191
|
-
catch (
|
|
192
|
-
|
|
193
|
-
`${buildError instanceof Error ? buildError.message : buildError}`;
|
|
194
|
-
this.reportFailure(message, failOpen, buildError);
|
|
181
|
+
catch (error) {
|
|
182
|
+
this.reportFailure(`Failed to build ${label} for ${context.requestName}: ${errorMessage(error)}`, failOpen, error);
|
|
195
183
|
return;
|
|
196
184
|
}
|
|
197
|
-
setPipelineItem(
|
|
185
|
+
setPipelineItem(context, token, record);
|
|
198
186
|
try {
|
|
199
|
-
await
|
|
187
|
+
await write(record);
|
|
200
188
|
}
|
|
201
|
-
catch (
|
|
202
|
-
|
|
203
|
-
`(correlationId: ${record.correlationId}):
|
|
204
|
-
`${sinkError instanceof Error ? sinkError.message : sinkError}`;
|
|
205
|
-
this.reportFailure(message, failOpen, sinkError);
|
|
189
|
+
catch (error) {
|
|
190
|
+
this.reportFailure(`Failed to write ${label} for ${record.requestName} ` +
|
|
191
|
+
`(correlationId: ${record.correlationId}): ${errorMessage(error)}`, failOpen, error);
|
|
206
192
|
}
|
|
207
193
|
}
|
|
208
194
|
/**
|
|
@@ -250,6 +236,9 @@ const FACTORY_OPTIONS = [
|
|
|
250
236
|
['metadata', 'metadata factory'],
|
|
251
237
|
['redact', 'redactor'],
|
|
252
238
|
];
|
|
239
|
+
function errorMessage(error) {
|
|
240
|
+
return error instanceof Error ? error.message : error;
|
|
241
|
+
}
|
|
253
242
|
function findInvalidFactory(options) {
|
|
254
243
|
for (const [option, label] of FACTORY_OPTIONS) {
|
|
255
244
|
const value = options[option];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.behavior.js","sourceRoot":"","sources":["../src/audit.behavior.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EACL,kBAAkB,EAMlB,0BAA0B,EAK1B,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AASnC
|
|
1
|
+
{"version":3,"file":"audit.behavior.js","sourceRoot":"","sources":["../src/audit.behavior.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { AUDIT_RECORD_ITEM_TOKEN, AUDIT_START_RECORD_ITEM_TOKEN, AuditBehavior, } from './audit.behavior.js';
|
|
2
2
|
export { AUDIT_OUTCOMES, AUDIT_REQUEST_KINDS, AUDIT_SEVERITY, } from './constants/tokens.js';
|
|
3
3
|
export { type AuditIntentOptions, audit, } from './helpers/audit.intent.js';
|
|
4
4
|
export type { BuildAuditRecordInput, BuildAuditStartRecordInput, } from './helpers/build-record.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,GACN,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,GACd,MAAM,yCAAyC,CAAC;AACjD,YAAY,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GACjB,MAAM,wCAAwC,CAAC;AAChD,YAAY,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EACL,KAAK,eAAe,EACpB,YAAY,EACZ,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,GAC3B,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
-
export {
|
|
2
|
+
export { AUDIT_RECORD_ITEM_TOKEN, AUDIT_START_RECORD_ITEM_TOKEN, AuditBehavior, } from './audit.behavior.js';
|
|
3
3
|
export { AUDIT_OUTCOMES, AUDIT_REQUEST_KINDS, AUDIT_SEVERITY, } from './constants/tokens.js';
|
|
4
4
|
export { audit, } from './helpers/audit.intent.js';
|
|
5
5
|
export { buildAuditRecord, buildAuditStartRecord, } from './helpers/build-record.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,GACN,MAAM,2BAA2B,CAAC;AAKnC,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAiB7B,OAAO,EAEL,YAAY,GAEb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,GAGlB,MAAM,0BAA0B,CAAC"}
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
+
import { type PostgresQueryableLike } from '@cqrs-ddd/pipeline';
|
|
1
2
|
import type { AuditRecord, AuditStartRecord } from '../interfaces/audit-record.interface.js';
|
|
2
3
|
import type { AuditSink } from '../interfaces/audit-sink.interface.js';
|
|
3
|
-
|
|
4
|
-
* Minimal structural shape of a `pg` `Pool` / `Client`. Declared locally so this
|
|
5
|
-
* package does not hard-depend on `pg` — a real `Pool` or `Client` satisfies it.
|
|
6
|
-
* Add it in your app: `pnpm add pg`.
|
|
7
|
-
*/
|
|
8
|
-
export interface PostgresQueryableLike {
|
|
9
|
-
query(text: string, values?: unknown[]): Promise<unknown>;
|
|
10
|
-
}
|
|
4
|
+
export type { PostgresQueryableLike };
|
|
11
5
|
/** Options for {@link PostgresAuditSink}. */
|
|
12
6
|
export interface PostgresAuditSinkOptions {
|
|
13
7
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.sink.d.ts","sourceRoot":"","sources":["../../src/sinks/postgres.sink.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postgres.sink.d.ts","sourceRoot":"","sources":["../../src/sinks/postgres.sink.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,qBAAqB,EAE3B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAEvE,YAAY,EAAE,qBAAqB,EAAE,CAAC;AAEtC,6CAA6C;AAC7C,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,SAAc,GAAG,MAAM,CAoB/D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,iBAAkB,YAAW,SAAS;IAK/C,OAAO,CAAC,QAAQ,CAAC,EAAE;IAJrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAElC,YACmB,EAAE,EAAE,qBAAqB,EAC1C,OAAO,GAAE,wBAA6B,EAmBvC;IAED,4DAA4D;IACtD,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnD;IAED;;;OAGG;IACG,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9C;IAED,OAAO,CAAC,MAAM;CA6Bf"}
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
-
import { toPostgresJson } from '@cqrs-ddd/pipeline';
|
|
2
|
+
import { assertSafeTable, toPostgresJson, } from '@cqrs-ddd/pipeline';
|
|
3
3
|
import { stringifyAuditValue } from '../helpers/json.js';
|
|
4
|
-
|
|
5
|
-
const SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?$/;
|
|
6
|
-
function assertSafeTable(table) {
|
|
7
|
-
if (!SAFE_IDENTIFIER.test(table)) {
|
|
8
|
-
throw new Error(`Invalid audit table name "${table}". ` +
|
|
9
|
-
'Use an unquoted identifier like "audit_log" or "schema.audit_log".');
|
|
10
|
-
}
|
|
11
|
-
return table;
|
|
12
|
-
}
|
|
4
|
+
const safeTable = (table) => assertSafeTable(table, 'audit', 'audit_log');
|
|
13
5
|
/**
|
|
14
6
|
* SQL to create the audit table. Run once in a migration.
|
|
15
7
|
*
|
|
@@ -25,7 +17,7 @@ function assertSafeTable(table) {
|
|
|
25
17
|
* @param table - Table name (validated). Default `'audit_log'`.
|
|
26
18
|
*/
|
|
27
19
|
export function createAuditTableSql(table = 'audit_log') {
|
|
28
|
-
const name =
|
|
20
|
+
const name = safeTable(table);
|
|
29
21
|
return `CREATE TABLE IF NOT EXISTS ${name} (
|
|
30
22
|
id UUID PRIMARY KEY,
|
|
31
23
|
correlation_id TEXT NOT NULL,
|
|
@@ -72,7 +64,7 @@ export class PostgresAuditSink {
|
|
|
72
64
|
writeSql;
|
|
73
65
|
constructor(db, options = {}) {
|
|
74
66
|
this.db = db;
|
|
75
|
-
const table =
|
|
67
|
+
const table = safeTable(options.table ?? 'audit_log');
|
|
76
68
|
const columns = `(id, correlation_id, action, severity, outcome, actor, request_kind,
|
|
77
69
|
request_name, handler_name, payload, response, error, duration_ms,
|
|
78
70
|
metadata, occurred_at, completed_at)`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.sink.js","sourceRoot":"","sources":["../../src/sinks/postgres.sink.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,
|
|
1
|
+
{"version":3,"file":"postgres.sink.js","sourceRoot":"","sources":["../../src/sinks/postgres.sink.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cqrs-ddd/pipeline-audit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Audit records for @cqrs-ddd/pipeline: who did what, in which tenant, with redacted payloads, to a log or PostgreSQL sink",
|
|
5
5
|
"author": "Aristotelis",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -46,16 +46,16 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@cqrs-ddd/pipeline": "^0.
|
|
49
|
+
"@cqrs-ddd/pipeline": "^0.6.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@cqrs-ddd/pipeline": "0.
|
|
52
|
+
"@cqrs-ddd/pipeline": "0.6.0",
|
|
53
53
|
"@vitest/coverage-v8": "^5.0.5",
|
|
54
54
|
"vitest": "^5.0.5"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@cqrs-ddd/safe-stringify": "^0.
|
|
58
|
-
"@cqrs-ddd/uuidv7": "^0.
|
|
57
|
+
"@cqrs-ddd/safe-stringify": "^0.6.0",
|
|
58
|
+
"@cqrs-ddd/uuidv7": "^0.6.0"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"build": "tsc -p tsconfig.build.json",
|