Skip to content

Commit 09deb86

Browse files
committed
Add type declarations
1 parent f7eaddc commit 09deb86

7 files changed

Lines changed: 302 additions & 120 deletions

File tree

index.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ const internals = {
55
instances: {}
66
};
77

8-
/**
9-
* @param {string} [name]
10-
* @param {import('./lib/logger').LoggerOptions} [opts]
11-
* @returns {Logger}
12-
*/
138
module.exports = function (name, opts) {
149
name = name || '_default';
1510
if (typeof (name) === 'object') {

index.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import type {Server, Request} from '@hapi/hapi';
2+
3+
declare namespace hapiLog {
4+
interface LogHandler {
5+
log(message: string): void;
6+
}
7+
8+
interface RequestInfo {
9+
remoteAddress: string;
10+
host: string;
11+
path: string;
12+
method: string;
13+
query: Record<string, unknown>;
14+
statusCode: number;
15+
responseTime: number;
16+
userAgent?: string;
17+
contentLength?: string;
18+
referer?: string;
19+
}
20+
21+
interface LogData {
22+
timestamp: number;
23+
tags: string[];
24+
log?: unknown;
25+
requestInfo?: RequestInfo;
26+
data?: Record<string, unknown>;
27+
}
28+
29+
interface LoggerOptions {
30+
handler?: LogHandler;
31+
meta?: (request?: Request) => Record<string, unknown> | undefined;
32+
formatTimestamp?: (timestamp: number) => string;
33+
jsonOutput?: boolean;
34+
requestInfoFilter?: (requestInfo: RequestInfo) => RequestInfo;
35+
}
36+
37+
interface PluginOptions extends LoggerOptions {
38+
name?: string;
39+
ignorePaths?: string[];
40+
ignoreMethods?: string[];
41+
onPreResponseError?: boolean;
42+
}
43+
44+
class Logger {
45+
constructor(options?: LoggerOptions);
46+
47+
readonly formatTime: (timestamp: number) => string;
48+
49+
handleError(request: Request, data: {error: Error}): void;
50+
handleRequest(request: Request, event: {timestamp: number; tags: string[]; data?: unknown; error?: Error}): void;
51+
handleResponse(request: Request): void;
52+
handleLog(event: {timestamp: number; tags: string[]; data?: unknown; error?: Error}): void;
53+
log(tags: string | string[], ...messages: unknown[]): void;
54+
formatter(obj: LogData): string;
55+
humanReadableFormatter(obj: LogData): string;
56+
stringifyRequestInfo(data: RequestInfo): string;
57+
write(obj: LogData): void;
58+
}
59+
60+
const plugin: {
61+
name: string;
62+
register(server: Server, options?: PluginOptions): void;
63+
};
64+
}
65+
66+
declare function hapiLog(name?: string | hapiLog.LoggerOptions, opts?: hapiLog.LoggerOptions): hapiLog.Logger;
67+
68+
export = hapiLog;

lib/logger.js

Lines changed: 0 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -14,104 +14,30 @@ const internals = {
1414
};
1515

1616

17-
/**
18-
* Default meta data to append to logs
19-
* @param {HapiRequest} [request]
20-
* @return {Record<string, unknown>|undefined}
21-
*/
2217
function defaultMeta(request) {
2318
if (!request) {
2419
return;
2520
}
2621
return {requestId: request.info.id};
2722
}
2823

29-
/**
30-
* defaultHandler for outputing the logs
31-
* @return {object}
32-
*/
3324
function defaultHandler() {
3425
return {
35-
/**
36-
* @param {string} str
37-
*/
3826
log(str) {
3927
process.stdout.write(str + '\n');
4028
}
4129
};
4230
}
4331

44-
/**
45-
* @typedef {object} RequestInfo
46-
* @property {string} remoteAddress
47-
* @property {string} host
48-
* @property {string} path
49-
* @property {string} method
50-
* @property {object} query
51-
* @property {number} statusCode
52-
* @property {number} responseTime
53-
* @property {string} [userAgent]
54-
* @property {string} [contentLength]
55-
* @property {string} [referer]
56-
*/
57-
58-
/**
59-
* @typedef {object} HapiRequest - Hapi request object
60-
* @property {object} request.info - Request information
61-
* @property {string} request.info.id - Unique request identifier
62-
* @property {string} request.info.remoteAddress - Client IP address
63-
* @property {string} request.info.hostname - Request hostname
64-
* @property {number} request.info.received - Timestamp when request was received
65-
* @property {string} request.path - Request path
66-
* @property {string} request.method - HTTP method
67-
* @property {Record<string, unknown>} request.query - Query propertyeters
68-
* @property {Record<string, string>} request.headers - Request headers
69-
* @property {object} request.raw - Raw request/response objects
70-
* @property {object} request.raw.req - Raw Node.js request object
71-
* @property {Record<string, string>} request.raw.req.headers - Raw request headers
72-
* @property {object} request.raw.res - Raw Node.js response object
73-
* @property {number} request.raw.res.statusCode - HTTP status code
74-
* @property {object} [request.response] - Hapi response object
75-
* @property {Record<string, string>} [request.response.headers] - Response headers
76-
*/
77-
78-
/**
79-
* @typedef {object} LogData
80-
* @property {number} timestamp when the log event occured
81-
* @property {string[]} tags
82-
* @property {object|string} [log] the log message or object
83-
* @property {RequestInfo} [requestInfo]
84-
* @property {object} [data] optional meta data
85-
*/
86-
87-
/**
88-
* @typedef {object} LoggerOptions
89-
* @property {{log: (message: string) => void}} [handler] Handler implementing `log(message)` method, defaults to console logging
90-
* @property {(request?: HapiRequest) => Record<string, unknown>} [meta] Should return meta data as an Object that is appended to logs. Default returns {requestId:request.info.id} This function doesnt always recieve request object.
91-
* @property {(timestamp: number) => string} [formatTime]
92-
* @property {boolean} [jsonOutput] output all data as stringified json
93-
*/
94-
9532
class Logger {
9633

97-
/**
98-
* Creates a new Logger
99-
*
100-
* @class Logger
101-
* @param {LoggerOptions} [options]
102-
*/
10334
constructor(options) {
10435
this.opts = {...internals.defaults, ...options};
10536
this.handler = this.opts.handler || defaultHandler();
10637
this.meta = this.opts.meta || defaultMeta;
10738
this.formatTime = this.opts.formatTimestamp;
10839
}
10940

110-
/**
111-
* Handle Error
112-
* @param {HapiRequest} request
113-
* @param {object} data
114-
*/
11541
handleError(request, data) {
11642
this.write({
11743
timestamp: Date.now(),
@@ -121,11 +47,6 @@ class Logger {
12147
});
12248
}
12349

124-
/**
125-
* Handle 'request' event
126-
* @param {HapiRequest} request
127-
* @param {object} event
128-
*/
12950
handleRequest(request, event) {
13051
this.write({
13152
timestamp: event.timestamp,
@@ -135,10 +56,6 @@ class Logger {
13556
});
13657
}
13758

138-
/**
139-
* Handle 'response' event
140-
* @param {HapiRequest} request
141-
*/
14259
handleResponse(request) {
14360
const referer = request.raw.req.headers.referer;
14461
const contentLength = request.response?.headers?.['content-length'];
@@ -150,7 +67,6 @@ class Logger {
15067
remoteAddress = xFF.split(',')[0];
15168
}
15269

153-
/** @type {RequestInfo} */
15470
const requestInfo = {
15571
remoteAddress,
15672
host: request.info.hostname,
@@ -178,11 +94,6 @@ class Logger {
17894
});
17995
}
18096

181-
/**
182-
* Format RequestInfo to a human friendly string
183-
* @param {RequestInfo} data
184-
* @return {string}
185-
*/
18697
stringifyRequestInfo(data) {
18798
return printf(
18899
'%s, %s %s %s %s %s (%sms), %s%s',
@@ -198,10 +109,6 @@ class Logger {
198109
);
199110
}
200111

201-
/**
202-
* Handle 'log' event
203-
* @param {object} event
204-
*/
205112
handleLog(event) {
206113
this.write({
207114
timestamp: event.timestamp,
@@ -210,11 +117,6 @@ class Logger {
210117
});
211118
}
212119

213-
/**
214-
* Format log data to human readable string
215-
* @param {LogData} obj
216-
* @return {string}
217-
*/
218120
humanReadableFormatter(obj) {
219121
let log;
220122
if (obj.requestInfo) {
@@ -233,11 +135,6 @@ class Logger {
233135
);
234136
}
235137

236-
/**
237-
* Formats Log to a string
238-
* @param {LogData} obj
239-
* @return {String}
240-
*/
241138
formatter(obj) {
242139
if (!this.opts.jsonOutput) {
243140
return this.humanReadableFormatter(obj);
@@ -263,19 +160,10 @@ class Logger {
263160
return stringify(formatted);
264161
}
265162

266-
/**
267-
* Formats and writes the log data
268-
* @param {LogData} obj
269-
*/
270163
write(obj) {
271164
this.handler.log(this.formatter(obj));
272165
}
273166

274-
/**
275-
* Add a log entry
276-
* @param {Array|String} tags
277-
* @param {Object|String} messages
278-
*/
279167
log(tags, ...messages) {
280168
// only apply printf if it has multiple messages
281169
// we want to be able to handle a single error objects for jsonOutput differently

0 commit comments

Comments
 (0)