@voltro/plugin-audit 0.84.0 → 0.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,29 +1,29 @@
1
1
  import { audit as e } from "./mixin.js";
2
- import { Effect as t } from "effect";
3
- import { anonymousSubject as n, definePlugin as r, pluginInstanceName as i, rawImpersonationMark as a } from "@voltro/protocol";
4
- import { createLogger as o } from "@voltro/logger";
5
- import { and as s, eq as c, id as l, integer as u, json as d, registerRetention as ee, resolveActorSnapshot as f, retentionTtlMsFromEnv as p, scopeKeyOf as m, table as h, text as g, timestamp as _ } from "@voltro/database";
6
- import { createHash as v, createHmac as y, randomBytes as b } from "node:crypto";
2
+ import { Cause as t, Effect as n } from "effect";
3
+ import { anonymousSubject as r, definePlugin as i, pluginInstanceName as a, rawImpersonationMark as o } from "@voltro/protocol";
4
+ import { createLogger as s } from "@voltro/logger";
5
+ import { and as c, column as l, eq as u, gt as d, id as f, integer as p, isNotNull as m, isNull as h, json as g, lte as _, or as v, registerRetention as ee, resolveActorSnapshot as y, retentionTtlMsFromEnv as b, scopeKeyOf as x, table as S, text as C, timestamp as w } from "@voltro/database";
6
+ import { createHash as T, createHmac as E, randomBytes as D } from "node:crypto";
7
7
  //#region src/redactionShape.ts
