@logtape/windows-eventlog 1.4.0-dev.428 → 1.4.0-dev.438

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/README.md CHANGED
@@ -100,6 +100,34 @@ await configure({
100
100
  > This is the standard location for application events and does not require
101
101
  > administrator privileges.
102
102
 
103
+ > [!NOTE]
104
+ > The event ID is used to lookup a string resource from a dynamic link library.
105
+ > If you do not register a library, “the system cannot open the file” will be
106
+ > printed as description in the Event Log regardless of the parameters passed.
107
+
108
+ If you want to log only the text supplied by the formatter into the event log,
109
+ you can register the system generic string library using this command:
110
+
111
+ ~~~~ powershell
112
+ New-Item `
113
+ -Path HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Application `
114
+ -Name MyApplication `
115
+ | New-ItemProperty `
116
+ -Name EventMessageFile `
117
+ -PropertyType ExpandString `
118
+ -Value %SystemRoot%\System32\netmsg.dll
119
+ ~~~~
120
+
121
+ Replacing `MyApplication` with the name you passed as `sourceName` to the sink,
122
+ and use the `NELOG_OEM_Code` (the default) as the event ID. Note that there is
123
+ no quotation marks around the data part of that command, as this trips up the
124
+ escaping of the percentage signs.
125
+
126
+ > [!NOTE]
127
+ > Event Viewer will cache the event message file when it is open. If you change
128
+ > the entry in the registry, it will not be updated until Event Viewer is
129
+ > restarted.
130
+
103
131
 
104
132
  Runtime support
105
133
  ---------------
package/dist/ffi.bun.cjs CHANGED
@@ -6,23 +6,21 @@ const bun_ffi = require_rolldown_runtime.__toESM(require("bun:ffi"));
6
6
  /**
7
7
  * Bun FFI implementation for Windows Event Log API
8
8
  */
9
- var WindowsEventLogFFI = class {
9
+ var WindowsEventLogBunFFI = class {
10
10
  eventSource = null;
11
11
  lib = null;
12
- sourceName;
12
+ sourceName = "";
13
13
  initialized = false;
14
14
  metaLogger = (0, __logtape_logtape.getLogger)([
15
15
  "logtape",
16
16
  "meta",
17
17
  "windows-eventlog"
18
18
  ]);
19
- constructor(sourceName) {
20
- this.sourceName = sourceName;
21
- }
22
19
  /**
23
20
  * Initialize the FFI bindings and register event source
24
21
  */
25
- initialize() {
22
+ initialize(sourceName) {
23
+ this.sourceName = sourceName;
26
24
  if (this.initialized) return;
27
25
  try {
28
26
  this.lib = (0, bun_ffi.dlopen)("advapi32.dll", {
@@ -62,15 +60,17 @@ var WindowsEventLogFFI = class {
62
60
  /**
63
61
  * Write an event to Windows Event Log
64
62
  */
65
- writeEvent(eventType, eventId, message) {
63
+ writeEvent(eventType, eventId, params) {
66
64
  if (!this.initialized || !this.eventSource || !this.lib) return;
67
65
  try {
66
+ const ptrArray = new BigUint64Array(params.length + 1);
68
67
  const encoder = new TextEncoder();
69
- const messageBuffer = encoder.encode(message + "\0");
70
- const ptrArray = new BigUint64Array(2);
71
- ptrArray[0] = BigInt((0, bun_ffi.ptr)(messageBuffer));
72
- ptrArray[1] = 0n;
73
- const success = this.lib.symbols.ReportEventA(this.eventSource, eventType, 0, eventId, null, 1, 0, ptrArray, null);
68
+ for (let i = 0; i < params.length; i++) {
69
+ const paramBuffer = encoder.encode(params[i] + "\0");
70
+ ptrArray[i] = BigInt((0, bun_ffi.ptr)(paramBuffer));
71
+ }
72
+ ptrArray[params.length] = 0n;
73
+ const success = this.lib.symbols.ReportEventA(this.eventSource, eventType, 0, eventId, null, params.length, 0, ptrArray, null);
74
74
  if (!success) throw new Error(`ReportEventA returned false`);
75
75
  } catch (error) {
76
76
  throw error;
@@ -99,4 +99,4 @@ var WindowsEventLogFFI = class {
99
99
  };
100
100
 
101
101
  //#endregion
102
- exports.WindowsEventLogFFI = WindowsEventLogFFI;
102
+ exports.WindowsEventLogBunFFI = WindowsEventLogBunFFI;
package/dist/ffi.bun.js CHANGED
@@ -5,23 +5,21 @@ import { FFIType, dlopen, ptr } from "bun:ffi";
5
5
  /**
6
6
  * Bun FFI implementation for Windows Event Log API
7
7
  */
8
- var WindowsEventLogFFI = class {
8
+ var WindowsEventLogBunFFI = class {
9
9
  eventSource = null;
10
10
  lib = null;
11
- sourceName;
11
+ sourceName = "";
12
12
  initialized = false;
13
13
  metaLogger = getLogger([
14
14
  "logtape",
15
15
  "meta",
16
16
  "windows-eventlog"
17
17
  ]);
18
- constructor(sourceName) {
19
- this.sourceName = sourceName;
20
- }
21
18
  /**
22
19
  * Initialize the FFI bindings and register event source
23
20
  */
24
- initialize() {
21
+ initialize(sourceName) {
22
+ this.sourceName = sourceName;
25
23
  if (this.initialized) return;
26
24
  try {
27
25
  this.lib = dlopen("advapi32.dll", {
@@ -61,15 +59,17 @@ var WindowsEventLogFFI = class {
61
59
  /**
62
60
  * Write an event to Windows Event Log
63
61
  */
64
- writeEvent(eventType, eventId, message) {
62
+ writeEvent(eventType, eventId, params) {
65
63
  if (!this.initialized || !this.eventSource || !this.lib) return;
66
64
  try {
65
+ const ptrArray = new BigUint64Array(params.length + 1);
67
66
  const encoder = new TextEncoder();
68
- const messageBuffer = encoder.encode(message + "\0");
69
- const ptrArray = new BigUint64Array(2);
70
- ptrArray[0] = BigInt(ptr(messageBuffer));
71
- ptrArray[1] = 0n;
72
- const success = this.lib.symbols.ReportEventA(this.eventSource, eventType, 0, eventId, null, 1, 0, ptrArray, null);
67
+ for (let i = 0; i < params.length; i++) {
68
+ const paramBuffer = encoder.encode(params[i] + "\0");
69
+ ptrArray[i] = BigInt(ptr(paramBuffer));
70
+ }
71
+ ptrArray[params.length] = 0n;
72
+ const success = this.lib.symbols.ReportEventA(this.eventSource, eventType, 0, eventId, null, params.length, 0, ptrArray, null);
73
73
  if (!success) throw new Error(`ReportEventA returned false`);
74
74
  } catch (error) {
75
75
  throw error;
@@ -98,5 +98,5 @@ var WindowsEventLogFFI = class {
98
98
  };
99
99
 
100
100
  //#endregion
101
- export { WindowsEventLogFFI };
101
+ export { WindowsEventLogBunFFI };
102
102
  //# sourceMappingURL=ffi.bun.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ffi.bun.js","names":["sourceName: string","eventType: EventType","eventId: number","message: string"],"sources":["../src/ffi.bun.ts"],"sourcesContent":["import { getLogger } from \"@logtape/logtape\";\n// @ts-types=\"npm:@types/bun@^1.2.16\"\nimport { dlopen, FFIType, ptr } from \"bun:ffi\";\nimport type { EventType } from \"./types.ts\";\n\n/**\n * Bun FFI implementation for Windows Event Log API\n */\nexport class WindowsEventLogFFI {\n private eventSource: number | null = null;\n // deno-lint-ignore no-explicit-any\n private lib: any = null;\n private sourceName: string;\n private initialized = false;\n private metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n constructor(sourceName: string) {\n this.sourceName = sourceName;\n }\n\n /**\n * Initialize the FFI bindings and register event source\n */\n initialize(): void {\n if (this.initialized) return;\n\n try {\n // Load advapi32.dll using Bun FFI\n this.lib = dlopen(\"advapi32.dll\", {\n RegisterEventSourceA: {\n args: [FFIType.ptr, FFIType.cstring],\n returns: FFIType.ptr,\n },\n ReportEventA: {\n args: [\n FFIType.ptr, // hEventLog\n FFIType.u16, // wType\n FFIType.u16, // wCategory\n FFIType.u32, // dwEventID\n FFIType.ptr, // lpUserSid\n FFIType.u16, // wNumStrings\n FFIType.u32, // dwDataSize\n FFIType.ptr, // lpStrings - pointer to array of string pointers\n FFIType.ptr, // lpRawData\n ],\n returns: FFIType.bool,\n },\n DeregisterEventSource: {\n args: [FFIType.ptr],\n returns: FFIType.bool,\n },\n });\n\n // Register event source using cstring\n // Create a buffer for the source name\n const encoder = new TextEncoder();\n const sourceNameBuffer = encoder.encode(this.sourceName + \"\\0\");\n\n const result = this.lib.symbols.RegisterEventSourceA(\n null,\n sourceNameBuffer,\n );\n this.eventSource = typeof result === \"number\" ? result : null;\n\n if (!this.eventSource || this.eventSource === 0) {\n throw new Error(\n `Failed to register event source: ${this.sourceName}`,\n );\n }\n\n this.initialized = true;\n } catch (error) {\n throw new Error(\n `Failed to initialize Windows Event Log FFI: ${error}`,\n );\n }\n }\n\n /**\n * Write an event to Windows Event Log\n */\n writeEvent(eventType: EventType, eventId: number, message: string): void {\n if (!this.initialized || !this.eventSource || !this.lib) {\n return;\n }\n\n try {\n // Use string array approach which works with Bun FFI\n const encoder = new TextEncoder();\n const messageBuffer = encoder.encode(message + \"\\0\");\n\n // Create pointer array for strings\n const ptrArray = new BigUint64Array(2);\n ptrArray[0] = BigInt(ptr(messageBuffer));\n ptrArray[1] = 0n; // null terminator\n\n const success = this.lib.symbols.ReportEventA(\n this.eventSource,\n eventType,\n 0, // category\n eventId,\n null, // user SID (null)\n 1, // number of strings\n 0, // data size\n ptrArray, // pointer to array of string pointers\n null, // raw data (null)\n );\n\n if (!success) {\n throw new Error(`ReportEventA returned false`);\n }\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Clean up resources\n */\n dispose(): void {\n if (this.initialized && this.eventSource && this.lib) {\n try {\n this.lib.symbols.DeregisterEventSource(this.eventSource);\n } catch (error) {\n this.metaLogger.error(\n \"Failed to deregister event source during cleanup: {error}\",\n { error },\n );\n }\n this.eventSource = null;\n this.initialized = false;\n\n try {\n this.lib.close();\n } catch (error) {\n this.metaLogger.error(\n \"Failed to close FFI library during cleanup: {error}\",\n { error },\n );\n }\n this.lib = null;\n }\n }\n}\n\n// cSpell: ignore cstring\n"],"mappings":";;;;;;;AAQA,IAAa,qBAAb,MAAgC;CAC9B,AAAQ,cAA6B;CAErC,AAAQ,MAAW;CACnB,AAAQ;CACR,AAAQ,cAAc;CACtB,AAAQ,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;CAEvE,YAAYA,YAAoB;AAC9B,OAAK,aAAa;CACnB;;;;CAKD,aAAmB;AACjB,MAAI,KAAK,YAAa;AAEtB,MAAI;AAEF,QAAK,MAAM,OAAO,gBAAgB;IAChC,sBAAsB;KACpB,MAAM,CAAC,QAAQ,KAAK,QAAQ,OAAQ;KACpC,SAAS,QAAQ;IAClB;IACD,cAAc;KACZ,MAAM;MACJ,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;KACT;KACD,SAAS,QAAQ;IAClB;IACD,uBAAuB;KACrB,MAAM,CAAC,QAAQ,GAAI;KACnB,SAAS,QAAQ;IAClB;GACF,EAAC;GAIF,MAAM,UAAU,IAAI;GACpB,MAAM,mBAAmB,QAAQ,OAAO,KAAK,aAAa,KAAK;GAE/D,MAAM,SAAS,KAAK,IAAI,QAAQ,qBAC9B,MACA,iBACD;AACD,QAAK,qBAAqB,WAAW,WAAW,SAAS;AAEzD,QAAK,KAAK,eAAe,KAAK,gBAAgB,EAC5C,OAAM,IAAI,OACP,mCAAmC,KAAK,WAAW;AAIxD,QAAK,cAAc;EACpB,SAAQ,OAAO;AACd,SAAM,IAAI,OACP,8CAA8C,MAAM;EAExD;CACF;;;;CAKD,WAAWC,WAAsBC,SAAiBC,SAAuB;AACvE,OAAK,KAAK,gBAAgB,KAAK,gBAAgB,KAAK,IAClD;AAGF,MAAI;GAEF,MAAM,UAAU,IAAI;GACpB,MAAM,gBAAgB,QAAQ,OAAO,UAAU,KAAK;GAGpD,MAAM,WAAW,IAAI,eAAe;AACpC,YAAS,KAAK,OAAO,IAAI,cAAc,CAAC;AACxC,YAAS,KAAK;GAEd,MAAM,UAAU,KAAK,IAAI,QAAQ,aAC/B,KAAK,aACL,WACA,GACA,SACA,MACA,GACA,GACA,UACA,KACD;AAED,QAAK,QACH,OAAM,IAAI,OAAO;EAEpB,SAAQ,OAAO;AACd,SAAM;EACP;CACF;;;;CAKD,UAAgB;AACd,MAAI,KAAK,eAAe,KAAK,eAAe,KAAK,KAAK;AACpD,OAAI;AACF,SAAK,IAAI,QAAQ,sBAAsB,KAAK,YAAY;GACzD,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,6DACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,cAAc;AACnB,QAAK,cAAc;AAEnB,OAAI;AACF,SAAK,IAAI,OAAO;GACjB,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,uDACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,MAAM;EACZ;CACF;AACF"}
1
+ {"version":3,"file":"ffi.bun.js","names":["sourceName: string","eventType: EventType","eventId: number","params: string[]"],"sources":["../src/ffi.bun.ts"],"sourcesContent":["import { getLogger } from \"@logtape/logtape\";\n// @ts-types=\"npm:@types/bun@^1.2.16\"\nimport { dlopen, FFIType, ptr } from \"bun:ffi\";\nimport type { WindowsEventLogFFI } from \"./ffi.ts\";\nimport type { EventType } from \"./types.ts\";\n\n/**\n * Bun FFI implementation for Windows Event Log API\n */\nexport class WindowsEventLogBunFFI implements WindowsEventLogFFI {\n private eventSource: number | null = null;\n // deno-lint-ignore no-explicit-any\n private lib: any = null;\n private sourceName: string = \"\"; // immediately overwritten in initialize\n private initialized = false;\n private metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n /**\n * Initialize the FFI bindings and register event source\n */\n initialize(sourceName: string): void {\n this.sourceName = sourceName;\n if (this.initialized) return;\n\n try {\n // Load advapi32.dll using Bun FFI\n this.lib = dlopen(\"advapi32.dll\", {\n RegisterEventSourceA: {\n args: [FFIType.ptr, FFIType.cstring],\n returns: FFIType.ptr,\n },\n ReportEventA: {\n args: [\n FFIType.ptr, // hEventLog\n FFIType.u16, // wType\n FFIType.u16, // wCategory\n FFIType.u32, // dwEventID\n FFIType.ptr, // lpUserSid\n FFIType.u16, // wNumStrings\n FFIType.u32, // dwDataSize\n FFIType.ptr, // lpStrings - pointer to array of string pointers\n FFIType.ptr, // lpRawData\n ],\n returns: FFIType.bool,\n },\n DeregisterEventSource: {\n args: [FFIType.ptr],\n returns: FFIType.bool,\n },\n });\n\n // Register event source using cstring\n // Create a buffer for the source name\n const encoder = new TextEncoder();\n const sourceNameBuffer = encoder.encode(this.sourceName + \"\\0\");\n\n const result = this.lib.symbols.RegisterEventSourceA(\n null,\n sourceNameBuffer,\n );\n this.eventSource = typeof result === \"number\" ? result : null;\n\n if (!this.eventSource || this.eventSource === 0) {\n throw new Error(\n `Failed to register event source: ${this.sourceName}`,\n );\n }\n\n this.initialized = true;\n } catch (error) {\n throw new Error(\n `Failed to initialize Windows Event Log FFI: ${error}`,\n );\n }\n }\n\n /**\n * Write an event to Windows Event Log\n */\n writeEvent(eventType: EventType, eventId: number, params: string[]): void {\n if (!this.initialized || !this.eventSource || !this.lib) {\n return;\n }\n\n try {\n // Create pointer array for strings\n const ptrArray = new BigUint64Array(params.length + 1);\n\n // Use string array approach which works with Bun FFI\n const encoder = new TextEncoder();\n for (let i = 0; i < params.length; i++) {\n const paramBuffer = encoder.encode(params[i] + \"\\0\");\n ptrArray[i] = BigInt(ptr(paramBuffer));\n }\n ptrArray[params.length] = 0n; // null terminator\n\n const success = this.lib.symbols.ReportEventA(\n this.eventSource,\n eventType,\n 0, // category\n eventId,\n null, // user SID (null)\n params.length, // number of strings\n 0, // data size\n ptrArray, // pointer to array of string pointers\n null, // raw data (null)\n );\n\n if (!success) {\n throw new Error(`ReportEventA returned false`);\n }\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Clean up resources\n */\n dispose(): void {\n if (this.initialized && this.eventSource && this.lib) {\n try {\n this.lib.symbols.DeregisterEventSource(this.eventSource);\n } catch (error) {\n this.metaLogger.error(\n \"Failed to deregister event source during cleanup: {error}\",\n { error },\n );\n }\n this.eventSource = null;\n this.initialized = false;\n\n try {\n this.lib.close();\n } catch (error) {\n this.metaLogger.error(\n \"Failed to close FFI library during cleanup: {error}\",\n { error },\n );\n }\n this.lib = null;\n }\n }\n}\n\n// cSpell: ignore cstring\n"],"mappings":";;;;;;;AASA,IAAa,wBAAb,MAAiE;CAC/D,AAAQ,cAA6B;CAErC,AAAQ,MAAW;CACnB,AAAQ,aAAqB;CAC7B,AAAQ,cAAc;CACtB,AAAQ,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;;;;CAKvE,WAAWA,YAA0B;AACnC,OAAK,aAAa;AAClB,MAAI,KAAK,YAAa;AAEtB,MAAI;AAEF,QAAK,MAAM,OAAO,gBAAgB;IAChC,sBAAsB;KACpB,MAAM,CAAC,QAAQ,KAAK,QAAQ,OAAQ;KACpC,SAAS,QAAQ;IAClB;IACD,cAAc;KACZ,MAAM;MACJ,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;MACR,QAAQ;KACT;KACD,SAAS,QAAQ;IAClB;IACD,uBAAuB;KACrB,MAAM,CAAC,QAAQ,GAAI;KACnB,SAAS,QAAQ;IAClB;GACF,EAAC;GAIF,MAAM,UAAU,IAAI;GACpB,MAAM,mBAAmB,QAAQ,OAAO,KAAK,aAAa,KAAK;GAE/D,MAAM,SAAS,KAAK,IAAI,QAAQ,qBAC9B,MACA,iBACD;AACD,QAAK,qBAAqB,WAAW,WAAW,SAAS;AAEzD,QAAK,KAAK,eAAe,KAAK,gBAAgB,EAC5C,OAAM,IAAI,OACP,mCAAmC,KAAK,WAAW;AAIxD,QAAK,cAAc;EACpB,SAAQ,OAAO;AACd,SAAM,IAAI,OACP,8CAA8C,MAAM;EAExD;CACF;;;;CAKD,WAAWC,WAAsBC,SAAiBC,QAAwB;AACxE,OAAK,KAAK,gBAAgB,KAAK,gBAAgB,KAAK,IAClD;AAGF,MAAI;GAEF,MAAM,WAAW,IAAI,eAAe,OAAO,SAAS;GAGpD,MAAM,UAAU,IAAI;AACpB,QAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;IACtC,MAAM,cAAc,QAAQ,OAAO,OAAO,KAAK,KAAK;AACpD,aAAS,KAAK,OAAO,IAAI,YAAY,CAAC;GACvC;AACD,YAAS,OAAO,UAAU;GAE1B,MAAM,UAAU,KAAK,IAAI,QAAQ,aAC/B,KAAK,aACL,WACA,GACA,SACA,MACA,OAAO,QACP,GACA,UACA,KACD;AAED,QAAK,QACH,OAAM,IAAI,OAAO;EAEpB,SAAQ,OAAO;AACd,SAAM;EACP;CACF;;;;CAKD,UAAgB;AACd,MAAI,KAAK,eAAe,KAAK,eAAe,KAAK,KAAK;AACpD,OAAI;AACF,SAAK,IAAI,QAAQ,sBAAsB,KAAK,YAAY;GACzD,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,6DACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,cAAc;AACnB,QAAK,cAAc;AAEnB,OAAI;AACF,SAAK,IAAI,OAAO;GACjB,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,uDACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,MAAM;EACZ;CACF;AACF"}
package/dist/ffi.deno.cjs CHANGED
@@ -3,9 +3,6 @@ const require_types = require('./types.cjs');
3
3
  const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
4
4
 
5
5
  //#region src/ffi.deno.ts
6
- const EVENTLOG_ERROR_TYPE = 1;
7
- const EVENTLOG_WARNING_TYPE = 2;
8
- const EVENTLOG_INFORMATION_TYPE = 4;
9
6
  const FFI_SYMBOLS = {
10
7
  RegisterEventSourceA: {
11
8
  parameters: ["pointer", "pointer"],
@@ -36,28 +33,30 @@ const FFI_SYMBOLS = {
36
33
  *
37
34
  * @since 1.0.0
38
35
  */
39
- var WindowsEventLogFFI = class {
36
+ var WindowsEventLogDenoFFI = class {
40
37
  lib = null;
41
38
  eventSource = null;
39
+ sourceName = "";
40
+ initialized = false;
42
41
  encoder = new TextEncoder();
43
42
  metaLogger = (0, __logtape_logtape.getLogger)([
44
43
  "logtape",
45
44
  "meta",
46
45
  "windows-eventlog"
47
46
  ]);
48
- constructor(sourceName) {
49
- this.sourceName = sourceName;
50
- }
51
47
  /**
52
48
  * Initializes the FFI library and registers the event source.
53
49
  * @throws {WindowsEventLogError} If initialization fails
54
50
  */
55
- initialize() {
51
+ initialize(sourceName) {
52
+ this.sourceName = sourceName;
53
+ if (this.initialized) return;
56
54
  try {
57
55
  this.lib = Deno.dlopen("advapi32.dll", FFI_SYMBOLS);
58
56
  const sourceNamePtr = Deno.UnsafePointer.of(this.encoder.encode(this.sourceName + "\0"));
59
57
  this.eventSource = this.lib.symbols.RegisterEventSourceA(null, sourceNamePtr);
60
58
  if (!this.eventSource) throw new require_types.WindowsEventLogError(`Failed to register event source '${this.sourceName}'.`);
59
+ this.initialized = true;
61
60
  } catch (error) {
62
61
  if (error instanceof require_types.WindowsEventLogError) throw error;
63
62
  throw new require_types.WindowsEventLogError(`Failed to initialize Windows Event Log FFI: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
@@ -67,19 +66,23 @@ var WindowsEventLogFFI = class {
67
66
  * Writes a message to the Windows Event Log.
68
67
  *
69
68
  * @param eventType Event type (error, warning, info)
70
- * @param eventId Event ID number
71
- * @param message Message string to log
69
+ * @param eventId Event ID number that gives us formatting string
70
+ * @param params Message parameter strings to log
72
71
  * @throws {WindowsEventLogError} If the write operation fails
73
72
  */
74
- writeEvent(eventType, eventId, message) {
73
+ writeEvent(eventType, eventId, params) {
75
74
  if (!this.lib || !this.eventSource) throw new require_types.WindowsEventLogError("FFI not initialized. Call initialize() first.");
76
75
  try {
77
- const messageBuffer = this.encoder.encode(message + "\0");
78
- const messagePtr = Deno.UnsafePointer.of(messageBuffer);
79
- const messagePtrValue = messagePtr ? Deno.UnsafePointer.value(messagePtr) : 0n;
80
- const stringsArray = new BigUint64Array([messagePtrValue]);
76
+ const unsafePointersToStrings = [];
77
+ for (let i = 0; i < params.length; i++) {
78
+ const paramBuffer = this.encoder.encode(params[i] + "\0");
79
+ const paramPtr = Deno.UnsafePointer.of(paramBuffer);
80
+ const paramPtrValue = paramPtr ? Deno.UnsafePointer.value(paramPtr) : 0n;
81
+ unsafePointersToStrings.push(paramPtrValue);
82
+ }
83
+ const stringsArray = new BigUint64Array(unsafePointersToStrings);
81
84
  const stringsPtr = Deno.UnsafePointer.of(stringsArray);
82
- const result = this.lib.symbols.ReportEventA(this.eventSource, eventType, 0, eventId, null, 1, 0, stringsPtr, null);
85
+ const result = this.lib.symbols.ReportEventA(this.eventSource, eventType, 0, eventId, null, stringsArray.length, 0, stringsPtr, null);
83
86
  if (result === 0) throw new require_types.WindowsEventLogError(`Failed to write event to Event Log.`);
84
87
  } catch (error) {
85
88
  if (error instanceof require_types.WindowsEventLogError) throw error;
@@ -106,11 +109,9 @@ var WindowsEventLogFFI = class {
106
109
  }
107
110
  this.lib = null;
108
111
  }
112
+ this.initialized = false;
109
113
  }
110
114
  };
111
115
 
112
116
  //#endregion
113
- exports.EVENTLOG_ERROR_TYPE = EVENTLOG_ERROR_TYPE;
114
- exports.EVENTLOG_INFORMATION_TYPE = EVENTLOG_INFORMATION_TYPE;
115
- exports.EVENTLOG_WARNING_TYPE = EVENTLOG_WARNING_TYPE;
116
- exports.WindowsEventLogFFI = WindowsEventLogFFI;
117
+ exports.WindowsEventLogDenoFFI = WindowsEventLogDenoFFI;
package/dist/ffi.deno.js CHANGED
@@ -2,9 +2,6 @@ import { WindowsEventLogError } from "./types.js";
2
2
  import { getLogger } from "@logtape/logtape";
3
3
 
4
4
  //#region src/ffi.deno.ts
5
- const EVENTLOG_ERROR_TYPE = 1;
6
- const EVENTLOG_WARNING_TYPE = 2;
7
- const EVENTLOG_INFORMATION_TYPE = 4;
8
5
  const FFI_SYMBOLS = {
9
6
  RegisterEventSourceA: {
10
7
  parameters: ["pointer", "pointer"],
@@ -35,28 +32,30 @@ const FFI_SYMBOLS = {
35
32
  *
36
33
  * @since 1.0.0
37
34
  */
38
- var WindowsEventLogFFI = class {
35
+ var WindowsEventLogDenoFFI = class {
39
36
  lib = null;
40
37
  eventSource = null;
38
+ sourceName = "";
39
+ initialized = false;
41
40
  encoder = new TextEncoder();
42
41
  metaLogger = getLogger([
43
42
  "logtape",
44
43
  "meta",
45
44
  "windows-eventlog"
46
45
  ]);
47
- constructor(sourceName) {
48
- this.sourceName = sourceName;
49
- }
50
46
  /**
51
47
  * Initializes the FFI library and registers the event source.
52
48
  * @throws {WindowsEventLogError} If initialization fails
53
49
  */
54
- initialize() {
50
+ initialize(sourceName) {
51
+ this.sourceName = sourceName;
52
+ if (this.initialized) return;
55
53
  try {
56
54
  this.lib = Deno.dlopen("advapi32.dll", FFI_SYMBOLS);
57
55
  const sourceNamePtr = Deno.UnsafePointer.of(this.encoder.encode(this.sourceName + "\0"));
58
56
  this.eventSource = this.lib.symbols.RegisterEventSourceA(null, sourceNamePtr);
59
57
  if (!this.eventSource) throw new WindowsEventLogError(`Failed to register event source '${this.sourceName}'.`);
58
+ this.initialized = true;
60
59
  } catch (error) {
61
60
  if (error instanceof WindowsEventLogError) throw error;
62
61
  throw new WindowsEventLogError(`Failed to initialize Windows Event Log FFI: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
@@ -66,19 +65,23 @@ var WindowsEventLogFFI = class {
66
65
  * Writes a message to the Windows Event Log.
67
66
  *
68
67
  * @param eventType Event type (error, warning, info)
69
- * @param eventId Event ID number
70
- * @param message Message string to log
68
+ * @param eventId Event ID number that gives us formatting string
69
+ * @param params Message parameter strings to log
71
70
  * @throws {WindowsEventLogError} If the write operation fails
72
71
  */
73
- writeEvent(eventType, eventId, message) {
72
+ writeEvent(eventType, eventId, params) {
74
73
  if (!this.lib || !this.eventSource) throw new WindowsEventLogError("FFI not initialized. Call initialize() first.");
75
74
  try {
76
- const messageBuffer = this.encoder.encode(message + "\0");
77
- const messagePtr = Deno.UnsafePointer.of(messageBuffer);
78
- const messagePtrValue = messagePtr ? Deno.UnsafePointer.value(messagePtr) : 0n;
79
- const stringsArray = new BigUint64Array([messagePtrValue]);
75
+ const unsafePointersToStrings = [];
76
+ for (let i = 0; i < params.length; i++) {
77
+ const paramBuffer = this.encoder.encode(params[i] + "\0");
78
+ const paramPtr = Deno.UnsafePointer.of(paramBuffer);
79
+ const paramPtrValue = paramPtr ? Deno.UnsafePointer.value(paramPtr) : 0n;
80
+ unsafePointersToStrings.push(paramPtrValue);
81
+ }
82
+ const stringsArray = new BigUint64Array(unsafePointersToStrings);
80
83
  const stringsPtr = Deno.UnsafePointer.of(stringsArray);
81
- const result = this.lib.symbols.ReportEventA(this.eventSource, eventType, 0, eventId, null, 1, 0, stringsPtr, null);
84
+ const result = this.lib.symbols.ReportEventA(this.eventSource, eventType, 0, eventId, null, stringsArray.length, 0, stringsPtr, null);
82
85
  if (result === 0) throw new WindowsEventLogError(`Failed to write event to Event Log.`);
83
86
  } catch (error) {
84
87
  if (error instanceof WindowsEventLogError) throw error;
@@ -105,9 +108,10 @@ var WindowsEventLogFFI = class {
105
108
  }
106
109
  this.lib = null;
107
110
  }
111
+ this.initialized = false;
108
112
  }
109
113
  };
110
114
 
111
115
  //#endregion
112
- export { EVENTLOG_ERROR_TYPE, EVENTLOG_INFORMATION_TYPE, EVENTLOG_WARNING_TYPE, WindowsEventLogFFI };
116
+ export { WindowsEventLogDenoFFI };
113
117
  //# sourceMappingURL=ffi.deno.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ffi.deno.js","names":["sourceName: string","eventType: number","eventId: number","message: string"],"sources":["../src/ffi.deno.ts"],"sourcesContent":["import { getLogger } from \"@logtape/logtape\";\nimport { WindowsEventLogError } from \"./types.ts\";\n\n/**\n * Windows Event Log API constants and types for FFI.\n * @since 1.0.0\n */\n\n// Event Log types\nexport const EVENTLOG_SUCCESS = 0x0000;\nexport const EVENTLOG_ERROR_TYPE = 0x0001;\nexport const EVENTLOG_WARNING_TYPE = 0x0002;\nexport const EVENTLOG_INFORMATION_TYPE = 0x0004;\n\n// FFI symbol definitions for Windows Event Log APIs\nconst FFI_SYMBOLS = {\n RegisterEventSourceA: {\n parameters: [\"pointer\", \"pointer\"] as const,\n result: \"pointer\" as const,\n },\n DeregisterEventSource: {\n parameters: [\"pointer\"] as const,\n result: \"u32\" as const,\n },\n ReportEventA: {\n parameters: [\n \"pointer\", // hEventLog\n \"u16\", // wType\n \"u16\", // wCategory\n \"u32\", // dwEventID\n \"pointer\", // lpUserSid\n \"u16\", // wNumStrings\n \"u32\", // dwDataSize\n \"pointer\", // lpStrings\n \"pointer\", // lpRawData\n ] as const,\n result: \"u32\" as const,\n },\n} as const;\n\n/**\n * Windows Event Log FFI wrapper class for Deno.\n * Provides direct access to Windows Event Log APIs through Deno's FFI.\n *\n * @since 1.0.0\n */\nexport class WindowsEventLogFFI {\n private lib: Deno.DynamicLibrary<typeof FFI_SYMBOLS> | null = null;\n private eventSource: Deno.PointerValue | null = null;\n private encoder = new TextEncoder();\n private metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n constructor(private sourceName: string) {}\n\n /**\n * Initializes the FFI library and registers the event source.\n * @throws {WindowsEventLogError} If initialization fails\n */\n initialize(): void {\n try {\n // Load advapi32.dll\n this.lib = Deno.dlopen(\"advapi32.dll\", FFI_SYMBOLS);\n\n // Register event source\n const sourceNamePtr = Deno.UnsafePointer.of(\n this.encoder.encode(this.sourceName + \"\\0\"),\n );\n this.eventSource = this.lib.symbols.RegisterEventSourceA(\n null,\n sourceNamePtr,\n );\n\n if (!this.eventSource) {\n throw new WindowsEventLogError(\n `Failed to register event source '${this.sourceName}'.`,\n );\n }\n } catch (error) {\n if (error instanceof WindowsEventLogError) {\n throw error;\n }\n throw new WindowsEventLogError(\n `Failed to initialize Windows Event Log FFI: ${\n error instanceof Error ? error.message : String(error)\n }`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Writes a message to the Windows Event Log.\n *\n * @param eventType Event type (error, warning, info)\n * @param eventId Event ID number\n * @param message Message string to log\n * @throws {WindowsEventLogError} If the write operation fails\n */\n writeEvent(eventType: number, eventId: number, message: string): void {\n if (!this.lib || !this.eventSource) {\n throw new WindowsEventLogError(\n \"FFI not initialized. Call initialize() first.\",\n );\n }\n\n try {\n // Prepare message string\n const messageBuffer = this.encoder.encode(message + \"\\0\");\n const messagePtr = Deno.UnsafePointer.of(messageBuffer);\n const messagePtrValue = messagePtr\n ? Deno.UnsafePointer.value(messagePtr)\n : 0n;\n const stringsArray = new BigUint64Array([messagePtrValue]);\n const stringsPtr = Deno.UnsafePointer.of(stringsArray);\n\n // Call ReportEventA\n const result = this.lib.symbols.ReportEventA(\n this.eventSource, // hEventLog\n eventType, // wType\n 0, // wCategory (0 = no category)\n eventId, // dwEventID\n null, // lpUserSid (null = current user)\n 1, // wNumStrings (1 string)\n 0, // dwDataSize (no additional data)\n stringsPtr, // lpStrings\n null, // lpRawData (no additional data)\n );\n\n if (result === 0) {\n throw new WindowsEventLogError(\n `Failed to write event to Event Log.`,\n );\n }\n } catch (error) {\n if (error instanceof WindowsEventLogError) {\n throw error;\n }\n throw new WindowsEventLogError(\n `Error writing to Event Log: ${\n error instanceof Error ? error.message : String(error)\n }`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Cleans up resources and deregisters the event source.\n */\n dispose(): void {\n if (this.lib && this.eventSource) {\n try {\n this.lib.symbols.DeregisterEventSource(this.eventSource);\n } catch (error) {\n this.metaLogger.error(\n \"Failed to deregister event source during cleanup: {error}\",\n { error },\n );\n }\n this.eventSource = null;\n }\n\n if (this.lib) {\n try {\n this.lib.close();\n } catch (error) {\n this.metaLogger.error(\n \"Failed to close FFI library during cleanup: {error}\",\n { error },\n );\n }\n this.lib = null;\n }\n }\n}\n"],"mappings":";;;;AAUA,MAAa,sBAAsB;AACnC,MAAa,wBAAwB;AACrC,MAAa,4BAA4B;AAGzC,MAAM,cAAc;CAClB,sBAAsB;EACpB,YAAY,CAAC,WAAW,SAAU;EAClC,QAAQ;CACT;CACD,uBAAuB;EACrB,YAAY,CAAC,SAAU;EACvB,QAAQ;CACT;CACD,cAAc;EACZ,YAAY;GACV;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD;EACD,QAAQ;CACT;AACF;;;;;;;AAQD,IAAa,qBAAb,MAAgC;CAC9B,AAAQ,MAAsD;CAC9D,AAAQ,cAAwC;CAChD,AAAQ,UAAU,IAAI;CACtB,AAAQ,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;CAEvE,YAAoBA,YAAoB;EAApB;CAAsB;;;;;CAM1C,aAAmB;AACjB,MAAI;AAEF,QAAK,MAAM,KAAK,OAAO,gBAAgB,YAAY;GAGnD,MAAM,gBAAgB,KAAK,cAAc,GACvC,KAAK,QAAQ,OAAO,KAAK,aAAa,KAAK,CAC5C;AACD,QAAK,cAAc,KAAK,IAAI,QAAQ,qBAClC,MACA,cACD;AAED,QAAK,KAAK,YACR,OAAM,IAAI,sBACP,mCAAmC,KAAK,WAAW;EAGzD,SAAQ,OAAO;AACd,OAAI,iBAAiB,qBACnB,OAAM;AAER,SAAM,IAAI,sBACP,8CACC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CACvD,GACD,iBAAiB,QAAQ;EAE5B;CACF;;;;;;;;;CAUD,WAAWC,WAAmBC,SAAiBC,SAAuB;AACpE,OAAK,KAAK,QAAQ,KAAK,YACrB,OAAM,IAAI,qBACR;AAIJ,MAAI;GAEF,MAAM,gBAAgB,KAAK,QAAQ,OAAO,UAAU,KAAK;GACzD,MAAM,aAAa,KAAK,cAAc,GAAG,cAAc;GACvD,MAAM,kBAAkB,aACpB,KAAK,cAAc,MAAM,WAAW,GACpC;GACJ,MAAM,eAAe,IAAI,eAAe,CAAC,eAAgB;GACzD,MAAM,aAAa,KAAK,cAAc,GAAG,aAAa;GAGtD,MAAM,SAAS,KAAK,IAAI,QAAQ,aAC9B,KAAK,aACL,WACA,GACA,SACA,MACA,GACA,GACA,YACA,KACD;AAED,OAAI,WAAW,EACb,OAAM,IAAI,sBACP;EAGN,SAAQ,OAAO;AACd,OAAI,iBAAiB,qBACnB,OAAM;AAER,SAAM,IAAI,sBACP,8BACC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CACvD,GACD,iBAAiB,QAAQ;EAE5B;CACF;;;;CAKD,UAAgB;AACd,MAAI,KAAK,OAAO,KAAK,aAAa;AAChC,OAAI;AACF,SAAK,IAAI,QAAQ,sBAAsB,KAAK,YAAY;GACzD,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,6DACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,cAAc;EACpB;AAED,MAAI,KAAK,KAAK;AACZ,OAAI;AACF,SAAK,IAAI,OAAO;GACjB,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,uDACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,MAAM;EACZ;CACF;AACF"}
1
+ {"version":3,"file":"ffi.deno.js","names":["sourceName: string","eventType: number","eventId: number","params: string[]","unsafePointersToStrings: bigint[]"],"sources":["../src/ffi.deno.ts"],"sourcesContent":["import { getLogger } from \"@logtape/logtape\";\nimport type { WindowsEventLogFFI } from \"./ffi.ts\";\nimport { WindowsEventLogError } from \"./types.ts\";\n\n/**\n * Windows Event Log API constants and types for FFI.\n * @since 1.0.0\n */\n\n// Event Log types\nexport const EVENTLOG_SUCCESS = 0x0000;\nexport const EVENTLOG_ERROR_TYPE = 0x0001;\nexport const EVENTLOG_WARNING_TYPE = 0x0002;\nexport const EVENTLOG_INFORMATION_TYPE = 0x0004;\n\n// FFI symbol definitions for Windows Event Log APIs\nconst FFI_SYMBOLS = {\n RegisterEventSourceA: {\n parameters: [\"pointer\", \"pointer\"] as const,\n result: \"pointer\" as const,\n },\n DeregisterEventSource: {\n parameters: [\"pointer\"] as const,\n result: \"u32\" as const,\n },\n ReportEventA: {\n parameters: [\n \"pointer\", // hEventLog\n \"u16\", // wType\n \"u16\", // wCategory\n \"u32\", // dwEventID\n \"pointer\", // lpUserSid\n \"u16\", // wNumStrings\n \"u32\", // dwDataSize\n \"pointer\", // lpStrings\n \"pointer\", // lpRawData\n ] as const,\n result: \"u32\" as const,\n },\n} as const;\n\n/**\n * Windows Event Log FFI wrapper class for Deno.\n * Provides direct access to Windows Event Log APIs through Deno's FFI.\n *\n * @since 1.0.0\n */\nexport class WindowsEventLogDenoFFI implements WindowsEventLogFFI {\n private lib: Deno.DynamicLibrary<typeof FFI_SYMBOLS> | null = null;\n private eventSource: Deno.PointerValue | null = null;\n private sourceName: string = \"\"; // immediately overwritten in initialize\n private initialized = false;\n private encoder = new TextEncoder();\n private metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n /**\n * Initializes the FFI library and registers the event source.\n * @throws {WindowsEventLogError} If initialization fails\n */\n initialize(sourceName: string): void {\n this.sourceName = sourceName;\n if (this.initialized) return;\n\n try {\n // Load advapi32.dll\n this.lib = Deno.dlopen(\"advapi32.dll\", FFI_SYMBOLS);\n\n // Register event source\n const sourceNamePtr = Deno.UnsafePointer.of(\n this.encoder.encode(this.sourceName + \"\\0\"),\n );\n this.eventSource = this.lib.symbols.RegisterEventSourceA(\n null,\n sourceNamePtr,\n );\n\n if (!this.eventSource) {\n throw new WindowsEventLogError(\n `Failed to register event source '${this.sourceName}'.`,\n );\n }\n\n this.initialized = true;\n } catch (error) {\n if (error instanceof WindowsEventLogError) {\n throw error;\n }\n throw new WindowsEventLogError(\n `Failed to initialize Windows Event Log FFI: ${\n error instanceof Error ? error.message : String(error)\n }`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Writes a message to the Windows Event Log.\n *\n * @param eventType Event type (error, warning, info)\n * @param eventId Event ID number that gives us formatting string\n * @param params Message parameter strings to log\n * @throws {WindowsEventLogError} If the write operation fails\n */\n writeEvent(eventType: number, eventId: number, params: string[]): void {\n if (!this.lib || !this.eventSource) {\n throw new WindowsEventLogError(\n \"FFI not initialized. Call initialize() first.\",\n );\n }\n\n try {\n const unsafePointersToStrings: bigint[] = [];\n for (let i = 0; i < params.length; i++) {\n // Prepare message string\n const paramBuffer = this.encoder.encode(params[i] + \"\\0\");\n const paramPtr = Deno.UnsafePointer.of(paramBuffer);\n const paramPtrValue = paramPtr\n ? Deno.UnsafePointer.value(paramPtr)\n : 0n;\n unsafePointersToStrings.push(paramPtrValue);\n }\n const stringsArray = new BigUint64Array(unsafePointersToStrings);\n const stringsPtr = Deno.UnsafePointer.of(stringsArray);\n\n // Call ReportEventA\n const result = this.lib.symbols.ReportEventA(\n this.eventSource, // hEventLog\n eventType, // wType\n 0, // wCategory (0 = no category)\n eventId, // dwEventID\n null, // lpUserSid (null = current user)\n stringsArray.length, // wNumStrings\n 0, // dwDataSize (no additional data)\n stringsPtr, // lpStrings\n null, // lpRawData (no additional data)\n );\n\n if (result === 0) {\n throw new WindowsEventLogError(\n `Failed to write event to Event Log.`,\n );\n }\n } catch (error) {\n if (error instanceof WindowsEventLogError) {\n throw error;\n }\n throw new WindowsEventLogError(\n `Error writing to Event Log: ${\n error instanceof Error ? error.message : String(error)\n }`,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n /**\n * Cleans up resources and deregisters the event source.\n */\n dispose(): void {\n if (this.lib && this.eventSource) {\n try {\n this.lib.symbols.DeregisterEventSource(this.eventSource);\n } catch (error) {\n this.metaLogger.error(\n \"Failed to deregister event source during cleanup: {error}\",\n { error },\n );\n }\n this.eventSource = null;\n }\n\n if (this.lib) {\n try {\n this.lib.close();\n } catch (error) {\n this.metaLogger.error(\n \"Failed to close FFI library during cleanup: {error}\",\n { error },\n );\n }\n this.lib = null;\n }\n\n this.initialized = false;\n }\n}\n"],"mappings":";;;;AAgBA,MAAM,cAAc;CAClB,sBAAsB;EACpB,YAAY,CAAC,WAAW,SAAU;EAClC,QAAQ;CACT;CACD,uBAAuB;EACrB,YAAY,CAAC,SAAU;EACvB,QAAQ;CACT;CACD,cAAc;EACZ,YAAY;GACV;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD;EACD,QAAQ;CACT;AACF;;;;;;;AAQD,IAAa,yBAAb,MAAkE;CAChE,AAAQ,MAAsD;CAC9D,AAAQ,cAAwC;CAChD,AAAQ,aAAqB;CAC7B,AAAQ,cAAc;CACtB,AAAQ,UAAU,IAAI;CACtB,AAAQ,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;;;;;CAMvE,WAAWA,YAA0B;AACnC,OAAK,aAAa;AAClB,MAAI,KAAK,YAAa;AAEtB,MAAI;AAEF,QAAK,MAAM,KAAK,OAAO,gBAAgB,YAAY;GAGnD,MAAM,gBAAgB,KAAK,cAAc,GACvC,KAAK,QAAQ,OAAO,KAAK,aAAa,KAAK,CAC5C;AACD,QAAK,cAAc,KAAK,IAAI,QAAQ,qBAClC,MACA,cACD;AAED,QAAK,KAAK,YACR,OAAM,IAAI,sBACP,mCAAmC,KAAK,WAAW;AAIxD,QAAK,cAAc;EACpB,SAAQ,OAAO;AACd,OAAI,iBAAiB,qBACnB,OAAM;AAER,SAAM,IAAI,sBACP,8CACC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CACvD,GACD,iBAAiB,QAAQ;EAE5B;CACF;;;;;;;;;CAUD,WAAWC,WAAmBC,SAAiBC,QAAwB;AACrE,OAAK,KAAK,QAAQ,KAAK,YACrB,OAAM,IAAI,qBACR;AAIJ,MAAI;GACF,MAAMC,0BAAoC,CAAE;AAC5C,QAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;IAEtC,MAAM,cAAc,KAAK,QAAQ,OAAO,OAAO,KAAK,KAAK;IACzD,MAAM,WAAW,KAAK,cAAc,GAAG,YAAY;IACnD,MAAM,gBAAgB,WAClB,KAAK,cAAc,MAAM,SAAS,GAClC;AACJ,4BAAwB,KAAK,cAAc;GAC5C;GACD,MAAM,eAAe,IAAI,eAAe;GACxC,MAAM,aAAa,KAAK,cAAc,GAAG,aAAa;GAGtD,MAAM,SAAS,KAAK,IAAI,QAAQ,aAC9B,KAAK,aACL,WACA,GACA,SACA,MACA,aAAa,QACb,GACA,YACA,KACD;AAED,OAAI,WAAW,EACb,OAAM,IAAI,sBACP;EAGN,SAAQ,OAAO;AACd,OAAI,iBAAiB,qBACnB,OAAM;AAER,SAAM,IAAI,sBACP,8BACC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CACvD,GACD,iBAAiB,QAAQ;EAE5B;CACF;;;;CAKD,UAAgB;AACd,MAAI,KAAK,OAAO,KAAK,aAAa;AAChC,OAAI;AACF,SAAK,IAAI,QAAQ,sBAAsB,KAAK,YAAY;GACzD,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,6DACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,cAAc;EACpB;AAED,MAAI,KAAK,KAAK;AACZ,OAAI;AACF,SAAK,IAAI,OAAO;GACjB,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,uDACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,MAAM;EACZ;AAED,OAAK,cAAc;CACpB;AACF"}
package/dist/ffi.node.cjs CHANGED
@@ -1,14 +1,14 @@
1
1
  const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
2
  const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
3
+ const koffi = require_rolldown_runtime.__toESM(require("koffi"));
3
4
 
4
5
  //#region src/ffi.node.ts
5
6
  /**
6
7
  * Node.js FFI implementation for Windows Event Log API using koffi
7
8
  */
8
- var WindowsEventLogFFI = class {
9
+ var WindowsEventLogNodeFFI = class {
9
10
  eventSource = null;
10
- koffi = null;
11
- sourceName;
11
+ sourceName = "";
12
12
  initialized = false;
13
13
  lib = null;
14
14
  metaLogger = (0, __logtape_logtape.getLogger)([
@@ -16,18 +16,14 @@ var WindowsEventLogFFI = class {
16
16
  "meta",
17
17
  "windows-eventlog"
18
18
  ]);
19
- constructor(sourceName) {
20
- this.sourceName = sourceName;
21
- }
22
19
  /**
23
20
  * Initialize the FFI bindings and register event source
24
21
  */
25
- async initialize() {
22
+ initialize(sourceName) {
23
+ this.sourceName = sourceName;
26
24
  if (this.initialized) return;
27
25
  try {
28
- const koffiModule = await import("koffi");
29
- this.koffi = koffiModule.default || koffiModule;
30
- this.lib = this.koffi.load("advapi32.dll");
26
+ this.lib = koffi.default.load("advapi32.dll");
31
27
  const RegisterEventSourceA = this.lib.func("uintptr __stdcall RegisterEventSourceA(uintptr lpUNCServerName, str lpSourceName)");
32
28
  const ReportEventA = this.lib.func("bool __stdcall ReportEventA(uintptr hEventLog, uint16 wType, uint16 wCategory, uint32 dwEventID, uintptr lpUserSid, uint16 wNumStrings, uint32 dwDataSize, char** lpStrings, uint8* lpRawData)");
33
29
  const DeregisterEventSource = this.lib.func("bool __stdcall DeregisterEventSource(uintptr hEventLog)");
@@ -47,12 +43,11 @@ var WindowsEventLogFFI = class {
47
43
  /**
48
44
  * Write an event to Windows Event Log
49
45
  */
50
- writeEvent(eventType, eventId, message) {
46
+ writeEvent(eventType, eventId, params) {
51
47
  if (!this.initialized || !this.eventSource || !this.ReportEventA) return;
52
48
  try {
53
- const messageWithNull = message + "\0";
54
- const messages = [messageWithNull];
55
- const success = this.ReportEventA(this.eventSource, eventType, 0, eventId, 0, 1, 0, messages, null);
49
+ const nullTerminatedParams = params.map((s) => s + "\0");
50
+ const success = this.ReportEventA(this.eventSource, eventType, 0, eventId, 0, nullTerminatedParams.length, 0, nullTerminatedParams, null);
56
51
  if (!success) throw new Error("ReportEventA() returned false.");
57
52
  } catch (error) {
58
53
  throw error;
@@ -75,4 +70,4 @@ var WindowsEventLogFFI = class {
75
70
  };
76
71
 
77
72
  //#endregion
78
- exports.WindowsEventLogFFI = WindowsEventLogFFI;
73
+ exports.WindowsEventLogNodeFFI = WindowsEventLogNodeFFI;
package/dist/ffi.node.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { getLogger } from "@logtape/logtape";
2
+ import koffi from "koffi";
2
3
 
3
4
  //#region src/ffi.node.ts
4
5
  /**
5
6
  * Node.js FFI implementation for Windows Event Log API using koffi
6
7
  */
7
- var WindowsEventLogFFI = class {
8
+ var WindowsEventLogNodeFFI = class {
8
9
  eventSource = null;
9
- koffi = null;
10
- sourceName;
10
+ sourceName = "";
11
11
  initialized = false;
12
12
  lib = null;
13
13
  metaLogger = getLogger([
@@ -15,18 +15,14 @@ var WindowsEventLogFFI = class {
15
15
  "meta",
16
16
  "windows-eventlog"
17
17
  ]);
18
- constructor(sourceName) {
19
- this.sourceName = sourceName;
20
- }
21
18
  /**
22
19
  * Initialize the FFI bindings and register event source
23
20
  */
24
- async initialize() {
21
+ initialize(sourceName) {
22
+ this.sourceName = sourceName;
25
23
  if (this.initialized) return;
26
24
  try {
27
- const koffiModule = await import("koffi");
28
- this.koffi = koffiModule.default || koffiModule;
29
- this.lib = this.koffi.load("advapi32.dll");
25
+ this.lib = koffi.load("advapi32.dll");
30
26
  const RegisterEventSourceA = this.lib.func("uintptr __stdcall RegisterEventSourceA(uintptr lpUNCServerName, str lpSourceName)");
31
27
  const ReportEventA = this.lib.func("bool __stdcall ReportEventA(uintptr hEventLog, uint16 wType, uint16 wCategory, uint32 dwEventID, uintptr lpUserSid, uint16 wNumStrings, uint32 dwDataSize, char** lpStrings, uint8* lpRawData)");
32
28
  const DeregisterEventSource = this.lib.func("bool __stdcall DeregisterEventSource(uintptr hEventLog)");
@@ -46,12 +42,11 @@ var WindowsEventLogFFI = class {
46
42
  /**
47
43
  * Write an event to Windows Event Log
48
44
  */
49
- writeEvent(eventType, eventId, message) {
45
+ writeEvent(eventType, eventId, params) {
50
46
  if (!this.initialized || !this.eventSource || !this.ReportEventA) return;
51
47
  try {
52
- const messageWithNull = message + "\0";
53
- const messages = [messageWithNull];
54
- const success = this.ReportEventA(this.eventSource, eventType, 0, eventId, 0, 1, 0, messages, null);
48
+ const nullTerminatedParams = params.map((s) => s + "\0");
49
+ const success = this.ReportEventA(this.eventSource, eventType, 0, eventId, 0, nullTerminatedParams.length, 0, nullTerminatedParams, null);
55
50
  if (!success) throw new Error("ReportEventA() returned false.");
56
51
  } catch (error) {
57
52
  throw error;
@@ -74,5 +69,5 @@ var WindowsEventLogFFI = class {
74
69
  };
75
70
 
76
71
  //#endregion
77
- export { WindowsEventLogFFI };
72
+ export { WindowsEventLogNodeFFI };
78
73
  //# sourceMappingURL=ffi.node.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ffi.node.js","names":["sourceName: string","eventType: EventType","eventId: number","message: string"],"sources":["../src/ffi.node.ts"],"sourcesContent":["import { getLogger } from \"@logtape/logtape\";\nimport type { EventType } from \"./types.ts\";\n\n/**\n * Node.js FFI implementation for Windows Event Log API using koffi\n */\nexport class WindowsEventLogFFI {\n private eventSource: unknown = null;\n private koffi: unknown = null;\n private sourceName: string;\n private initialized = false;\n private lib: unknown = null;\n private metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n constructor(sourceName: string) {\n this.sourceName = sourceName;\n }\n\n /**\n * Initialize the FFI bindings and register event source\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n try {\n // Dynamic import for koffi\n const koffiModule = await import(\"koffi\");\n this.koffi = koffiModule.default || koffiModule;\n\n // Load advapi32.dll\n this.lib = (this.koffi as unknown as { load: (lib: string) => unknown })\n .load(\"advapi32.dll\");\n\n // Define Windows API functions with correct koffi types using __stdcall convention\n const RegisterEventSourceA =\n (this.lib as unknown as { func: (sig: string) => unknown }).func(\n \"uintptr __stdcall RegisterEventSourceA(uintptr lpUNCServerName, str lpSourceName)\",\n );\n // ReportEventA expects LPCSTR* (array of string pointers) for lpStrings\n // Use char** for null-terminated array of strings\n const ReportEventA =\n (this.lib as unknown as { func: (sig: string) => unknown }).func(\n \"bool __stdcall ReportEventA(uintptr hEventLog, uint16 wType, uint16 wCategory, uint32 dwEventID, uintptr lpUserSid, uint16 wNumStrings, uint32 dwDataSize, char** lpStrings, uint8* lpRawData)\",\n );\n const DeregisterEventSource =\n (this.lib as unknown as { func: (sig: string) => unknown }).func(\n \"bool __stdcall DeregisterEventSource(uintptr hEventLog)\",\n );\n\n // Store functions\n this.RegisterEventSourceA = RegisterEventSourceA;\n this.ReportEventA = ReportEventA;\n this.DeregisterEventSource = DeregisterEventSource;\n\n // Register event source\n this.eventSource = (this.RegisterEventSourceA as unknown as (\n ...args: unknown[]\n ) => unknown)(0, this.sourceName);\n\n if (!this.eventSource || this.eventSource === 0) {\n throw new Error(\n `Failed to register event source: ${this.sourceName}`,\n );\n }\n\n this.initialized = true;\n } catch (error) {\n throw new Error(\n `Failed to initialize Windows Event Log FFI: ${error}`,\n );\n }\n }\n\n private RegisterEventSourceA: unknown = null;\n private ReportEventA: unknown = null;\n private DeregisterEventSource: unknown = null;\n\n /**\n * Write an event to Windows Event Log\n */\n writeEvent(eventType: EventType, eventId: number, message: string): void {\n if (!this.initialized || !this.eventSource || !this.ReportEventA) {\n return;\n }\n\n try {\n // Create null-terminated string\n const messageWithNull = message + \"\\0\";\n\n // Create an array with a single string pointer\n // In koffi, we pass an array of strings for char**\n const messages = [messageWithNull];\n\n // Report the event using strings array approach\n const success =\n (this.ReportEventA as unknown as (...args: unknown[]) => unknown)(\n this.eventSource,\n eventType,\n 0, // category\n eventId,\n 0, // user SID (null)\n 1, // number of strings (1 - we have one message)\n 0, // data size (0 - not using raw data)\n messages, // strings array with our message\n null, // raw data (null - not using)\n );\n\n if (!success) {\n throw new Error(\"ReportEventA() returned false.\");\n }\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Clean up resources\n */\n dispose(): void {\n if (this.initialized && this.eventSource && this.DeregisterEventSource) {\n try {\n (this.DeregisterEventSource as unknown as (\n ...args: unknown[]\n ) => unknown)(this.eventSource);\n } catch (error) {\n this.metaLogger.error(\n \"Failed to deregister event source during cleanup: {error}\",\n { error },\n );\n }\n this.eventSource = null;\n this.initialized = false;\n }\n }\n}\n"],"mappings":";;;;;;AAMA,IAAa,qBAAb,MAAgC;CAC9B,AAAQ,cAAuB;CAC/B,AAAQ,QAAiB;CACzB,AAAQ;CACR,AAAQ,cAAc;CACtB,AAAQ,MAAe;CACvB,AAAQ,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;CAEvE,YAAYA,YAAoB;AAC9B,OAAK,aAAa;CACnB;;;;CAKD,MAAM,aAA4B;AAChC,MAAI,KAAK,YAAa;AAEtB,MAAI;GAEF,MAAM,cAAc,MAAM,OAAO;AACjC,QAAK,QAAQ,YAAY,WAAW;AAGpC,QAAK,MAAM,AAAC,KAAK,MACd,KAAK,eAAe;GAGvB,MAAM,uBACJ,AAAC,KAAK,IAAsD,KAC1D,oFACD;GAGH,MAAM,eACJ,AAAC,KAAK,IAAsD,KAC1D,iMACD;GACH,MAAM,wBACJ,AAAC,KAAK,IAAsD,KAC1D,0DACD;AAGH,QAAK,uBAAuB;AAC5B,QAAK,eAAe;AACpB,QAAK,wBAAwB;AAG7B,QAAK,cAAc,AAAC,KAAK,qBAEX,GAAG,KAAK,WAAW;AAEjC,QAAK,KAAK,eAAe,KAAK,gBAAgB,EAC5C,OAAM,IAAI,OACP,mCAAmC,KAAK,WAAW;AAIxD,QAAK,cAAc;EACpB,SAAQ,OAAO;AACd,SAAM,IAAI,OACP,8CAA8C,MAAM;EAExD;CACF;CAED,AAAQ,uBAAgC;CACxC,AAAQ,eAAwB;CAChC,AAAQ,wBAAiC;;;;CAKzC,WAAWC,WAAsBC,SAAiBC,SAAuB;AACvE,OAAK,KAAK,gBAAgB,KAAK,gBAAgB,KAAK,aAClD;AAGF,MAAI;GAEF,MAAM,kBAAkB,UAAU;GAIlC,MAAM,WAAW,CAAC,eAAgB;GAGlC,MAAM,UACJ,AAAC,KAAK,aACJ,KAAK,aACL,WACA,GACA,SACA,GACA,GACA,GACA,UACA,KACD;AAEH,QAAK,QACH,OAAM,IAAI,MAAM;EAEnB,SAAQ,OAAO;AACd,SAAM;EACP;CACF;;;;CAKD,UAAgB;AACd,MAAI,KAAK,eAAe,KAAK,eAAe,KAAK,uBAAuB;AACtE,OAAI;AACF,IAAC,KAAK,sBAEQ,KAAK,YAAY;GAChC,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,6DACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,cAAc;AACnB,QAAK,cAAc;EACpB;CACF;AACF"}
1
+ {"version":3,"file":"ffi.node.js","names":["sourceName: string","eventType: EventType","eventId: number","params: string[]"],"sources":["../src/ffi.node.ts"],"sourcesContent":["import { getLogger } from \"@logtape/logtape\";\nimport koffi from \"koffi\";\nimport type { WindowsEventLogFFI } from \"./ffi.ts\";\nimport type { EventType } from \"./types.ts\";\n\n/**\n * Node.js FFI implementation for Windows Event Log API using koffi\n */\nexport class WindowsEventLogNodeFFI implements WindowsEventLogFFI {\n private eventSource: unknown = null;\n private sourceName: string = \"\"; // immediately overwritten in initialize;\n private initialized = false;\n private lib: unknown = null;\n private metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n /**\n * Initialize the FFI bindings and register event source\n */\n initialize(sourceName: string): void {\n this.sourceName = sourceName;\n if (this.initialized) return;\n\n try {\n // Load advapi32.dll\n this.lib = koffi.load(\"advapi32.dll\");\n\n // Define Windows API functions with correct koffi types using __stdcall convention\n const RegisterEventSourceA =\n (this.lib as unknown as { func: (sig: string) => unknown }).func(\n \"uintptr __stdcall RegisterEventSourceA(uintptr lpUNCServerName, str lpSourceName)\",\n );\n // ReportEventA expects LPCSTR* (array of string pointers) for lpStrings\n // Use char** for null-terminated array of strings\n const ReportEventA =\n (this.lib as unknown as { func: (sig: string) => unknown }).func(\n \"bool __stdcall ReportEventA(uintptr hEventLog, uint16 wType, uint16 wCategory, uint32 dwEventID, uintptr lpUserSid, uint16 wNumStrings, uint32 dwDataSize, char** lpStrings, uint8* lpRawData)\",\n );\n const DeregisterEventSource =\n (this.lib as unknown as { func: (sig: string) => unknown }).func(\n \"bool __stdcall DeregisterEventSource(uintptr hEventLog)\",\n );\n\n // Store functions\n this.RegisterEventSourceA = RegisterEventSourceA;\n this.ReportEventA = ReportEventA;\n this.DeregisterEventSource = DeregisterEventSource;\n\n // Register event source\n this.eventSource = (this.RegisterEventSourceA as unknown as (\n ...args: unknown[]\n ) => unknown)(0, this.sourceName);\n\n if (!this.eventSource || this.eventSource === 0) {\n throw new Error(\n `Failed to register event source: ${this.sourceName}`,\n );\n }\n\n this.initialized = true;\n } catch (error) {\n throw new Error(\n `Failed to initialize Windows Event Log FFI: ${error}`,\n );\n }\n }\n\n private RegisterEventSourceA: unknown = null;\n private ReportEventA: unknown = null;\n private DeregisterEventSource: unknown = null;\n\n /**\n * Write an event to Windows Event Log\n */\n writeEvent(eventType: EventType, eventId: number, params: string[]): void {\n if (!this.initialized || !this.eventSource || !this.ReportEventA) {\n return;\n }\n\n try {\n // Create null-terminated strings\n // In koffi, we pass an array of strings for char**\n const nullTerminatedParams = params.map((s) => s + \"\\0\");\n\n // Report the event using strings array approach\n const success =\n (this.ReportEventA as unknown as (...args: unknown[]) => unknown)(\n this.eventSource,\n eventType,\n 0, // category\n eventId,\n 0, // user SID (null)\n nullTerminatedParams.length, // number of strings\n 0, // data size (0 - not using raw data)\n nullTerminatedParams, // strings array with our message\n null, // raw data (null - not using)\n );\n\n if (!success) {\n throw new Error(\"ReportEventA() returned false.\");\n }\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Clean up resources\n */\n dispose(): void {\n if (this.initialized && this.eventSource && this.DeregisterEventSource) {\n try {\n (this.DeregisterEventSource as unknown as (\n ...args: unknown[]\n ) => unknown)(this.eventSource);\n } catch (error) {\n this.metaLogger.error(\n \"Failed to deregister event source during cleanup: {error}\",\n { error },\n );\n }\n this.eventSource = null;\n this.initialized = false;\n }\n }\n}\n"],"mappings":";;;;;;;AAQA,IAAa,yBAAb,MAAkE;CAChE,AAAQ,cAAuB;CAC/B,AAAQ,aAAqB;CAC7B,AAAQ,cAAc;CACtB,AAAQ,MAAe;CACvB,AAAQ,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;;;;CAKvE,WAAWA,YAA0B;AACnC,OAAK,aAAa;AAClB,MAAI,KAAK,YAAa;AAEtB,MAAI;AAEF,QAAK,MAAM,MAAM,KAAK,eAAe;GAGrC,MAAM,uBACJ,AAAC,KAAK,IAAsD,KAC1D,oFACD;GAGH,MAAM,eACJ,AAAC,KAAK,IAAsD,KAC1D,iMACD;GACH,MAAM,wBACJ,AAAC,KAAK,IAAsD,KAC1D,0DACD;AAGH,QAAK,uBAAuB;AAC5B,QAAK,eAAe;AACpB,QAAK,wBAAwB;AAG7B,QAAK,cAAc,AAAC,KAAK,qBAEX,GAAG,KAAK,WAAW;AAEjC,QAAK,KAAK,eAAe,KAAK,gBAAgB,EAC5C,OAAM,IAAI,OACP,mCAAmC,KAAK,WAAW;AAIxD,QAAK,cAAc;EACpB,SAAQ,OAAO;AACd,SAAM,IAAI,OACP,8CAA8C,MAAM;EAExD;CACF;CAED,AAAQ,uBAAgC;CACxC,AAAQ,eAAwB;CAChC,AAAQ,wBAAiC;;;;CAKzC,WAAWC,WAAsBC,SAAiBC,QAAwB;AACxE,OAAK,KAAK,gBAAgB,KAAK,gBAAgB,KAAK,aAClD;AAGF,MAAI;GAGF,MAAM,uBAAuB,OAAO,IAAI,CAAC,MAAM,IAAI,KAAK;GAGxD,MAAM,UACJ,AAAC,KAAK,aACJ,KAAK,aACL,WACA,GACA,SACA,GACA,qBAAqB,QACrB,GACA,sBACA,KACD;AAEH,QAAK,QACH,OAAM,IAAI,MAAM;EAEnB,SAAQ,OAAO;AACd,SAAM;EACP;CACF;;;;CAKD,UAAgB;AACd,MAAI,KAAK,eAAe,KAAK,eAAe,KAAK,uBAAuB;AACtE,OAAI;AACF,IAAC,KAAK,sBAEQ,KAAK,YAAY;GAChC,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,6DACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,cAAc;AACnB,QAAK,cAAc;EACpB;CACF;AACF"}
@@ -0,0 +1,38 @@
1
+
2
+ //#region src/formatter.ts
3
+ /**
4
+ * Formats a log record message into a string suitable for Windows Event Log.
5
+ * Combines the template and arguments into a readable message.
6
+ */
7
+ function formatMessage(record) {
8
+ let message = "";
9
+ for (let i = 0; i < record.message.length; i++) if (i % 2 === 0) message += record.message[i];
10
+ else {
11
+ const arg = record.message[i];
12
+ if (typeof arg === "string") message += arg;
13
+ else message += JSON.stringify(arg);
14
+ }
15
+ return message;
16
+ }
17
+ /**
18
+ * Formats additional context information for the log entry.
19
+ * Includes category, properties, and other metadata.
20
+ */
21
+ function formatContext(record) {
22
+ const context = [];
23
+ if (record.category && record.category.length > 0) context.push(`Category: ${record.category.join(".")}`);
24
+ if (record.properties && Object.keys(record.properties).length > 0) context.push(`Properties: ${JSON.stringify(record.properties)}`);
25
+ context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);
26
+ return context.length > 0 ? `\n\n${context.join("\n")}` : "";
27
+ }
28
+ /**
29
+ * Default way of rendering a record into text that goes in the event log.
30
+ */
31
+ function defaultWindowsEventlogFormatter(record) {
32
+ const msg = formatMessage(record);
33
+ const ctx = formatContext(record);
34
+ return msg + ctx;
35
+ }
36
+
37
+ //#endregion
38
+ exports.defaultWindowsEventlogFormatter = defaultWindowsEventlogFormatter;
@@ -0,0 +1,38 @@
1
+ //#region src/formatter.ts
2
+ /**
3
+ * Formats a log record message into a string suitable for Windows Event Log.
4
+ * Combines the template and arguments into a readable message.
5
+ */
6
+ function formatMessage(record) {
7
+ let message = "";
8
+ for (let i = 0; i < record.message.length; i++) if (i % 2 === 0) message += record.message[i];
9
+ else {
10
+ const arg = record.message[i];
11
+ if (typeof arg === "string") message += arg;
12
+ else message += JSON.stringify(arg);
13
+ }
14
+ return message;
15
+ }
16
+ /**
17
+ * Formats additional context information for the log entry.
18
+ * Includes category, properties, and other metadata.
19
+ */
20
+ function formatContext(record) {
21
+ const context = [];
22
+ if (record.category && record.category.length > 0) context.push(`Category: ${record.category.join(".")}`);
23
+ if (record.properties && Object.keys(record.properties).length > 0) context.push(`Properties: ${JSON.stringify(record.properties)}`);
24
+ context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);
25
+ return context.length > 0 ? `\n\n${context.join("\n")}` : "";
26
+ }
27
+ /**
28
+ * Default way of rendering a record into text that goes in the event log.
29
+ */
30
+ function defaultWindowsEventlogFormatter(record) {
31
+ const msg = formatMessage(record);
32
+ const ctx = formatContext(record);
33
+ return msg + ctx;
34
+ }
35
+
36
+ //#endregion
37
+ export { defaultWindowsEventlogFormatter };
38
+ //# sourceMappingURL=formatter.js.map