@murumets-ee/logging 0.1.4 → 0.1.6

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,3 +1,4 @@
1
+ //#region src/admin/routes.d.ts
1
2
  /**
2
3
  * Audit log admin routes for the centralized admin API handler.
3
4
  *
@@ -18,27 +19,28 @@
18
19
  * ```
19
20
  */
20
21
  interface AdminRoute {
21
- prefix: string;
22
- resource?: string;
23
- actions?: readonly string[];
24
- handlers: Partial<Record<string, (req: Request, ctx: {
25
- segments: string[];
26
- user: {
27
- id: string;
28
- role?: string;
29
- };
30
- checkPermission: (resource: string, action: string) => boolean;
31
- }) => Promise<Response>>>;
22
+ prefix: string;
23
+ resource?: string;
24
+ actions?: readonly string[];
25
+ handlers: Partial<Record<string, (req: Request, ctx: {
26
+ segments: string[];
27
+ user: {
28
+ id: string;
29
+ role?: string;
30
+ };
31
+ checkPermission: (resource: string, action: string) => boolean;
32
+ }) => Promise<Response>>>;
32
33
  }
33
34
  interface AuditLogClientLike {
34
- query(options: Record<string, unknown>): Promise<{
35
- items: unknown[];
36
- total: number;
37
- }>;
38
- findById(id: string): Promise<unknown | null>;
39
- getDistinctEntityTypes(): Promise<string[]>;
40
- getDistinctActions(): Promise<string[]>;
35
+ query(options: Record<string, unknown>): Promise<{
36
+ items: unknown[];
37
+ total: number;
38
+ }>;
39
+ findById(id: string): Promise<unknown | null>;
40
+ getDistinctEntityTypes(): Promise<string[]>;
41
+ getDistinctActions(): Promise<string[]>;
41
42
  }
42
43
  declare function logRoutes(getClient: () => AuditLogClientLike): AdminRoute;
43
-
44
+ //#endregion
44
45
  export { logRoutes };