8
- var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e === 0 || t <= 0 || e >= t ? `string(${e})` : `string(<${t})`, E = (e, t) => e.length <= C && w.test(e) ? e : `<key:${T(e.length, t)}>`, D = (e, t = 0, n = 16) => {
8
+ var O = 4, k = 32, A = 64, te = /^[A-Za-z_$][A-Za-z0-9_$]*$/, j = (e, t) => e === 0 || t <= 0 || e >= t ? `string(${e})` : `string(<${t})`, M = (e, t) => e.length <= A && te.test(e) ? e : `<key:${j(e.length, t)}>`, N = (e, t = 0, n = 16) => {
9
9
  if (e === null) return "null";
10
10
  if (e === void 0) return "undefined";
11
11
  let r = typeof e;
12
- if (r === "string") return T(e.length, n);
12
+ if (r === "string") return j(e.length, n);
13
13
  if (r === "number" || r === "boolean" || r === "bigint" || r === "symbol" || r === "function") return r;
14
14
  if (e instanceof Date) return "date";
15
- if (t >= x) return Array.isArray(e) ? "array(…)" : "object(…)";
15
+ if (t >= O) return Array.isArray(e) ? "array(…)" : "object(…)";
16
16
  if (Array.isArray(e)) {
17
- let r = e.slice(0, S).map((e) => D(e, t + 1, n));
18
- return e.length > S ? [...r, `…${e.length - S} more`] : r;
17
+ let r = e.slice(0, k).map((e) => N(e, t + 1, n));
18
+ return e.length > k ? [...r, `…${e.length - k} more`] : r;
19
19
  }
20
20
  if (r === "object") {
21
21
  let r = Object.entries(e), i = {};
22
- for (let [e, a] of r.slice(0, S)) i[E(e, n)] = D(a, t + 1, n);
23
- return r.length > S && (i["…"] = `${r.length - S} more key(s)`), i;
22
+ for (let [e, a] of r.slice(0, k)) i[M(e, n)] = N(a, t + 1, n);
23
+ return r.length > k && (i["…"] = `${r.length - k} more key(s)`), i;
24
24
  }
25
25
  return r;
26
- }, O = (e, t = 16) => ({ __redacted: D(e, 0, t) }), k = "_voltro_audit_log", A = [
26
+ }, P = (e, t = 16) => ({ __redacted: N(e, 0, t) }), F = "_voltro_audit_log", I = [
27
27
  "tag",
28
28
  "at",
29
29
  "subjectId",
@@ -38,26 +38,26 @@ var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e ===
38
38
  "input",
39
39
  "outcome",
40
40
  "errorTag"
41
- ], j = (e) => {
41
+ ], L = (e) => {
42
42
  if (e == null) return "null";
43
43
  if (e instanceof Date) return JSON.stringify(e.toISOString());
44
44
  let t = typeof e;
45
- return t === "number" || t === "boolean" || t === "string" ? JSON.stringify(e) : t === "bigint" ? JSON.stringify(String(e)) : Array.isArray(e) ? `[${e.map(j).join(",")}]` : t === "object" ? `{${Object.entries(e).filter(([, e]) => e !== void 0).sort(([e], [t]) => e < t ? -1 : +(e > t)).map(([e, t]) => `${JSON.stringify(e)}:${j(t)}`).join(",")}}` : JSON.stringify(String(e));
46
- }, M = (e) => e instanceof Date ? e.toISOString() : e, N = (e) => j(Object.fromEntries(A.map((t) => [t, M(e[t] ?? null)]))), P = (e) => {
45
+ return t === "number" || t === "boolean" || t === "string" ? JSON.stringify(e) : t === "bigint" ? JSON.stringify(String(e)) : Array.isArray(e) ? `[${e.map(L).join(",")}]` : t === "object" ? `{${Object.entries(e).filter(([, e]) => e !== void 0).sort(([e], [t]) => e < t ? -1 : +(e > t)).map(([e, t]) => `${JSON.stringify(e)}:${L(t)}`).join(",")}}` : JSON.stringify(String(e));
46
+ }, ne = (e) => e instanceof Date ? e.toISOString() : e, re = (e) => L(Object.fromEntries(I.map((t) => [t, ne(e[t] ?? null)]))), ie = (e) => {
47
47
  let t = process.env.VOLTRO_AUDIT_CHAIN_SECRET;
48
- return t ? y("sha256", t).update(e, "utf8").digest("hex") : v("sha256").update(e, "utf8").digest("hex");
49
- }, F = (e, t) => P(JSON.stringify([
48
+ return t ? E("sha256", t).update(e, "utf8").digest("hex") : T("sha256").update(e, "utf8").digest("hex");
49
+ }, R = (e, t) => ie(JSON.stringify([
50
50
  t.chainId,
51
51
  t.seq,
52
52
  t.prevHash,
53
- N(e)
54
- ])), I = (e = b(12).toString("base64url")) => {
53
+ re(e)
54
+ ])), z = (e = D(12).toString("base64url")) => {
55
55
  let t = 0, n = null;
56
56
  return {
57
57
  chainId: e,
58
58
  link: (r) => {
59
59
  t += 1;
60
- let i = F(r, {
60
+ let i = R(r, {
61
61
  chainId: e,
62
62
  seq: t,
63
63
  prevHash: n
@@ -71,92 +71,144 @@ var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e ===
71
71
  return n = i, a;
72
72
  }
73
73
  };
74
- }, L = async (e, t = {}) => {
75
- let n = t.chainId === void 0 ? void 0 : c("chainId", t.chainId), r = await e.query({
76
- table: k,
77
- ...n ? { predicate: n } : {},
78
- order: [{
74
+ };
75
+ async function* B(e, t) {
76
+ let n = t.chainId === void 0 ? void 0 : u("chainId", t.chainId), r = (e, t, n) => ({
77
+ table: F,
78
+ predicate: e,
79
+ order: n,
80
+ take: t,
81
+ skip: void 0,
82
+ projection: void 0
83
+ });
84
+ if (t.limit !== void 0) {
85
+ yield* await e.query(r(n, t.limit, [{
79
86
  column: "chainId",
80
87
  direction: "asc"
81
88
  }, {
82
89
  column: "seq",
83
90
  direction: "asc"
84
- }],
85
- ...t.limit === void 0 ? {} : { take: t.limit }
86
- }), i = [], a = [], o = 0, s = 0, l = null, u = () => {
87
- l &&= (a.push({
88
- chainId: l.chainId,
89
- from: l.from,
90
- to: l.last,
91
- tip: l.tip,
92
- prunedPrefix: l.from > 1
91
+ }]));
92
+ return;
93
+ }
94
+ let i = [...await e.query({
95
+ ...r(n, void 0, [{
96
+ column: "chainId",
97
+ direction: "asc"
98
+ }]),
99
+ groupBy: ["chainId"],
100
+ aggregations: [
101
+ l("chainId"),
102
+ {
103
+ op: "max",
104
+ column: "seq",
105
+ alias: "lastSeq"
106
+ },
107
+ {
108
+ op: "max",
109
+ column: "id",
110
+ alias: "lastId"
111
+ }
112
+ ]
113
+ })].sort((e, t) => String(e.chainId) < String(t.chainId) ? -1 : +(String(e.chainId) > String(t.chainId)));
114
+ for (let t of i) {
115
+ let n = t.chainId, i = n == null ? h("chainId") : u("chainId", n), a = n == null ? [!1] : [!1, !0];
116
+ for (let o of a) {
117
+ if (o && t.lastSeq == null) continue;
118
+ let a = [i, _("id", t.lastId)];
119
+ n != null && a.push(o ? c(m("seq"), _("seq", t.lastSeq)) : h("seq"));
120
+ let s;
121
+ for (;;) {
122
+ let t = s === void 0 ? void 0 : o ? v(d("seq", s.seq), c(u("seq", s.seq), d("id", s.id))) : d("id", s.id), n = await e.query(r(c(...a, ...t ? [t] : []), 1e3, [...o ? [{
123
+ column: "seq",
124
+ direction: "asc"
125
+ }] : [], {
126
+ column: "id",
127
+ direction: "asc"
128
+ }]));
129
+ if (yield* n, n.length < 1e3) break;
130
+ let i = n[n.length - 1];
131
+ if (i.id === void 0 || i.id === s?.id) throw Error("audit verification cursor did not advance");
132
+ s = i;
133
+ }
134
+ }
135
+ }
136
+ }
137
+ var V = async (e, t = {}) => {
138
+ let n = [], r = [], i = 0, a = 0, o = null, s = () => {
139
+ o &&= (r.push({
140
+ chainId: o.chainId,
141
+ from: o.from,
142
+ to: o.last,
143
+ tip: o.tip,
144
+ prunedPrefix: o.from > 1
93
145
  }), null);
94
146
  };
95
- for (let e of r) {
96
- let t = e.chainId, n = e.hash, r = e.seq;
97
- if (typeof t != "string" || typeof n != "string" || r == null) {
98
- o += 1;
147
+ for await (let r of B(e, t)) {
148
+ let e = r.chainId, t = r.hash, c = r.seq;
149
+ if (typeof e != "string" || typeof t != "string" || c == null) {
150
+ i += 1;
99
151
  continue;
100
152
  }
101
- let a = Number(r), c = typeof e.prevHash == "string" ? e.prevHash : null, d = typeof e.id == "string" ? e.id : void 0;
102
- s += 1, !l || l.chainId !== t ? (u(), l = {
103
- chainId: t,
104
- from: a,
105
- last: a,
106
- tip: n
107
- }) : (a === l.last + 1 ? c !== l.tip && i.push({
153
+ let l = Number(c), u = typeof r.prevHash == "string" ? r.prevHash : null, d = typeof r.id == "string" ? r.id : void 0;
154
+ a += 1, !o || o.chainId !== e ? (s(), o = {
155
+ chainId: e,
156
+ from: l,
157
+ last: l,
158
+ tip: t
159
+ }) : (l === o.last + 1 ? u !== o.tip && n.push({
108
160
  kind: "broken-link",
109
- chainId: t,
110
- seq: a,
161
+ chainId: e,
162
+ seq: l,
111
163
  ...d ? { rowId: d } : {},
112
- detail: `prevHash does not match the hash of seq ${l.last}`
113
- }) : i.push({
164
+ detail: `prevHash does not match the hash of seq ${o.last}`
165
+ }) : n.push({
114
166
  kind: "gap",
115
- chainId: t,
116
- seq: l.last + 1,
117
- detail: `chain jumps from seq ${l.last} to ${a} — ${a - l.last - 1} row(s) missing`
118
- }), l.last = a, l.tip = n), F(e, {
119
- chainId: t,
120
- seq: a,
121
- prevHash: c
122
- }) !== n && i.push({
167
+ chainId: e,
168
+ seq: o.last + 1,
169
+ detail: `chain jumps from seq ${o.last} to ${l} — ${l - o.last - 1} row(s) missing`
170
+ }), o.last = l, o.tip = t), R(r, {
171
+ chainId: e,
172
+ seq: l,
173
+ prevHash: u
174
+ }) !== t && n.push({
123
175
  kind: "tampered",
124
- chainId: t,
125
- seq: a,
176
+ chainId: e,
177
+ seq: l,
126
178
  ...d ? { rowId: d } : {},
127
179
  detail: "the row content does not hash to its stored hash — a column was altered"
128
180
  });
129
181
  }
130
- return u(), {
131
- ok: i.length === 0,
132
- rowsChecked: s,
133
- unchainedRows: o,
134
- chains: a,
135
- issues: i,
182
+ return s(), {
183
+ ok: n.length === 0,
184
+ rowsChecked: a,
185
+ unchainedRows: i,
186
+ chains: r,
187
+ issues: n,
136
188
  keyed: !!process.env.VOLTRO_AUDIT_CHAIN_SECRET
137
189
  };
138
- }, R = h(k, {
139
- id: l({ prefix: "audit" }),
140
- tag: g(),
141
- at: _(),
142
- subjectId: g().nullable(),
143
- tenantId: g().nullable(),
144
- traceId: g(),
145
- status: g(),
146
- durationMs: g(),
147
- subject: d(),
148
- actor: d().nullable(),
149
- scope: d().nullable(),
150
- scopeKey: g().nullable(),
151
- metadata: d().nullable(),
152
- impersonation: d().nullable(),
153
- input: d(),
154
- outcome: d(),
155
- errorTag: g().nullable(),
156
- chainId: g().nullable(),
157
- seq: u().nullable(),
158
- prevHash: g().nullable(),
159
- hash: g().nullable()
190
+ }, H = S(F, {
191
+ id: f({ prefix: "audit" }),
192
+ tag: C(),
193
+ at: w(),
194
+ subjectId: C().nullable(),
195
+ tenantId: C().nullable(),
196
+ traceId: C(),
197
+ status: C(),
198
+ durationMs: C(),
199
+ subject: g(),
200
+ actor: g().nullable(),
201
+ scope: g().nullable(),
202
+ scopeKey: C().nullable(),
203
+ metadata: g().nullable(),
204
+ impersonation: g().nullable(),
205
+ input: g(),
206
+ outcome: g(),
207
+ errorTag: C().nullable(),
208
+ chainId: C().nullable(),
209
+ seq: p().nullable(),
210
+ prevHash: C().nullable(),
211
+ hash: C().nullable()
160
212
  }).index("byAuditTag", ["tag"]).index("byAuditTrace", ["traceId"]).index("byAuditSubjectStatus", [
161
213
  "subjectId",
162
214
  "status",
@@ -165,7 +217,7 @@ var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e ===
165
217
  "tenantId",
166
218
  "status",
167
219
  "at"
168
- ]).index("byAuditScope", ["scopeKey", "at"]).index("byAuditChain", ["chainId", "seq"]), z = [R], B = (e) => ({
220
+ ]).index("byAuditScope", ["scopeKey", "at"]).index("byAuditChain", ["chainId", "seq"]), U = [H], W = (e) => ({
169
221
  tag: e.tag,
170
222
  at: new Date(e.ts),
171
223
  subjectId: e.subject.id ?? null,
@@ -176,61 +228,61 @@ var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e ===
176
228
  subject: e.subject,
177
229
  actor: e.actor ?? null,
178
230
  scope: e.scope ?? null,
179
- scopeKey: m(e.scope),
231
+ scopeKey: x(e.scope),
180
232
  metadata: e.metadata ?? null,
181
233
  impersonation: e.impersonation ?? null,
182
234
  input: e.input,
183
235
  outcome: e.outcome,
184
- errorTag: e.outcome.kind === "error" ? V(e.outcome.error) : null
185
- }), V = (e) => {
236
+ errorTag: e.outcome.kind === "error" ? G(e.outcome.error) : null
237
+ }), G = (e) => {
186
238
  if (typeof e != "object" || !e) return null;
187
239
  let t = e._tag;
188
240
  return typeof t == "string" && t !== "" ? t : null;
189
- }, H = async (e, t) => e.query({
190
- table: k,
191
- predicate: c("traceId", t),
241
+ }, K = async (e, t) => e.query({
242
+ table: F,
243
+ predicate: u("traceId", t),
192
244
  order: [{
193
245
  column: "at",
194
246
  direction: "asc"
195
247
  }]
196
- }), U = async (e, t, n = {}) => {
197
- let r = m(t);
248
+ }), q = async (e, t, n = {}) => {
249
+ let r = x(t);
198
250
  if (r === null) return [];
199
- let i = c("scopeKey", r);
251
+ let i = u("scopeKey", r);
200
252
  return e.query({
201
- table: k,
202
- predicate: n.status === void 0 ? i : s(i, c("status", n.status)),
253
+ table: F,
254
+ predicate: n.status === void 0 ? i : c(i, u("status", n.status)),
203
255
  order: [{
204
256
  column: "at",
205
257
  direction: "desc"
206
258
  }],
207
259
  take: n.limit ?? 100
208
260
  });
209
- }, W = async (e, t, n = {}) => {
210
- let r = c("subjectId", t);
261
+ }, J = async (e, t, n = {}) => {
262
+ let r = u("subjectId", t);
211
263
  return e.query({
212
- table: k,
213
- predicate: n.status === void 0 ? r : s(r, c("status", n.status)),
264
+ table: F,
265
+ predicate: n.status === void 0 ? r : c(r, u("status", n.status)),
214
266
  order: [{
215
267
  column: "at",
216
268
  direction: "desc"
217
269
  }],
218
270
  take: n.limit ?? 100
219
271
  });
220
- }, G = (e) => {
221
- let t = I();
272
+ }, Y = (e) => {
273
+ let t = z();
222
274
  return async (n) => {
223
275
  let r = n.actor !== void 0 || typeof e.query != "function" ? n : {
224
276
  ...n,
225
- actor: await f(e, n.subject.id ?? null, n.subject.type)
277
+ actor: await y(e, n.subject.id ?? null, n.subject.type)
226
278
  };
227
- await e.insert(k, t.link(B(r)));
279
+ await e.insert(F, t.link(W(r)));
228
280
  };
229
- }, K = o({ scope: "@voltro/plugin-audit" }), q = 1e3, J = [], Y = () => [...J], X = () => {
230
- J.length = 0;
231
- }, Z = (e) => {
232
- J.push(e), J.length > q && J.splice(0, J.length - q);
233
- }, Q = (e) => {
281
+ }, X = s({ scope: "@voltro/plugin-audit" }), Z = 1e3, Q = [], ae = () => [...Q], oe = () => {
282
+ Q.length = 0;
283
+ }, se = (e) => {
284
+ Q.push(e), Q.length > Z && Q.splice(0, Q.length - Z);
285
+ }, ce = (e) => {
234
286
  let t = e.subject.id ? `${e.subject.type}:${e.subject.id}` : e.subject.type, n = e.outcome.kind === "ok" ? "ok" : "error", r = {
235
287
  subject: t,
236
288
  tenant: e.subject.tenantId ?? null,
@@ -238,70 +290,49 @@ var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e ===
238
290
  durationMs: e.outcome.durationMs,
239
291
  traceId: e.traceId
240
292
  };
241
- n === "error" ? K.warn(e.tag, r) : K.info(e.tag, r);
242
- }, te = (e, n) => typeof e == "function" ? (n) => t.suspend(() => {
243
- let r = e(n);
244
- return r === void 0 ? t.void : t.isEffect(r) ? r : t.tryPromise({
293
+ n === "error" ? X.warn(e.tag, r) : X.info(e.tag, r);
294
+ }, le = (e, t) => typeof e == "function" ? (t) => n.suspend(() => {
295
+ let r = e(t);
296
+ return r === void 0 ? n.void : n.isEffect(r) ? r : n.tryPromise({
245
297
  try: () => Promise.resolve(r),
246
298
  catch: (e) => e
247
299
  });
248
- }) : e === "datastore" ? (e) => t.suspend(() => {
249
- let r = n();
250
- return r ? t.tryPromise({
300
+ }) : e === "datastore" ? (e) => n.suspend(() => {
301
+ let r = t();
302
+ return r ? n.tryPromise({
251
303
  try: () => r(e),
252
304
  catch: (e) => e
253
- }) : t.void;
254
- }) : e === "memory" ? (e) => t.sync(() => Z(e)) : (e) => t.sync(() => Q(e)), ne = (e) => {
255
- let t = [], n = [], r = (e) => {
256
- if (e._tag !== "Empty") {
257
- if (e._tag === "Fail") {
258
- t.push(e.error);
259
- return;
260
- }
261
- if (e._tag === "Die") {
262
- n.push(e.defect);
263
- return;
264
- }
265
- if (e._tag !== "Interrupt") {
266
- if (e._tag === "Sequential") {
267
- r(e.left), r(e.right);
268
- return;
269
- }
270
- if (e._tag === "Parallel") {
271
- r(e.left), r(e.right);
272
- return;
273
- }
274
- }
275
- }
276
- };
277
- return r(e), t[0] ?? n[0] ?? e;
278
- }, $ = "@voltro/plugin-audit", re = (e = {}) => {
279
- let o = e.sink === "datastore";
280
- o && ee({
305
+ }) : n.void;
306
+ }) : e === "memory" ? (e) => n.sync(() => se(e)) : (e) => n.sync(() => ce(e)), ue = (e) => {
307
+ let n = e.reasons.filter(t.isFailReason).map((e) => e.error), r = e.reasons.filter(t.isDieReason).map((e) => e.defect);
308
+ return n[0] ?? r[0] ?? e;
309
+ }, $ = "@voltro/plugin-audit", de = (e = {}) => {
310
+ let t = e.sink === "datastore";
311
+ t && ee({
281
312
  source: "plugin",
282
- table: k,
313
+ table: F,
283
314
  timeColumn: "at",
284
- ttlMs: p(process.env.VOLTRO_AUDIT_LOG_TTL_HOURS, 8760)
315
+ ttlMs: b(process.env.VOLTRO_AUDIT_LOG_TTL_HOURS, 8760)
285
316
  });
286
- let s, c = te(e.sink, () => s), l = (e) => e === void 0 || !e.global && !e.sticky ? e : new RegExp(e.source, e.flags.replace(/[gy]/g, "")), u = l(e.exclude), d = l(e.include), f = (e) => !(u?.test(e) || d && !d.test(e)), m = (t) => {
317
+ let s, c = le(e.sink, () => s), l = (e) => e === void 0 || !e.global && !e.sticky ? e : new RegExp(e.source, e.flags.replace(/[gy]/g, "")), u = l(e.exclude), d = l(e.include), f = (e) => !(u?.test(e) || d && !d.test(e)), p = (t) => {
287
318
  let n = e.record ?? "all";
288
319
  return n === "all" ? !0 : n === "errors" ? t.outcome.kind === "error" : n(t);
289
- }, h = { __redacted: "all" }, g = e.redactionLengthFloor ?? 16, _ = (t) => {
320
+ }, m = { __redacted: "all" }, h = e.redactionLengthFloor ?? 16, g = (t) => {
290
321
  let n = e.redactInput ?? "all";
291
322
  return n === "none" ? t : n === "all" ? {
292
323
  ...t,
293
- input: h
324
+ input: m
294
325
  } : n === "shape" ? {
295
326
  ...t,
296
- input: O(t.input, g)
327
+ input: P(t.input, h)
297
328
  } : {
298
329
  ...t,
299
330
  input: n(t)
300
331
  };
301
- }, v = (t) => {
332
+ }, _ = (t) => {
302
333
  let n = e.redactOutcome ?? "all";
303
334
  if (n === "none") return t;
304
- let r = t.outcome, i = n === "all" ? h : n === "shape" ? ((e) => O(e, g))(r.kind === "ok" ? r.value : r.error) : n(t);
335
+ let r = t.outcome, i = n === "all" ? m : n === "shape" ? ((e) => P(e, h))(r.kind === "ok" ? r.value : r.error) : n(t);
305
336
  if (r.kind === "ok") return {
306
337
  ...t,
307
338
  outcome: {
@@ -320,7 +351,7 @@ var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e ===
320
351
  }
321
352
  }
322
353
  };
323
- }, y = (t) => {
354
+ }, v = (t) => {
324
355
  let n = e.redactSubject ?? "metadata";
325
356
  if (n === "none") return t;
326
357
  if (typeof n == "function") return {
@@ -329,7 +360,7 @@ var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e ===
329
360
  };
330
361
  let r = t.subject;
331
362
  if (r.metadata === void 0) return t;
332
- let { metadata: i, ...a } = r, o = n === "metadata-shape" ? O(i, g) : h;
363
+ let { metadata: i, ...a } = r, o = n === "metadata-shape" ? P(i, h) : m;
333
364
  return {
334
365
  ...t,
335
366
  subject: {
@@ -337,67 +368,67 @@ var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e ===
337
368
  metadata: o
338
369
  }
339
370
  };
340
- }, b = (e) => {
341
- let t = a(e.subject);
371
+ }, y = (e) => {
372
+ let t = o(e.subject);
342
373
  return t === null ? e : {
343
374
  ...e,
344
375
  impersonation: t
345
376
  };
346
- }, x = (e) => m(e) ? c(v(y(_(b(e))))) : t.void, S = (t) => {
377
+ }, x = (e) => p(e) ? c(_(v(g(y(e))))) : n.void, S = (t) => {
347
378
  if (e.resolveScope !== void 0) try {
348
379
  return e.resolveScope(t);
349
380
  } catch {
350
381
  return;
351
382
  }
352
- }, C = (n, r) => e.metadata === void 0 ? t.succeed(void 0) : t.tryPromise(async () => e.metadata({
353
- tag: n.tag,
354
- subject: n.subject,
355
- input: n.input,
383
+ }, C = (t, r) => e.metadata === void 0 ? n.succeed(void 0) : n.tryPromise(async () => e.metadata({
384
+ tag: t.tag,
385
+ subject: t.subject,
386
+ input: t.input,
356
387
  outcome: r
357
- })).pipe(t.catchAllCause(() => t.succeed(void 0))), w = (e, n) => f(n.tag) ? t.suspend(() => {
358
- let r = Date.now(), i = S(n);
359
- return e.pipe(t.tap((e) => C(n, {
388
+ })).pipe(n.catchCause(() => n.succeed(void 0))), w = (e, t) => f(t.tag) ? n.suspend(() => {
389
+ let r = Date.now(), i = S(t);
390
+ return e.pipe(n.tap((e) => C(t, {
360
391
  kind: "ok",
361
392
  value: e
362
- }).pipe(t.flatMap((t) => x({
393
+ }).pipe(n.flatMap((n) => x({
363
394
  ts: r,
364
- tag: n.tag,
365
- subject: n.subject,
395
+ tag: t.tag,
396
+ subject: t.subject,
366
397
  ...i === void 0 ? {} : { scope: i },
367
- ...t === void 0 ? {} : { metadata: t },
368
- traceId: n.traceId,
369
- input: n.input,
398
+ ...n === void 0 ? {} : { metadata: n },
399
+ traceId: t.traceId,
400
+ input: t.input,
370
401
  outcome: {
371
402
  kind: "ok",
372
403
  value: e,
373
404
  durationMs: Date.now() - r
374
405
  }
375
- }))).pipe(t.catchAllCause(() => t.void))), t.tapErrorCause((e) => {
376
- let a = ne(e);
377
- return C(n, {
406
+ }))).pipe(n.catchCause(() => n.void))), n.tapCause((e) => {
407
+ let a = ue(e);
408
+ return C(t, {
378
409
  kind: "error",
379
410
  error: a
380
- }).pipe(t.flatMap((e) => x({
411
+ }).pipe(n.flatMap((e) => x({
381
412
  ts: r,
382
- tag: n.tag,
383
- subject: n.subject,
413
+ tag: t.tag,
414
+ subject: t.subject,
384
415
  ...i === void 0 ? {} : { scope: i },
385
416
  ...e === void 0 ? {} : { metadata: e },
386
- traceId: n.traceId,
387
- input: n.input,
417
+ traceId: t.traceId,
418
+ input: t.input,
388
419
  outcome: {
389
420
  kind: "error",
390
421
  error: a,
391
422
  durationMs: Date.now() - r
392
423
  }
393
- }))).pipe(t.catchAllCause(() => t.void));
424
+ }))).pipe(n.catchCause(() => n.void));
394
425
  }));
395
426
  }) : e, T = (e) => {
396
- let r = `http.${e.method.toUpperCase()} ${e.path}`;
397
- f(r) && t.runPromise(x({
427
+ let t = `http.${e.method.toUpperCase()} ${e.path}`;
428
+ f(t) && n.runPromise(x({
398
429
  ts: Date.now() - e.durationMs,
399
- tag: r,
400
- subject: n(null),
430
+ tag: t,
431
+ subject: r(null),
401
432
  traceId: e.traceId,
402
433
  input: {
403
434
  method: e.method,
@@ -420,10 +451,10 @@ var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e ===
420
451
  value: { status: e.status },
421
452
  durationMs: e.durationMs
422
453
  }
423
- }).pipe(t.catchAllCause(() => t.void)));
424
- }, E = w, D = w, A = w, j = w;
425
- return r({
426
- name: i({
454
+ }).pipe(n.catchCause(() => n.void)));
455
+ }, E = w, D = w, O = w, k = w;
456
+ return i({
457
+ name: a({
427
458
  base: $,
428
459
  alias: e.alias
429
460
  }),
@@ -434,21 +465,21 @@ var x = 4, S = 32, C = 64, w = /^[A-Za-z_$][A-Za-z0-9_$]*$/, T = (e, t) => e ===
434
465
  "rpc:intercept:action",
435
466
  "rpc:intercept:workflow",
436
467
  "http:intercept",
437
- ...o ? ["store:write"] : [],
468
+ ...t ? ["store:write"] : [],
438
469
  ...e.recordQueries === !0 ? ["rpc:intercept:query"] : []
439
470
  ],
440
- ...o ? {
441
- ...e.tables === !1 ? {} : { extendSchema: { tables: z } },
471
+ ...t ? {
472
+ ...e.tables === !1 ? {} : { extendSchema: { tables: U } },
442
473
  bindDataStore: (e) => {
443
- s = G(e);
474
+ s = Y(e);
444
475
  }
445
476
  } : {},
446
477
  interceptMutation: E,
447
478
  interceptAction: D,
448
- interceptWorkflow: A,
479
+ interceptWorkflow: O,
449
480
  onHttpRoute: T,
450
- ...e.recordQueries === !0 ? { interceptQuery: j } : {}
481
+ ...e.recordQueries === !0 ? { interceptQuery: k } : {}
451
482
  });
452
483
  };
453
484
  //#endregion
454
- export { k as AUDIT_LOG_TABLE, e as audit, U as auditByScope, W as auditBySubject, H as auditByTrace, B as auditEventToRow, R as auditLogTable, z as auditLogTables, re as auditPlugin, F as auditRowHash, X as clearAuditBuffer, G as dataStoreAuditSink, I as makeAuditChain, Y as readAuditBuffer, L as verifyAuditChain };
485
+ export { F as AUDIT_LOG_TABLE, e as audit, q as auditByScope, J as auditBySubject, K as auditByTrace, W as auditEventToRow, H as auditLogTable, U as auditLogTables, de as auditPlugin, R as auditRowHash, oe as clearAuditBuffer, Y as dataStoreAuditSink, z as makeAuditChain, ae as readAuditBuffer, V as verifyAuditChain };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/plugin-audit",
3
- "version": "0.84.0",
3
+ "version": "0.85.0",
4
4
  "description": "Audit plugin — ships the `audit()` schema mixin (createdAt/updatedAt/createdBy/updatedBy → Actor) plus an optional interceptor that records every mutation and action (queries on request) to a configurable sink (console / memory / datastore / custom function).",
5
5
  "keywords": [
6
6
  "voltro",
@@ -38,12 +38,12 @@
38
38
  "node": ">=24.0.0"
39
39
  },
40
40
  "dependencies": {
41
- "@voltro/database": "0.84.0",
42
- "@voltro/logger": "0.84.0",
43
- "@voltro/protocol": "0.84.0"
41
+ "@voltro/database": "0.85.0",
42
+ "@voltro/logger": "0.85.0",
43
+ "@voltro/protocol": "0.85.0"
44
44
  },
45
45
  "peerDependencies": {
46
- "effect": "^3.22.2"
46
+ "effect": "4.0.1"
47
47
  },
48
48
  "publishConfig": {
49
49
  "access": "public"