46
+ //# sourceMappingURL=admin.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.d.mts","names":[],"sources":["../src/admin/routes.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;UA2BU,UAAA;EACR,MAAA;EACA,QAAA;EACA,OAAA;EACA,QAAA,EAAU,OAAA,CACR,MAAA,UAGI,GAAA,EAAK,OAAA,EACL,GAAA;IACE,QAAA;IACA,IAAA;MAAQ,EAAA;MAAY,IAAA;IAAA;IACpB,eAAA,GAAkB,QAAA,UAAkB,MAAA;EAAA,MAEnC,OAAA,CAAQ,QAAA;AAAA;AAAA,UA4CT,kBAAA;EACR,KAAA,CAAM,OAAA,EAAS,MAAA,oBAA0B,OAAA;IAAU,KAAA;IAAkB,KAAA;EAAA;EACrE,QAAA,CAAS,EAAA,WAAa,OAAA;EACtB,sBAAA,IAA0B,OAAA;EAC1B,kBAAA,IAAsB,OAAA;AAAA;AAAA,iBAOR,SAAA,CAAU,SAAA,QAAiB,kBAAA,GAAqB,UAAA"}
package/dist/admin.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{z as e}from"zod";const t=/^[a-zA-Z0-9_-]{1,255}$/,n=e.object({action:e.string().max(100).optional(),entityType:e.string().max(100).optional(),entityId:e.string().regex(t,`Invalid ID format`).optional(),userId:e.string().regex(t,`Invalid user ID format`).optional(),dateFrom:e.string().datetime({offset:!0,message:`Invalid ISO date`}).optional(),dateTo:e.string().datetime({offset:!0,message:`Invalid ISO date`}).optional(),search:e.string().max(200).optional(),limit:e.coerce.number().min(1).max(100).default(50),offset:e.coerce.number().min(0).default(0),sortField:e.enum([`createdAt`,`action`,`entityType`]).default(`createdAt`),sortDirection:e.enum([`asc`,`desc`]).default(`desc`)});function r(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":`application/json`}})}function i(e,t){return r({error:e},t)}function a(e){return{prefix:`logs`,resource:`audit-logs`,actions:[`view`],handlers:{GET:async(t,{segments:a})=>{let o=e();if(a.length===1&&a[0]===`filters`){let[e,t]=await Promise.all([o.getDistinctEntityTypes(),o.getDistinctActions()]);return r({entityTypes:e,actions:t})}if(a.length===1&&a[0]!==`filters`){let e=await o.findById(a[0]);return e?r(e):i(`Audit log entry not found`,404)}let s=new URL(t.url),c=Object.fromEntries(s.searchParams),l=n.safeParse(c);return l.success?r(await o.query({...l.data,dateFrom:l.data.dateFrom?new Date(l.data.dateFrom):void 0,dateTo:l.data.dateTo?new Date(l.data.dateTo):void 0})):i(`Invalid query params: ${l.error.issues.map(e=>e.message).join(`, `)}`,400)}}}}export{a as logRoutes};
2
+ //# sourceMappingURL=admin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.mjs","names":[],"sources":["../src/admin/routes.ts"],"sourcesContent":["/**\n * Audit log admin routes for the centralized admin API handler.\n *\n * Read-only: only GET handlers. Audit logs are immutable.\n * Admin-only: explicit role check before any data access.\n *\n * @example\n * ```typescript\n * import { createAdminApiHandler } from '@murumets-ee/admin-ui/server'\n * import { logRoutes } from '@murumets-ee/logging/admin'\n * import { AuditLogClient } from '@murumets-ee/logging'\n *\n * const handler = createAdminApiHandler({\n * authenticate: async (req) => { ... },\n * entities: [...],\n * routes: [logRoutes(() => new AuditLogClient(db))],\n * })\n * ```\n */\n\nimport { z } from 'zod'\n\n// ---------------------------------------------------------------------------\n// Local route type — avoids circular build dep: logging → core → logging.\n// Structurally compatible with AdminRoute from @murumets-ee/core.\n// ---------------------------------------------------------------------------\n\ninterface AdminRoute {\n prefix: string\n resource?: string\n actions?: readonly string[]\n handlers: Partial<\n Record<\n string,\n (\n req: Request,\n ctx: {\n segments: string[]\n user: { id: string; role?: string }\n checkPermission: (resource: string, action: string) => boolean\n },\n ) => Promise<Response>\n >\n >\n}\n\n// ---------------------------------------------------------------------------\n// Query param validation\n// ---------------------------------------------------------------------------\n\nconst ID_REGEX = /^[a-zA-Z0-9_-]{1,255}$/\n\nconst auditLogQuerySchema = z.object({\n action: z.string().max(100).optional(),\n entityType: z.string().max(100).optional(),\n entityId: z.string().regex(ID_REGEX, 'Invalid ID format').optional(),\n userId: z.string().regex(ID_REGEX, 'Invalid user ID format').optional(),\n dateFrom: z.string().datetime({ offset: true, message: 'Invalid ISO date' }).optional(),\n dateTo: z.string().datetime({ offset: true, message: 'Invalid ISO date' }).optional(),\n search: z.string().max(200).optional(),\n limit: z.coerce.number().min(1).max(100).default(50),\n offset: z.coerce.number().min(0).default(0),\n sortField: z.enum(['createdAt', 'action', 'entityType']).default('createdAt'),\n sortDirection: z.enum(['asc', 'desc']).default('desc'),\n})\n\n// ---------------------------------------------------------------------------\n// Response helpers\n// ---------------------------------------------------------------------------\n\nfunction json(data: unknown, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: { 'Content-Type': 'application/json' },\n })\n}\n\nfunction errorJson(message: string, status: number): Response {\n return json({ error: message }, status)\n}\n\n// ---------------------------------------------------------------------------\n// AuditLogClient interface (avoids importing from ../audit-client.js)\n// ---------------------------------------------------------------------------\n\ninterface AuditLogClientLike {\n query(options: Record<string, unknown>): Promise<{ items: unknown[]; total: number }>\n findById(id: string): Promise<unknown | null>\n getDistinctEntityTypes(): Promise<string[]>\n getDistinctActions(): Promise<string[]>\n}\n\n// ---------------------------------------------------------------------------\n// Route factory\n// ---------------------------------------------------------------------------\n\nexport function logRoutes(getClient: () => AuditLogClientLike): AdminRoute {\n return {\n prefix: 'logs',\n resource: 'audit-logs',\n actions: ['view'],\n handlers: {\n GET: async (req, { segments }) => {\n // Permission check handled by framework via resource: 'audit-logs'\n const client = getClient()\n\n // GET /logs/filters — distinct values for filter dropdowns\n if (segments.length === 1 && segments[0] === 'filters') {\n const [entityTypes, actions] = await Promise.all([\n client.getDistinctEntityTypes(),\n client.getDistinctActions(),\n ])\n return json({ entityTypes, actions })\n }\n\n // GET /logs/:id — single entry detail\n if (segments.length === 1 && segments[0] !== 'filters') {\n const entry = await client.findById(segments[0])\n if (!entry) return errorJson('Audit log entry not found', 404)\n return json(entry)\n }\n\n // GET /logs — list with filters + pagination\n const url = new URL(req.url)\n const params = Object.fromEntries(url.searchParams)\n const parsed = auditLogQuerySchema.safeParse(params)\n if (!parsed.success) {\n return errorJson(\n `Invalid query params: ${parsed.error.issues.map((i) => i.message).join(', ')}`,\n 400,\n )\n }\n\n const result = await client.query({\n ...parsed.data,\n dateFrom: parsed.data.dateFrom ? new Date(parsed.data.dateFrom) : undefined,\n dateTo: parsed.data.dateTo ? new Date(parsed.data.dateTo) : undefined,\n })\n\n return json(result)\n },\n // No POST, PATCH, DELETE — audit logs are append-only\n },\n }\n}\n"],"mappings":"wBAkDA,MAAM,EAAW,yBAEX,EAAsB,EAAE,OAAO,CACnC,OAAQ,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,UAAU,CACtC,WAAY,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,UAAU,CAC1C,SAAU,EAAE,QAAQ,CAAC,MAAM,EAAU,oBAAoB,CAAC,UAAU,CACpE,OAAQ,EAAE,QAAQ,CAAC,MAAM,EAAU,yBAAyB,CAAC,UAAU,CACvE,SAAU,EAAE,QAAQ,CAAC,SAAS,CAAE,OAAQ,GAAM,QAAS,mBAAoB,CAAC,CAAC,UAAU,CACvF,OAAQ,EAAE,QAAQ,CAAC,SAAS,CAAE,OAAQ,GAAM,QAAS,mBAAoB,CAAC,CAAC,UAAU,CACrF,OAAQ,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,UAAU,CACtC,MAAO,EAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,CACpD,OAAQ,EAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAC3C,UAAW,EAAE,KAAK,CAAC,YAAa,SAAU,aAAa,CAAC,CAAC,QAAQ,YAAY,CAC7E,cAAe,EAAE,KAAK,CAAC,MAAO,OAAO,CAAC,CAAC,QAAQ,OAAO,CACvD,CAAC,CAMF,SAAS,EAAK,EAAe,EAAS,IAAe,CACnD,OAAO,IAAI,SAAS,KAAK,UAAU,EAAK,CAAE,CACxC,SACA,QAAS,CAAE,eAAgB,mBAAoB,CAChD,CAAC,CAGJ,SAAS,EAAU,EAAiB,EAA0B,CAC5D,OAAO,EAAK,CAAE,MAAO,EAAS,CAAE,EAAO,CAkBzC,SAAgB,EAAU,EAAiD,CACzE,MAAO,CACL,OAAQ,OACR,SAAU,aACV,QAAS,CAAC,OAAO,CACjB,SAAU,CACR,IAAK,MAAO,EAAK,CAAE,cAAe,CAEhC,IAAM,EAAS,GAAW,CAG1B,GAAI,EAAS,SAAW,GAAK,EAAS,KAAO,UAAW,CACtD,GAAM,CAAC,EAAa,GAAW,MAAM,QAAQ,IAAI,CAC/C,EAAO,wBAAwB,CAC/B,EAAO,oBAAoB,CAC5B,CAAC,CACF,OAAO,EAAK,CAAE,cAAa,UAAS,CAAC,CAIvC,GAAI,EAAS,SAAW,GAAK,EAAS,KAAO,UAAW,CACtD,IAAM,EAAQ,MAAM,EAAO,SAAS,EAAS,GAAG,CAEhD,OADK,EACE,EAAK,EAAM,CADC,EAAU,4BAA6B,IAAI,CAKhE,IAAM,EAAM,IAAI,IAAI,EAAI,IAAI,CACtB,EAAS,OAAO,YAAY,EAAI,aAAa,CAC7C,EAAS,EAAoB,UAAU,EAAO,CAcpD,OAbK,EAAO,QAaL,EANQ,MAAM,EAAO,MAAM,CAChC,GAAG,EAAO,KACV,SAAU,EAAO,KAAK,SAAW,IAAI,KAAK,EAAO,KAAK,SAAS,CAAG,IAAA,GAClE,OAAQ,EAAO,KAAK,OAAS,IAAI,KAAK,EAAO,KAAK,OAAO,CAAG,IAAA,GAC7D,CAAC,CAEiB,CAZV,EACL,yBAAyB,EAAO,MAAM,OAAO,IAAK,GAAM,EAAE,QAAQ,CAAC,KAAK,KAAK,GAC7E,IACD,EAYN,CACF"}
@@ -0,0 +1,125 @@
1
+ import { toolkitAuditLogs } from "./schema.mjs";
2
+ import { Logger as Logger$1 } from "pino";
3
+ import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
4
+
5
+ //#region src/logger.d.ts
6
+ type Logger = Logger$1;
7
+ interface LoggerConfig {
8
+ name?: string;
9
+ level?: string;
10
+ redact?: string[];
11
+ }
12
+ /**
13
+ * Create a logger instance
14
+ * If no config provided, returns the root logger
15
+ * If config provided, returns a child logger with the specified context
16
+ */
17
+ declare function createLogger(config?: LoggerConfig): Logger;
18
+ /**
19
+ * Create a child logger from an existing logger with additional context
20
+ */
21
+ declare function createChildLogger(parent: Logger, context: Record<string, unknown>): Logger;
22
+ //#endregion
23
+ //#region src/audit.d.ts
24
+ interface AuditEntry {
25
+ action: string;
26
+ entityType?: string;
27
+ entityId?: string;
28
+ userId?: string;
29
+ userName?: string;
30
+ changes?: Record<string, unknown>;
31
+ metadata?: Record<string, unknown>;
32
+ }
33
+ interface AuditConfig {
34
+ logger: Logger;
35
+ dbWriter?: (entry: AuditEntry) => Promise<void>;
36
+ }
37
+ interface AuditLogger {
38
+ log: (entry: AuditEntry) => Promise<void>;
39
+ }
40
+ /**
41
+ * Create a dbWriter callback wired to AuditLogClient.
42
+ *
43
+ * Pass the returned function as `dbWriter` to `createAuditLogger`:
44
+ * ```typescript
45
+ * const auditLogger = createAuditLogger({
46
+ * logger,
47
+ * dbWriter: createAuditDbWriter(db),
48
+ * })
49
+ * ```
50
+ */
51
+ declare function createAuditDbWriter(db: PostgresJsDatabase): (entry: AuditEntry) => Promise<void>;
52
+ /**
53
+ * Create an audit logger
54
+ *
55
+ * Audit logs are written to stdout immediately (non-blocking).
56
+ * Optionally, they can also be written to the database if dbWriter is provided.
57
+ *
58
+ * Database writes are fire-and-forget to avoid blocking the main operation.
59
+ * If DB write fails, it's logged to stderr but doesn't throw.
60
+ */
61
+ declare function createAuditLogger(config: AuditConfig): AuditLogger;
62
+ //#endregion
63
+ //#region src/audit-client.d.ts
64
+ interface AuditLogQueryOptions {
65
+ action?: string;
66
+ entityType?: string;
67
+ entityId?: string;
68
+ userId?: string;
69
+ dateFrom?: Date;
70
+ dateTo?: Date;
71
+ /** Free-text search across action, entityType, userName */
72
+ search?: string;
73
+ /** Default 50, max 100 */
74
+ limit?: number;
75
+ offset?: number;
76
+ sortField?: 'createdAt' | 'action' | 'entityType';
77
+ sortDirection?: 'asc' | 'desc';
78
+ }
79
+ interface AuditLogEntry {
80
+ id: string;
81
+ action: string;
82
+ entityType: string | null;
83
+ entityId: string | null;
84
+ userId: string | null;
85
+ userName: string | null;
86
+ changes: Record<string, unknown> | null;
87
+ metadata: Record<string, unknown> | null;
88
+ createdAt: Date;
89
+ }
90
+ interface AuditLogListResult {
91
+ items: AuditLogEntry[];
92
+ total: number;
93
+ }
94
+ declare class AuditLogClient {
95
+ private db;
96
+ constructor(db: PostgresJsDatabase);
97
+ /** Write a single audit log entry */
98
+ write(entry: Omit<AuditLogEntry, 'id' | 'createdAt'>): Promise<void>;
99
+ /** Query audit logs with filters and pagination */
100
+ query(options?: AuditLogQueryOptions): Promise<AuditLogListResult>;
101
+ /** Get a single audit log entry by ID */
102
+ findById(id: string): Promise<AuditLogEntry | null>;
103
+ /** Get distinct entity types present in the audit log */
104
+ getDistinctEntityTypes(): Promise<string[]>;
105
+ /** Get distinct actions present in the audit log */
106
+ getDistinctActions(): Promise<string[]>;
107
+ private buildConditions;
108
+ private buildOrderBy;
109
+ }
110
+ //#endregion
111
+ //#region src/context.d.ts
112
+ interface RequestContext {
113
+ requestId?: string;
114
+ userId?: string;
115
+ teamId?: string;
116
+ locale?: string;
117
+ }
118
+ /**
119
+ * Bind request context to a logger
120
+ * Returns a child logger with the context automatically included in all log entries
121
+ */
122
+ declare function bindRequestContext(logger: Logger, context: RequestContext): Logger;
123
+ //#endregion
124
+ export { type AuditConfig, type AuditEntry, AuditLogClient, type AuditLogEntry, type AuditLogListResult, type AuditLogQueryOptions, type AuditLogger, type Logger, type LoggerConfig, type RequestContext, bindRequestContext, createAuditDbWriter, createAuditLogger, createChildLogger, createLogger, toolkitAuditLogs };
125
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/logger.ts","../src/audit.ts","../src/audit-client.ts","../src/context.ts"],"mappings":";;;;;KAEY,MAAA,GAAS,QAAA;AAAA,UAEJ,YAAA;EACf,IAAA;EACA,KAAA;EACA,MAAA;AAAA;;;;AAHF;;iBAoCgB,YAAA,CAAa,MAAA,GAAS,YAAA,GAAe,MAAA;;;;iBAqBrC,iBAAA,CAAkB,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,MAAA,oBAA0B,MAAA;;;UCzDpE,UAAA;EACf,MAAA;EACA,UAAA;EACA,QAAA;EACA,MAAA;EACA,QAAA;EACA,OAAA,GAAU,MAAA;EACV,QAAA,GAAW,MAAA;AAAA;AAAA,UAGI,WAAA;EACf,MAAA,EAAQ,MAAA;EACR,QAAA,IAAY,KAAA,EAAO,UAAA,KAAe,OAAA;AAAA;AAAA,UAGnB,WAAA;EACf,GAAA,GAAM,KAAA,EAAO,UAAA,KAAe,OAAA;AAAA;;ADoB9B;;;;;;;;;AAqBA;iBC3BgB,mBAAA,CAAoB,EAAA,EAAI,kBAAA,IAAsB,KAAA,EAAO,UAAA,KAAe,OAAA;;;;;;;;;;iBAuBpE,iBAAA,CAAkB,MAAA,EAAQ,WAAA,GAAc,WAAA;;;UCjDvC,oBAAA;EACf,MAAA;EACA,UAAA;EACA,QAAA;EACA,MAAA;EACA,QAAA,GAAW,IAAA;EACX,MAAA,GAAS,IAAA;EFZU;EEcnB,MAAA;EFZe;EEcf,KAAA;EACA,MAAA;EACA,SAAA;EACA,aAAA;AAAA;AAAA,UAGe,aAAA;EACf,EAAA;EACA,MAAA;EACA,UAAA;EACA,QAAA;EACA,MAAA;EACA,QAAA;EACA,OAAA,EAAS,MAAA;EACT,QAAA,EAAU,MAAA;EACV,SAAA,EAAW,IAAA;AAAA;AAAA,UAGI,kBAAA;EACf,KAAA,EAAO,aAAA;EACP,KAAA;AAAA;AAAA,cAcW,cAAA;EAAA,QACS,EAAA;cAAA,EAAA,EAAI,kBAAA;EFQiE;EELnF,KAAA,CAAM,KAAA,EAAO,IAAA,CAAK,aAAA,wBAAqC,OAAA;EFKrB;EEQlC,KAAA,CAAM,OAAA,GAAS,oBAAA,GAA4B,OAAA,CAAQ,kBAAA;EFRA;EEkCnD,QAAA,CAAS,EAAA,WAAa,OAAA,CAAQ,aAAA;EFlC+C;EE6C7E,sBAAA,CAAA,GAA0B,OAAA;EF7CyD;EEwDnF,kBAAA,CAAA,GAAsB,OAAA;EAAA,QAapB,eAAA;EAAA,QAmCA,YAAA;AAAA;;;UCnKO,cAAA;EACf,SAAA;EACA,MAAA;EACA,MAAA;EACA,MAAA;AAAA;;;;AHFF;iBGSgB,kBAAA,CAAmB,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,cAAA,GAAiB,MAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{toolkitAuditLogs as e}from"./schema.mjs";import{and as t,asc as n,count as r,desc as i,eq as a,gte as o,ilike as s,isNotNull as c,lte as l,or as u}from"drizzle-orm";import d from"pino";var f=class{constructor(e){this.db=e}async write(t){await this.db.insert(e).values({action:t.action,entityType:t.entityType,entityId:t.entityId,userId:t.userId,userName:t.userName,changes:t.changes,metadata:t.metadata})}async query(n={}){let i=Math.min(Math.max(n.limit??50,1),100),a=Math.max(n.offset??0,0),o=this.buildConditions(n),s=o.length>0?t(...o):void 0,c=this.buildOrderBy(n.sortField,n.sortDirection),[l,u]=await Promise.all([this.db.select().from(e).where(s).orderBy(c).limit(i).offset(a),this.db.select({count:r()}).from(e).where(s)]);return{items:l,total:u[0]?.count??0}}async findById(t){return(await this.db.select().from(e).where(a(e.id,t)).limit(1))[0]??null}async getDistinctEntityTypes(){return(await this.db.selectDistinct({entityType:e.entityType}).from(e).where(c(e.entityType)).orderBy(n(e.entityType))).map(e=>e.entityType).filter(Boolean)}async getDistinctActions(){return(await this.db.selectDistinct({action:e.action}).from(e).orderBy(n(e.action))).map(e=>e.action)}buildConditions(t){let n=[];if(t.action&&n.push(a(e.action,t.action)),t.entityType&&n.push(a(e.entityType,t.entityType)),t.entityId&&n.push(a(e.entityId,t.entityId)),t.userId&&n.push(a(e.userId,t.userId)),t.dateFrom&&n.push(o(e.createdAt,t.dateFrom)),t.dateTo&&n.push(l(e.createdAt,t.dateTo)),t.search){let r=`%${t.search}%`;n.push(u(s(e.action,r),s(e.entityType,r),s(e.userName,r)))}return n}buildOrderBy(t,r){let a=r===`asc`?n:i;switch(t){case`action`:return a(e.action);case`entityType`:return a(e.entityType);default:return a(e.createdAt)}}};function p(e){let t=new f(e);return e=>t.write({action:e.action,entityType:e.entityType??null,entityId:e.entityId??null,userId:e.userId??null,userName:e.userName??null,changes:e.changes??null,metadata:e.metadata??null})}function m(e){return{log:async t=>{e.logger.info({audit:!0,action:t.action,entityType:t.entityType,entityId:t.entityId,userId:t.userId,userName:t.userName,changes:t.changes,metadata:t.metadata},`Audit: ${t.action}`),e.dbWriter&&e.dbWriter(t).catch(n=>{e.logger.error({err:n,auditEntry:t},`Failed to write audit log to database`)})}}}function h(e,t){return e.child(t)}const g=d({level:process.env.LOG_LEVEL||`info`,formatters:{level:e=>({level:e})},timestamp:!1,serializers:{err:d.stdSerializers.err,error:d.stdSerializers.err},redact:{paths:[`password`,`token`,`secret`,`apiKey`,`accessToken`,`refreshToken`],censor:`[REDACTED]`}});function _(e){if(!e)return g;let t={};e.name&&(t.name=e.name);let n={};return e.level&&(n.level=e.level),g.child(t,n)}function v(e,t){return e.child(t)}export{f as AuditLogClient,h as bindRequestContext,p as createAuditDbWriter,m as createAuditLogger,v as createChildLogger,_ as createLogger,e as toolkitAuditLogs};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/audit-client.ts","../src/audit.ts","../src/context.ts","../src/logger.ts"],"sourcesContent":["import { and, asc, count, desc, eq, gte, ilike, isNotNull, lte, or, type SQL } from 'drizzle-orm'\nimport type { PostgresJsDatabase } from 'drizzle-orm/postgres-js'\nimport { toolkitAuditLogs } from './schema.js'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface AuditLogQueryOptions {\n action?: string\n entityType?: string\n entityId?: string\n userId?: string\n dateFrom?: Date\n dateTo?: Date\n /** Free-text search across action, entityType, userName */\n search?: string\n /** Default 50, max 100 */\n limit?: number\n offset?: number\n sortField?: 'createdAt' | 'action' | 'entityType'\n sortDirection?: 'asc' | 'desc'\n}\n\nexport interface AuditLogEntry {\n id: string\n action: string\n entityType: string | null\n entityId: string | null\n userId: string | null\n userName: string | null\n changes: Record<string, unknown> | null\n metadata: Record<string, unknown> | null\n createdAt: Date\n}\n\nexport interface AuditLogListResult {\n items: AuditLogEntry[]\n total: number\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst MAX_LIMIT = 100\nconst DEFAULT_LIMIT = 50\n\n// ---------------------------------------------------------------------------\n// Client\n// ---------------------------------------------------------------------------\n\nexport class AuditLogClient {\n constructor(private db: PostgresJsDatabase) {}\n\n /** Write a single audit log entry */\n async write(entry: Omit<AuditLogEntry, 'id' | 'createdAt'>): Promise<void> {\n await this.db.insert(toolkitAuditLogs).values({\n action: entry.action,\n entityType: entry.entityType,\n entityId: entry.entityId,\n userId: entry.userId,\n userName: entry.userName,\n changes: entry.changes,\n metadata: entry.metadata,\n })\n }\n\n /** Query audit logs with filters and pagination */\n async query(options: AuditLogQueryOptions = {}): Promise<AuditLogListResult> {\n const limit = Math.min(Math.max(options.limit ?? DEFAULT_LIMIT, 1), MAX_LIMIT)\n const offset = Math.max(options.offset ?? 0, 0)\n\n const conditions = this.buildConditions(options)\n const where = conditions.length > 0 ? and(...conditions) : undefined\n const orderBy = this.buildOrderBy(options.sortField, options.sortDirection)\n\n const [items, totalResult] = await Promise.all([\n this.db\n .select()\n .from(toolkitAuditLogs)\n .where(where)\n .orderBy(orderBy)\n .limit(limit)\n .offset(offset),\n this.db.select({ count: count() }).from(toolkitAuditLogs).where(where),\n ])\n\n return {\n items: items as AuditLogEntry[],\n total: totalResult[0]?.count ?? 0,\n }\n }\n\n /** Get a single audit log entry by ID */\n async findById(id: string): Promise<AuditLogEntry | null> {\n const rows = await this.db\n .select()\n .from(toolkitAuditLogs)\n .where(eq(toolkitAuditLogs.id, id))\n .limit(1)\n\n return (rows[0] as AuditLogEntry) ?? null\n }\n\n /** Get distinct entity types present in the audit log */\n async getDistinctEntityTypes(): Promise<string[]> {\n const rows = await this.db\n .selectDistinct({ entityType: toolkitAuditLogs.entityType })\n .from(toolkitAuditLogs)\n .where(isNotNull(toolkitAuditLogs.entityType))\n .orderBy(asc(toolkitAuditLogs.entityType))\n\n return rows.map((r) => r.entityType!).filter(Boolean)\n }\n\n /** Get distinct actions present in the audit log */\n async getDistinctActions(): Promise<string[]> {\n const rows = await this.db\n .selectDistinct({ action: toolkitAuditLogs.action })\n .from(toolkitAuditLogs)\n .orderBy(asc(toolkitAuditLogs.action))\n\n return rows.map((r) => r.action)\n }\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n private buildConditions(options: AuditLogQueryOptions): SQL[] {\n const conditions: SQL[] = []\n\n if (options.action) {\n conditions.push(eq(toolkitAuditLogs.action, options.action))\n }\n if (options.entityType) {\n conditions.push(eq(toolkitAuditLogs.entityType, options.entityType))\n }\n if (options.entityId) {\n conditions.push(eq(toolkitAuditLogs.entityId, options.entityId))\n }\n if (options.userId) {\n conditions.push(eq(toolkitAuditLogs.userId, options.userId))\n }\n if (options.dateFrom) {\n conditions.push(gte(toolkitAuditLogs.createdAt, options.dateFrom))\n }\n if (options.dateTo) {\n conditions.push(lte(toolkitAuditLogs.createdAt, options.dateTo))\n }\n if (options.search) {\n const pattern = `%${options.search}%`\n conditions.push(\n or(\n ilike(toolkitAuditLogs.action, pattern),\n ilike(toolkitAuditLogs.entityType, pattern),\n ilike(toolkitAuditLogs.userName, pattern),\n )!,\n )\n }\n\n return conditions\n }\n\n private buildOrderBy(sortField?: string, sortDirection?: string): SQL {\n const dirFn = sortDirection === 'asc' ? asc : desc\n switch (sortField) {\n case 'action':\n return dirFn(toolkitAuditLogs.action)\n case 'entityType':\n return dirFn(toolkitAuditLogs.entityType)\n case 'createdAt':\n default:\n return dirFn(toolkitAuditLogs.createdAt)\n }\n }\n}\n","import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js'\nimport { AuditLogClient } from './audit-client.js'\nimport type { Logger } from './logger.js'\n\nexport interface AuditEntry {\n action: string\n entityType?: string\n entityId?: string\n userId?: string\n userName?: string\n changes?: Record<string, unknown>\n metadata?: Record<string, unknown>\n}\n\nexport interface AuditConfig {\n logger: Logger\n dbWriter?: (entry: AuditEntry) => Promise<void>\n}\n\nexport interface AuditLogger {\n log: (entry: AuditEntry) => Promise<void>\n}\n\n/**\n * Create a dbWriter callback wired to AuditLogClient.\n *\n * Pass the returned function as `dbWriter` to `createAuditLogger`:\n * ```typescript\n * const auditLogger = createAuditLogger({\n * logger,\n * dbWriter: createAuditDbWriter(db),\n * })\n * ```\n */\nexport function createAuditDbWriter(db: PostgresJsDatabase): (entry: AuditEntry) => Promise<void> {\n const client = new AuditLogClient(db)\n return (entry) =>\n client.write({\n action: entry.action,\n entityType: entry.entityType ?? null,\n entityId: entry.entityId ?? null,\n userId: entry.userId ?? null,\n userName: entry.userName ?? null,\n changes: entry.changes ?? null,\n metadata: entry.metadata ?? null,\n })\n}\n\n/**\n * Create an audit logger\n *\n * Audit logs are written to stdout immediately (non-blocking).\n * Optionally, they can also be written to the database if dbWriter is provided.\n *\n * Database writes are fire-and-forget to avoid blocking the main operation.\n * If DB write fails, it's logged to stderr but doesn't throw.\n */\nexport function createAuditLogger(config: AuditConfig): AuditLogger {\n return {\n log: async (entry: AuditEntry) => {\n // Log to stdout immediately (structured log with audit: true marker)\n config.logger.info(\n {\n audit: true,\n action: entry.action,\n entityType: entry.entityType,\n entityId: entry.entityId,\n userId: entry.userId,\n userName: entry.userName,\n changes: entry.changes,\n metadata: entry.metadata,\n },\n `Audit: ${entry.action}`,\n )\n\n // Write to DB if configured (fire and forget)\n if (config.dbWriter) {\n config.dbWriter(entry).catch((err) => {\n config.logger.error({ err, auditEntry: entry }, 'Failed to write audit log to database')\n })\n }\n },\n }\n}\n","import type { Logger } from './logger.js'\n\nexport interface RequestContext {\n requestId?: string\n userId?: string\n teamId?: string\n locale?: string\n}\n\n/**\n * Bind request context to a logger\n * Returns a child logger with the context automatically included in all log entries\n */\nexport function bindRequestContext(logger: Logger, context: RequestContext): Logger {\n return logger.child(context)\n}\n","import pino, { type Logger as PinoLogger } from 'pino'\n\nexport type Logger = PinoLogger\n\nexport interface LoggerConfig {\n name?: string\n level?: string\n redact?: string[]\n}\n\n/**\n * Root logger instance\n *\n * IMPORTANT: No transports are used to avoid Next.js bundler issues.\n * Pino transports use worker threads that break webpack/turbopack.\n *\n * For dev pretty-printing, pipe to pino-pretty:\n * pnpm dev | pnpm pino-pretty\n */\nconst rootLogger = pino({\n level: process.env.LOG_LEVEL || 'info',\n formatters: {\n level: (label) => ({ level: label }),\n },\n timestamp: false,\n serializers: {\n err: pino.stdSerializers.err,\n error: pino.stdSerializers.err,\n },\n redact: {\n paths: ['password', 'token', 'secret', 'apiKey', 'accessToken', 'refreshToken'],\n censor: '[REDACTED]',\n },\n})\n\n/**\n * Create a logger instance\n * If no config provided, returns the root logger\n * If config provided, returns a child logger with the specified context\n */\nexport function createLogger(config?: LoggerConfig): Logger {\n if (!config) {\n return rootLogger\n }\n\n const bindings: Record<string, unknown> = {}\n if (config.name) {\n bindings.name = config.name\n }\n\n const options: { level?: string } = {}\n if (config.level) {\n options.level = config.level\n }\n\n return rootLogger.child(bindings, options)\n}\n\n/**\n * Create a child logger from an existing logger with additional context\n */\nexport function createChildLogger(parent: Logger, context: Record<string, unknown>): Logger {\n return parent.child(context)\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ //#region src/plugin.d.ts
1
2
  /**
2
3
  * Logging plugin — registers the audit log table schema for migration generation.
3
4
  *
@@ -11,8 +12,9 @@
11
12
  * ```
12
13
  */
13
14
  declare function logging(): {
14
- name: string;
15
- schemaCode: string;
15
+ name: string;
16
+ schemaCode: string;
16
17
  };
17
-
18
+ //#endregion
18
19
  export { logging };
20
+ //# sourceMappingURL=plugin.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.mts","names":[],"sources":["../src/plugin.ts"],"mappings":";;AAcA;;;;;;;;;;;iBAAgB,OAAA,CAAA;EAAa,IAAA;EAAc,UAAA;AAAA"}
@@ -0,0 +1,2 @@
1
+ import{generateLoggingSchemaCode as e}from"./schema-codegen.mjs";function t(){return{name:`@murumets-ee/logging`,schemaCode:e()}}export{t as logging};
2
+ //# sourceMappingURL=plugin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.mjs","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["import { generateLoggingSchemaCode } from './schema-codegen.js'\n\n/**\n * Logging plugin — registers the audit log table schema for migration generation.\n *\n * @example\n * ```typescript\n * import { logging } from '@murumets-ee/logging/plugin'\n *\n * export default defineConfig({\n * plugins: [logging()],\n * })\n * ```\n */\nexport function logging(): { name: string; schemaCode: string } {\n return {\n name: '@murumets-ee/logging',\n schemaCode: generateLoggingSchemaCode(),\n }\n}\n"],"mappings":"iEAcA,SAAgB,GAAgD,CAC9D,MAAO,CACL,KAAM,uBACN,WAAY,GAA2B,CACxC"}
@@ -1,7 +1,9 @@
1
+ //#region src/schema-codegen.d.ts
1
2
  /**
2
3
  * Returns Drizzle table definition code as a string for logging plugin tables.
3
4
  * Used by the CLI generate command to inline into generated/schema.ts.
4
5
  */
5
6
  declare function generateLoggingSchemaCode(): string;
6
-
7
+ //#endregion
7
8
  export { generateLoggingSchemaCode };
9
+ //# sourceMappingURL=schema-codegen.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-codegen.d.mts","names":[],"sources":["../src/schema-codegen.ts"],"mappings":";;AAIA;;;iBAAgB,yBAAA,CAAA"}
@@ -1,4 +1,4 @@
1
- function t(){return`export const toolkitAuditLogs = pgTable('toolkit_audit_logs', {
1
+ function e(){return`export const toolkitAuditLogs = pgTable('toolkit_audit_logs', {
2
2
  id: uuid('id').primaryKey().defaultRandom(),
3
3
  action: varchar('action', { length: 100 }).notNull(),
4
4
  entityType: varchar('entity_type', { length: 100 }),
@@ -14,4 +14,5 @@ function t(){return`export const toolkitAuditLogs = pgTable('toolkit_audit_logs'
14
14
  actionCreatedAtIdx: index('audit_action_created_at_idx').on(table.action, table.createdAt),
15
15
  createdAtIdx: index('audit_created_at_idx').on(table.createdAt),
16
16
  entityIdIdx: index('audit_entity_id_idx').on(table.entityId),
17
- }))`}export{t as a};
17
+ }))`}export{e as generateLoggingSchemaCode};
18
+ //# sourceMappingURL=schema-codegen.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-codegen.mjs","names":[],"sources":["../src/schema-codegen.ts"],"sourcesContent":["/**\n * Returns Drizzle table definition code as a string for logging plugin tables.\n * Used by the CLI generate command to inline into generated/schema.ts.\n */\nexport function generateLoggingSchemaCode(): string {\n return `export const toolkitAuditLogs = pgTable('toolkit_audit_logs', {\n id: uuid('id').primaryKey().defaultRandom(),\n action: varchar('action', { length: 100 }).notNull(),\n entityType: varchar('entity_type', { length: 100 }),\n entityId: varchar('entity_id', { length: 255 }),\n userId: varchar('user_id', { length: 255 }),\n userName: varchar('user_name', { length: 255 }),\n changes: jsonb('changes'),\n metadata: jsonb('metadata'),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => ({\n entityTypeCreatedAtIdx: index('audit_entity_type_created_at_idx').on(table.entityType, table.createdAt),\n userIdCreatedAtIdx: index('audit_user_id_created_at_idx').on(table.userId, table.createdAt),\n actionCreatedAtIdx: index('audit_action_created_at_idx').on(table.action, table.createdAt),\n createdAtIdx: index('audit_created_at_idx').on(table.createdAt),\n entityIdIdx: index('audit_entity_id_idx').on(table.entityId),\n}))`\n}\n"],"mappings":"AAIA,SAAgB,GAAoC,CAClD,MAAO"}
@@ -0,0 +1,180 @@
1
+ import * as _$drizzle_orm_pg_core0 from "drizzle-orm/pg-core";
2
+
3
+ //#region src/schema.d.ts
4
+ declare const toolkitAuditLogs: _$drizzle_orm_pg_core0.PgTableWithColumns<{
5
+ name: "toolkit_audit_logs";
6
+ schema: undefined;
7
+ columns: {
8
+ id: _$drizzle_orm_pg_core0.PgColumn<{
9
+ name: "id";
10
+ tableName: "toolkit_audit_logs";
11
+ dataType: "string";
12
+ columnType: "PgUUID";
13
+ data: string;
14
+ driverParam: string;
15
+ notNull: true;
16
+ hasDefault: true;
17
+ isPrimaryKey: true;
18
+ isAutoincrement: false;
19
+ hasRuntimeDefault: false;
20
+ enumValues: undefined;
21
+ baseColumn: never;
22
+ identity: undefined;
23
+ generated: undefined;
24
+ }, {}, {}>;
25
+ action: _$drizzle_orm_pg_core0.PgColumn<{
26
+ name: "action";
27
+ tableName: "toolkit_audit_logs";
28
+ dataType: "string";
29
+ columnType: "PgVarchar";
30
+ data: string;
31
+ driverParam: string;
32
+ notNull: true;
33
+ hasDefault: false;
34
+ isPrimaryKey: false;
35
+ isAutoincrement: false;
36
+ hasRuntimeDefault: false;
37
+ enumValues: [string, ...string[]];
38
+ baseColumn: never;
39
+ identity: undefined;
40
+ generated: undefined;
41
+ }, {}, {
42
+ length: 100;
43
+ }>;
44
+ entityType: _$drizzle_orm_pg_core0.PgColumn<{
45
+ name: "entity_type";
46
+ tableName: "toolkit_audit_logs";
47
+ dataType: "string";
48
+ columnType: "PgVarchar";
49
+ data: string;
50
+ driverParam: string;
51
+ notNull: false;
52
+ hasDefault: false;
53
+ isPrimaryKey: false;
54
+ isAutoincrement: false;
55
+ hasRuntimeDefault: false;
56
+ enumValues: [string, ...string[]];
57
+ baseColumn: never;
58
+ identity: undefined;
59
+ generated: undefined;
60
+ }, {}, {
61
+ length: 100;
62
+ }>;
63
+ entityId: _$drizzle_orm_pg_core0.PgColumn<{
64
+ name: "entity_id";
65
+ tableName: "toolkit_audit_logs";
66
+ dataType: "string";
67
+ columnType: "PgVarchar";
68
+ data: string;
69
+ driverParam: string;
70
+ notNull: false;
71
+ hasDefault: false;
72
+ isPrimaryKey: false;
73
+ isAutoincrement: false;
74
+ hasRuntimeDefault: false;
75
+ enumValues: [string, ...string[]];
76
+ baseColumn: never;
77
+ identity: undefined;
78
+ generated: undefined;
79
+ }, {}, {
80
+ length: 255;
81
+ }>;
82
+ userId: _$drizzle_orm_pg_core0.PgColumn<{
83
+ name: "user_id";
84
+ tableName: "toolkit_audit_logs";
85
+ dataType: "string";
86
+ columnType: "PgVarchar";
87
+ data: string;
88
+ driverParam: string;
89
+ notNull: false;
90
+ hasDefault: false;
91
+ isPrimaryKey: false;
92
+ isAutoincrement: false;
93
+ hasRuntimeDefault: false;
94
+ enumValues: [string, ...string[]];
95
+ baseColumn: never;
96
+ identity: undefined;
97
+ generated: undefined;
98
+ }, {}, {
99
+ length: 255;
100
+ }>;
101
+ userName: _$drizzle_orm_pg_core0.PgColumn<{
102
+ name: "user_name";
103
+ tableName: "toolkit_audit_logs";
104
+ dataType: "string";
105
+ columnType: "PgVarchar";
106
+ data: string;
107
+ driverParam: string;
108
+ notNull: false;
109
+ hasDefault: false;
110
+ isPrimaryKey: false;
111
+ isAutoincrement: false;
112
+ hasRuntimeDefault: false;
113
+ enumValues: [string, ...string[]];
114
+ baseColumn: never;
115
+ identity: undefined;
116
+ generated: undefined;
117
+ }, {}, {
118
+ length: 255;
119
+ }>;
120
+ changes: _$drizzle_orm_pg_core0.PgColumn<{
121
+ name: "changes";
122
+ tableName: "toolkit_audit_logs";
123
+ dataType: "json";
124
+ columnType: "PgJsonb";
125
+ data: Record<string, unknown>;
126
+ driverParam: unknown;
127
+ notNull: false;
128
+ hasDefault: false;
129
+ isPrimaryKey: false;
130
+ isAutoincrement: false;
131
+ hasRuntimeDefault: false;
132
+ enumValues: undefined;
133
+ baseColumn: never;
134
+ identity: undefined;
135
+ generated: undefined;
136
+ }, {}, {
137
+ $type: Record<string, unknown>;
138
+ }>;
139
+ metadata: _$drizzle_orm_pg_core0.PgColumn<{
140
+ name: "metadata";
141
+ tableName: "toolkit_audit_logs";
142
+ dataType: "json";
143
+ columnType: "PgJsonb";
144
+ data: Record<string, unknown>;
145
+ driverParam: unknown;
146
+ notNull: false;
147
+ hasDefault: false;
148
+ isPrimaryKey: false;
149
+ isAutoincrement: false;
150
+ hasRuntimeDefault: false;
151
+ enumValues: undefined;
152
+ baseColumn: never;
153
+ identity: undefined;
154
+ generated: undefined;
155
+ }, {}, {
156
+ $type: Record<string, unknown>;
157
+ }>;
158
+ createdAt: _$drizzle_orm_pg_core0.PgColumn<{
159
+ name: "created_at";
160
+ tableName: "toolkit_audit_logs";
161
+ dataType: "date";
162
+ columnType: "PgTimestamp";
163
+ data: Date;
164
+ driverParam: string;
165
+ notNull: true;
166
+ hasDefault: true;
167
+ isPrimaryKey: false;
168
+ isAutoincrement: false;
169
+ hasRuntimeDefault: false;
170
+ enumValues: undefined;
171
+ baseColumn: never;
172
+ identity: undefined;
173
+ generated: undefined;
174
+ }, {}, {}>;
175
+ };
176
+ dialect: "pg";
177
+ }>;
178
+ //#endregion
179
+ export { toolkitAuditLogs };
180
+ //# sourceMappingURL=schema.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.mts","names":[],"sources":["../src/schema.ts"],"mappings":";;;cAEa,gBAAA,yBAAgB,kBAAA;;;;QAuB5B,sBAAA,CAAA,QAAA"}
@@ -0,0 +1,2 @@
1
+ import{index as e,jsonb as t,pgTable as n,timestamp as r,uuid as i,varchar as a}from"drizzle-orm/pg-core";const o=n(`toolkit_audit_logs`,{id:i(`id`).primaryKey().defaultRandom(),action:a(`action`,{length:100}).notNull(),entityType:a(`entity_type`,{length:100}),entityId:a(`entity_id`,{length:255}),userId:a(`user_id`,{length:255}),userName:a(`user_name`,{length:255}),changes:t(`changes`).$type(),metadata:t(`metadata`).$type(),createdAt:r(`created_at`,{withTimezone:!0}).notNull().defaultNow()},t=>({entityTypeCreatedAtIdx:e(`audit_entity_type_created_at_idx`).on(t.entityType,t.createdAt),userIdCreatedAtIdx:e(`audit_user_id_created_at_idx`).on(t.userId,t.createdAt),actionCreatedAtIdx:e(`audit_action_created_at_idx`).on(t.action,t.createdAt),createdAtIdx:e(`audit_created_at_idx`).on(t.createdAt),entityIdIdx:e(`audit_entity_id_idx`).on(t.entityId)}));export{o as toolkitAuditLogs};
2
+ //# sourceMappingURL=schema.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.mjs","names":[],"sources":["../src/schema.ts"],"sourcesContent":["import { index, jsonb, pgTable, timestamp, uuid, varchar } from 'drizzle-orm/pg-core'\n\nexport const toolkitAuditLogs = pgTable(\n 'toolkit_audit_logs',\n {\n id: uuid('id').primaryKey().defaultRandom(),\n action: varchar('action', { length: 100 }).notNull(),\n entityType: varchar('entity_type', { length: 100 }),\n entityId: varchar('entity_id', { length: 255 }),\n userId: varchar('user_id', { length: 255 }),\n userName: varchar('user_name', { length: 255 }),\n changes: jsonb('changes').$type<Record<string, unknown>>(),\n metadata: jsonb('metadata').$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n },\n (table) => ({\n entityTypeCreatedAtIdx: index('audit_entity_type_created_at_idx').on(\n table.entityType,\n table.createdAt,\n ),\n userIdCreatedAtIdx: index('audit_user_id_created_at_idx').on(table.userId, table.createdAt),\n actionCreatedAtIdx: index('audit_action_created_at_idx').on(table.action, table.createdAt),\n createdAtIdx: index('audit_created_at_idx').on(table.createdAt),\n entityIdIdx: index('audit_entity_id_idx').on(table.entityId),\n }),\n)\n"],"mappings":"0GAEA,MAAa,EAAmB,EAC9B,qBACA,CACE,GAAI,EAAK,KAAK,CAAC,YAAY,CAAC,eAAe,CAC3C,OAAQ,EAAQ,SAAU,CAAE,OAAQ,IAAK,CAAC,CAAC,SAAS,CACpD,WAAY,EAAQ,cAAe,CAAE,OAAQ,IAAK,CAAC,CACnD,SAAU,EAAQ,YAAa,CAAE,OAAQ,IAAK,CAAC,CAC/C,OAAQ,EAAQ,UAAW,CAAE,OAAQ,IAAK,CAAC,CAC3C,SAAU,EAAQ,YAAa,CAAE,OAAQ,IAAK,CAAC,CAC/C,QAAS,EAAM,UAAU,CAAC,OAAgC,CAC1D,SAAU,EAAM,WAAW,CAAC,OAAgC,CAC5D,UAAW,EAAU,aAAc,CAAE,aAAc,GAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAClF,CACA,IAAW,CACV,uBAAwB,EAAM,mCAAmC,CAAC,GAChE,EAAM,WACN,EAAM,UACP,CACD,mBAAoB,EAAM,+BAA+B,CAAC,GAAG,EAAM,OAAQ,EAAM,UAAU,CAC3F,mBAAoB,EAAM,8BAA8B,CAAC,GAAG,EAAM,OAAQ,EAAM,UAAU,CAC1F,aAAc,EAAM,uBAAuB,CAAC,GAAG,EAAM,UAAU,CAC/D,YAAa,EAAM,sBAAsB,CAAC,GAAG,EAAM,SAAS,CAC7D,EACF"}
package/package.json CHANGED
@@ -1,24 +1,24 @@
1
1
  {
2
2
  "name": "@murumets-ee/logging",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "license": "Elastic-2.0",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": {
8
- "types": "./dist/index.d.ts",
9
- "import": "./dist/index.js"
8
+ "types": "./dist/index.d.mts",
9
+ "import": "./dist/index.mjs"
10
10
  },
11
11
  "./schema": {
12
- "types": "./dist/schema.d.ts",
13
- "import": "./dist/schema.js"
12
+ "types": "./dist/schema.d.mts",
13
+ "import": "./dist/schema.mjs"
14
14
  },
15
15
  "./admin": {
16
- "types": "./dist/admin.d.ts",
17
- "import": "./dist/admin.js"
16
+ "types": "./dist/admin.d.mts",
17
+ "import": "./dist/admin.mjs"
18
18
  },
19
19
  "./plugin": {
20
- "types": "./dist/plugin.d.ts",
21
- "import": "./dist/plugin.js"
20
+ "types": "./dist/plugin.d.mts",
21
+ "import": "./dist/plugin.mjs"
22
22
  }
23
23
  },
24
24
  "files": [
@@ -30,13 +30,13 @@
30
30
  "zod": ">=3.0.0"
31
31
  },
32
32
  "devDependencies": {
33
- "tsup": "^8.3.5",
33
+ "tsdown": "^0.21.7",
34
34
  "typescript": "^5.7.2",
35
35
  "vitest": "^2.1.8"
36
36
  },
37
37
  "scripts": {
38
- "build": "tsup",
39
- "dev": "tsup --watch",
38
+ "build": "tsdown",
39
+ "dev": "tsdown --watch",
40
40
  "test": "vitest"
41
41
  }
42
42
  }
package/dist/admin.js DELETED
@@ -1 +0,0 @@
1
- import{z as e}from"zod";var d=/^[a-zA-Z0-9_-]{1,255}$/,f=e.object({action:e.string().max(100).optional(),entityType:e.string().max(100).optional(),entityId:e.string().regex(d,"Invalid ID format").optional(),userId:e.string().regex(d,"Invalid user ID format").optional(),dateFrom:e.string().datetime({offset:!0,message:"Invalid ISO date"}).optional(),dateTo:e.string().datetime({offset:!0,message:"Invalid ISO date"}).optional(),search:e.string().max(200).optional(),limit:e.coerce.number().min(1).max(100).default(50),offset:e.coerce.number().min(0).default(0),sortField:e.enum(["createdAt","action","entityType"]).default("createdAt"),sortDirection:e.enum(["asc","desc"]).default("desc")});function a(r,i=200){return new Response(JSON.stringify(r),{status:i,headers:{"Content-Type":"application/json"}})}function u(r,i){return a({error:r},i)}function p(r){return{prefix:"logs",resource:"audit-logs",actions:["view"],handlers:{GET:async(i,{segments:o})=>{let s=r();if(o.length===1&&o[0]==="filters"){let[n,g]=await Promise.all([s.getDistinctEntityTypes(),s.getDistinctActions()]);return a({entityTypes:n,actions:g})}if(o.length===1&&o[0]!=="filters"){let n=await s.findById(o[0]);return n?a(n):u("Audit log entry not found",404)}let c=new URL(i.url),l=Object.fromEntries(c.searchParams),t=f.safeParse(l);if(!t.success)return u(`Invalid query params: ${t.error.issues.map(n=>n.message).join(", ")}`,400);let m=await s.query({...t.data,dateFrom:t.data.dateFrom?new Date(t.data.dateFrom):void 0,dateTo:t.data.dateTo?new Date(t.data.dateTo):void 0});return a(m)}}}}export{p as logRoutes};
@@ -1 +0,0 @@
1
- import{index as e,jsonb as i,pgTable as n,timestamp as a,uuid as r,varchar as d}from"drizzle-orm/pg-core";var _=n("toolkit_audit_logs",{id:r("id").primaryKey().defaultRandom(),action:d("action",{length:100}).notNull(),entityType:d("entity_type",{length:100}),entityId:d("entity_id",{length:255}),userId:d("user_id",{length:255}),userName:d("user_name",{length:255}),changes:i("changes").$type(),metadata:i("metadata").$type(),createdAt:a("created_at",{withTimezone:!0}).notNull().defaultNow()},t=>({entityTypeCreatedAtIdx:e("audit_entity_type_created_at_idx").on(t.entityType,t.createdAt),userIdCreatedAtIdx:e("audit_user_id_created_at_idx").on(t.userId,t.createdAt),actionCreatedAtIdx:e("audit_action_created_at_idx").on(t.action,t.createdAt),createdAtIdx:e("audit_created_at_idx").on(t.createdAt),entityIdIdx:e("audit_entity_id_idx").on(t.entityId)}));export{_ as a};
package/dist/index.d.ts DELETED
@@ -1,121 +0,0 @@
1
- import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
2
- import { Logger as Logger$1 } from 'pino';
3
- export { toolkitAuditLogs } from './schema.js';
4
- import 'drizzle-orm/pg-core';
5
-
6
- type Logger = Logger$1;
7
- interface LoggerConfig {
8
- name?: string;
9
- level?: string;
10
- redact?: string[];
11
- }
12
- /**
13
- * Create a logger instance
14
- * If no config provided, returns the root logger
15
- * If config provided, returns a child logger with the specified context
16
- */
17
- declare function createLogger(config?: LoggerConfig): Logger;
18
- /**
19
- * Create a child logger from an existing logger with additional context
20
- */
21
- declare function createChildLogger(parent: Logger, context: Record<string, unknown>): Logger;
22
-
23
- interface AuditEntry {
24
- action: string;
25
- entityType?: string;
26
- entityId?: string;
27
- userId?: string;
28
- userName?: string;
29
- changes?: Record<string, unknown>;
30
- metadata?: Record<string, unknown>;
31
- }
32
- interface AuditConfig {
33
- logger: Logger;
34
- dbWriter?: (entry: AuditEntry) => Promise<void>;
35
- }
36
- interface AuditLogger {
37
- log: (entry: AuditEntry) => Promise<void>;
38
- }
39
- /**
40
- * Create a dbWriter callback wired to AuditLogClient.
41
- *
42
- * Pass the returned function as `dbWriter` to `createAuditLogger`:
43
- * ```typescript
44
- * const auditLogger = createAuditLogger({
45
- * logger,
46
- * dbWriter: createAuditDbWriter(db),
47
- * })
48
- * ```
49
- */
50
- declare function createAuditDbWriter(db: PostgresJsDatabase): (entry: AuditEntry) => Promise<void>;
51
- /**
52
- * Create an audit logger
53
- *
54
- * Audit logs are written to stdout immediately (non-blocking).
55
- * Optionally, they can also be written to the database if dbWriter is provided.
56
- *
57
- * Database writes are fire-and-forget to avoid blocking the main operation.
58
- * If DB write fails, it's logged to stderr but doesn't throw.
59
- */
60
- declare function createAuditLogger(config: AuditConfig): AuditLogger;
61
-
62
- interface AuditLogQueryOptions {
63
- action?: string;
64
- entityType?: string;
65
- entityId?: string;
66
- userId?: string;
67
- dateFrom?: Date;
68
- dateTo?: Date;
69
- /** Free-text search across action, entityType, userName */
70
- search?: string;
71
- /** Default 50, max 100 */
72
- limit?: number;
73
- offset?: number;
74
- sortField?: 'createdAt' | 'action' | 'entityType';
75
- sortDirection?: 'asc' | 'desc';
76
- }
77
- interface AuditLogEntry {
78
- id: string;
79
- action: string;
80
- entityType: string | null;
81
- entityId: string | null;
82
- userId: string | null;
83
- userName: string | null;
84
- changes: Record<string, unknown> | null;
85
- metadata: Record<string, unknown> | null;
86
- createdAt: Date;
87
- }
88
- interface AuditLogListResult {
89
- items: AuditLogEntry[];
90
- total: number;
91
- }
92
- declare class AuditLogClient {
93
- private db;
94
- constructor(db: PostgresJsDatabase);
95
- /** Write a single audit log entry */
96
- write(entry: Omit<AuditLogEntry, 'id' | 'createdAt'>): Promise<void>;
97
- /** Query audit logs with filters and pagination */
98
- query(options?: AuditLogQueryOptions): Promise<AuditLogListResult>;
99
- /** Get a single audit log entry by ID */
100
- findById(id: string): Promise<AuditLogEntry | null>;
101
- /** Get distinct entity types present in the audit log */
102
- getDistinctEntityTypes(): Promise<string[]>;
103
- /** Get distinct actions present in the audit log */
104
- getDistinctActions(): Promise<string[]>;
105
- private buildConditions;
106
- private buildOrderBy;
107
- }
108
-
109
- interface RequestContext {
110
- requestId?: string;
111
- userId?: string;
112
- teamId?: string;
113
- locale?: string;
114
- }
115
- /**
116
- * Bind request context to a logger
117
- * Returns a child logger with the context automatically included in all log entries
118
- */
119
- declare function bindRequestContext(logger: Logger, context: RequestContext): Logger;
120
-
121
- export { type AuditConfig, type AuditEntry, AuditLogClient, type AuditLogEntry, type AuditLogListResult, type AuditLogQueryOptions, type AuditLogger, type Logger, type LoggerConfig, type RequestContext, bindRequestContext, createAuditDbWriter, createAuditLogger, createChildLogger, createLogger };
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- import{a as r}from"./chunk-PQXD7TOP.js";import{and as f,asc as a,count as L,desc as A,eq as o,gte as h,ilike as d,isNotNull as I,lte as T,or as w}from"drizzle-orm";var b=100,x=50,s=class{constructor(t){this.db=t}async write(t){await this.db.insert(r).values({action:t.action,entityType:t.entityType,entityId:t.entityId,userId:t.userId,userName:t.userName,changes:t.changes,metadata:t.metadata})}async query(t={}){let e=Math.min(Math.max(t.limit??x,1),b),n=Math.max(t.offset??0,0),g=this.buildConditions(t),c=g.length>0?f(...g):void 0,y=this.buildOrderBy(t.sortField,t.sortDirection),[m,p]=await Promise.all([this.db.select().from(r).where(c).orderBy(y).limit(e).offset(n),this.db.select({count:L()}).from(r).where(c)]);return{items:m,total:p[0]?.count??0}}async findById(t){return(await this.db.select().from(r).where(o(r.id,t)).limit(1))[0]??null}async getDistinctEntityTypes(){return(await this.db.selectDistinct({entityType:r.entityType}).from(r).where(I(r.entityType)).orderBy(a(r.entityType))).map(e=>e.entityType).filter(Boolean)}async getDistinctActions(){return(await this.db.selectDistinct({action:r.action}).from(r).orderBy(a(r.action))).map(e=>e.action)}buildConditions(t){let e=[];if(t.action&&e.push(o(r.action,t.action)),t.entityType&&e.push(o(r.entityType,t.entityType)),t.entityId&&e.push(o(r.entityId,t.entityId)),t.userId&&e.push(o(r.userId,t.userId)),t.dateFrom&&e.push(h(r.createdAt,t.dateFrom)),t.dateTo&&e.push(T(r.createdAt,t.dateTo)),t.search){let n=`%${t.search}%`;e.push(w(d(r.action,n),d(r.entityType,n),d(r.userName,n)))}return e}buildOrderBy(t,e){let n=e==="asc"?a:A;switch(t){case"action":return n(r.action);case"entityType":return n(r.entityType);default:return n(r.createdAt)}}};function E(i){let t=new s(i);return e=>t.write({action:e.action,entityType:e.entityType??null,entityId:e.entityId??null,userId:e.userId??null,userName:e.userName??null,changes:e.changes??null,metadata:e.metadata??null})}function D(i){return{log:async t=>{i.logger.info({audit:!0,action:t.action,entityType:t.entityType,entityId:t.entityId,userId:t.userId,userName:t.userName,changes:t.changes,metadata:t.metadata},`Audit: ${t.action}`),i.dbWriter&&i.dbWriter(t).catch(e=>{i.logger.error({err:e,auditEntry:t},"Failed to write audit log to database")})}}}function v(i,t){return i.child(t)}import u from"pino";var l=u({level:process.env.LOG_LEVEL||"info",formatters:{level:i=>({level:i})},timestamp:!1,serializers:{err:u.stdSerializers.err,error:u.stdSerializers.err},redact:{paths:["password","token","secret","apiKey","accessToken","refreshToken"],censor:"[REDACTED]"}});function C(i){if(!i)return l;let t={};i.name&&(t.name=i.name);let e={};return i.level&&(e.level=i.level),l.child(t,e)}function R(i,t){return i.child(t)}export{s as AuditLogClient,v as bindRequestContext,E as createAuditDbWriter,D as createAuditLogger,R as createChildLogger,C as createLogger,r as toolkitAuditLogs};
package/dist/plugin.js DELETED
@@ -1 +0,0 @@
1
- import{a as e}from"./chunk-3M2SQ6QE.js";function n(){return{name:"@murumets-ee/logging",schemaCode:e()}}export{n as logging};
@@ -1 +0,0 @@
1
- import{a}from"./chunk-3M2SQ6QE.js";export{a as generateLoggingSchemaCode};
package/dist/schema.d.ts DELETED
@@ -1,178 +0,0 @@
1
- import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
2
-
3
- declare const toolkitAuditLogs: drizzle_orm_pg_core.PgTableWithColumns<{
4
- name: "toolkit_audit_logs";
5
- schema: undefined;
6
- columns: {
7
- id: drizzle_orm_pg_core.PgColumn<{
8
- name: "id";
9
- tableName: "toolkit_audit_logs";
10
- dataType: "string";
11
- columnType: "PgUUID";
12
- data: string;
13
- driverParam: string;
14
- notNull: true;
15
- hasDefault: true;
16
- isPrimaryKey: true;
17
- isAutoincrement: false;
18
- hasRuntimeDefault: false;
19
- enumValues: undefined;
20
- baseColumn: never;
21
- identity: undefined;
22
- generated: undefined;
23
- }, {}, {}>;
24
- action: drizzle_orm_pg_core.PgColumn<{
25
- name: "action";
26
- tableName: "toolkit_audit_logs";
27
- dataType: "string";
28
- columnType: "PgVarchar";
29
- data: string;
30
- driverParam: string;
31
- notNull: true;
32
- hasDefault: false;
33
- isPrimaryKey: false;
34
- isAutoincrement: false;
35
- hasRuntimeDefault: false;
36
- enumValues: [string, ...string[]];
37
- baseColumn: never;
38
- identity: undefined;
39
- generated: undefined;
40
- }, {}, {
41
- length: 100;
42
- }>;
43
- entityType: drizzle_orm_pg_core.PgColumn<{
44
- name: "entity_type";
45
- tableName: "toolkit_audit_logs";
46
- dataType: "string";
47
- columnType: "PgVarchar";
48
- data: string;
49
- driverParam: string;
50
- notNull: false;
51
- hasDefault: false;
52
- isPrimaryKey: false;
53
- isAutoincrement: false;
54
- hasRuntimeDefault: false;
55
- enumValues: [string, ...string[]];
56
- baseColumn: never;
57
- identity: undefined;
58
- generated: undefined;
59
- }, {}, {
60
- length: 100;
61
- }>;
62
- entityId: drizzle_orm_pg_core.PgColumn<{
63
- name: "entity_id";
64
- tableName: "toolkit_audit_logs";
65
- dataType: "string";
66
- columnType: "PgVarchar";
67
- data: string;
68
- driverParam: string;
69
- notNull: false;
70
- hasDefault: false;
71
- isPrimaryKey: false;
72
- isAutoincrement: false;
73
- hasRuntimeDefault: false;
74
- enumValues: [string, ...string[]];
75
- baseColumn: never;
76
- identity: undefined;
77
- generated: undefined;
78
- }, {}, {
79
- length: 255;
80
- }>;
81
- userId: drizzle_orm_pg_core.PgColumn<{
82
- name: "user_id";
83
- tableName: "toolkit_audit_logs";
84
- dataType: "string";
85
- columnType: "PgVarchar";
86
- data: string;
87
- driverParam: string;
88
- notNull: false;
89
- hasDefault: false;
90
- isPrimaryKey: false;
91
- isAutoincrement: false;
92
- hasRuntimeDefault: false;
93
- enumValues: [string, ...string[]];
94
- baseColumn: never;
95
- identity: undefined;
96
- generated: undefined;
97
- }, {}, {
98
- length: 255;
99
- }>;
100
- userName: drizzle_orm_pg_core.PgColumn<{
101
- name: "user_name";
102
- tableName: "toolkit_audit_logs";
103
- dataType: "string";
104
- columnType: "PgVarchar";
105
- data: string;
106
- driverParam: string;
107
- notNull: false;
108
- hasDefault: false;
109
- isPrimaryKey: false;
110
- isAutoincrement: false;
111
- hasRuntimeDefault: false;
112
- enumValues: [string, ...string[]];
113
- baseColumn: never;
114
- identity: undefined;
115
- generated: undefined;
116
- }, {}, {
117
- length: 255;
118
- }>;
119
- changes: drizzle_orm_pg_core.PgColumn<{
120
- name: "changes";
121
- tableName: "toolkit_audit_logs";
122
- dataType: "json";
123
- columnType: "PgJsonb";
124
- data: Record<string, unknown>;
125
- driverParam: unknown;
126
- notNull: false;
127
- hasDefault: false;
128
- isPrimaryKey: false;
129
- isAutoincrement: false;
130
- hasRuntimeDefault: false;
131
- enumValues: undefined;
132
- baseColumn: never;
133
- identity: undefined;
134
- generated: undefined;
135
- }, {}, {
136
- $type: Record<string, unknown>;
137
- }>;
138
- metadata: drizzle_orm_pg_core.PgColumn<{
139
- name: "metadata";
140
- tableName: "toolkit_audit_logs";
141
- dataType: "json";
142
- columnType: "PgJsonb";
143
- data: Record<string, unknown>;
144
- driverParam: unknown;
145
- notNull: false;
146
- hasDefault: false;
147
- isPrimaryKey: false;
148
- isAutoincrement: false;
149
- hasRuntimeDefault: false;
150
- enumValues: undefined;
151
- baseColumn: never;
152
- identity: undefined;
153
- generated: undefined;
154
- }, {}, {
155
- $type: Record<string, unknown>;
156
- }>;
157
- createdAt: drizzle_orm_pg_core.PgColumn<{
158
- name: "created_at";
159
- tableName: "toolkit_audit_logs";
160
- dataType: "date";
161
- columnType: "PgTimestamp";
162
- data: Date;
163
- driverParam: string;
164
- notNull: true;
165
- hasDefault: true;
166
- isPrimaryKey: false;
167
- isAutoincrement: false;
168
- hasRuntimeDefault: false;
169
- enumValues: undefined;
170
- baseColumn: never;
171
- identity: undefined;
172
- generated: undefined;
173
- }, {}, {}>;
174
- };
175
- dialect: "pg";
176
- }>;
177
-
178
- export { toolkitAuditLogs };
package/dist/schema.js DELETED
@@ -1 +0,0 @@
1
- import{a}from"./chunk-PQXD7TOP.js";export{a as toolkitAuditLogs};