@verdaccio/middleware 9.0.0-next-9.20 → 9.0.0-next-9.21
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/build/middlewares/log.js +53 -37
- package/build/middlewares/log.js.map +1 -1
- package/build/middlewares/log.mjs +54 -38
- package/build/middlewares/log.mjs.map +1 -1
- package/build/middlewares/request-options.js +1 -7
- package/build/middlewares/request-options.js.map +1 -1
- package/build/middlewares/request-options.mjs +1 -5
- package/build/middlewares/request-options.mjs.map +1 -1
- package/package.json +6 -6
package/build/middlewares/log.js
CHANGED
|
@@ -6,11 +6,14 @@ let lodash_es = require("lodash-es");
|
|
|
6
6
|
//#region src/middlewares/log.ts
|
|
7
7
|
var debug$1 = (0, debug.default)("verdaccio:middleware:log");
|
|
8
8
|
function isStaticRequest(url) {
|
|
9
|
-
return url.startsWith("/-/static/");
|
|
9
|
+
return url.startsWith("/-/static/") || url.startsWith("/favicon");
|
|
10
|
+
}
|
|
11
|
+
var LOG_STATUS_MESSAGE = _verdaccio_core.constants.LOG_STATUS_MESSAGE;
|
|
12
|
+
var LOG_VERDACCIO_ERROR = _verdaccio_core.constants.LOG_VERDACCIO_ERROR;
|
|
13
|
+
var LOG_VERDACCIO_BYTES = _verdaccio_core.constants.LOG_VERDACCIO_BYTES;
|
|
14
|
+
function convertToDebugString(template) {
|
|
15
|
+
return template.replace(/@\{[^}]+\}/g, "%o");
|
|
10
16
|
}
|
|
11
|
-
var LOG_STATUS_MESSAGE = "@{status}, user: @{user}(@{remoteIP}), req: '@{request.method} @{request.url}'";
|
|
12
|
-
var LOG_VERDACCIO_ERROR = `${LOG_STATUS_MESSAGE}, error: @{!error}`;
|
|
13
|
-
var LOG_VERDACCIO_BYTES = `${LOG_STATUS_MESSAGE}, bytes: @{bytes.in}/@{bytes.out}`;
|
|
14
17
|
var log = (logger, options = {}) => {
|
|
15
18
|
const { hideStaticLogs = true } = options;
|
|
16
19
|
return function log(req, res, next) {
|
|
@@ -21,14 +24,12 @@ var log = (logger, options = {}) => {
|
|
|
21
24
|
if ((0, lodash_es.isNil)(_cookie) === false) req.headers.cookie = "<Classified>";
|
|
22
25
|
req.url = req.originalUrl;
|
|
23
26
|
const _skipLog = hideStaticLogs && isStaticRequest(req.url);
|
|
24
|
-
if (_skipLog)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
});
|
|
28
|
-
else req.log.info({
|
|
27
|
+
if (_skipLog) {
|
|
28
|
+
if (debug$1.enabled) debug$1(convertToDebugString(_verdaccio_core.constants.LOG_REQUEST_MESSAGE), req.ip, req.method, req.url);
|
|
29
|
+
} else req.log.info({
|
|
29
30
|
req,
|
|
30
31
|
ip: req.ip
|
|
31
|
-
},
|
|
32
|
+
}, _verdaccio_core.constants.LOG_REQUEST_MESSAGE);
|
|
32
33
|
req.originalUrl = req.url;
|
|
33
34
|
if ((0, lodash_es.isNil)(_auth) === false) req.headers.authorization = _auth;
|
|
34
35
|
if ((0, lodash_es.isNil)(_cookie) === false) req.headers.cookie = _cookie;
|
|
@@ -42,18 +43,16 @@ var log = (logger, options = {}) => {
|
|
|
42
43
|
bytesout += args[0]?.length || 0;
|
|
43
44
|
return _write.apply(res, args);
|
|
44
45
|
};
|
|
45
|
-
|
|
46
|
+
let requestCompleted = false;
|
|
47
|
+
let abortLogged = false;
|
|
48
|
+
const getRequestContext = () => {
|
|
46
49
|
const forwardedFor = req.get(_verdaccio_core.HEADERS.FORWARDED_FOR);
|
|
47
50
|
const remoteAddress = req.socket.remoteAddress;
|
|
48
51
|
const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;
|
|
49
|
-
|
|
50
|
-
if (res.locals._verdaccio_error) message = LOG_VERDACCIO_ERROR;
|
|
51
|
-
else message = LOG_VERDACCIO_BYTES;
|
|
52
|
-
req.url = req.originalUrl;
|
|
53
|
-
if (_skipLog) debug$1(message, {
|
|
52
|
+
return {
|
|
54
53
|
request: {
|
|
55
54
|
method: req.method,
|
|
56
|
-
url: req.
|
|
55
|
+
url: req.originalUrl
|
|
57
56
|
},
|
|
58
57
|
user: req.remote_user?.name || null,
|
|
59
58
|
remoteIP,
|
|
@@ -63,32 +62,49 @@ var log = (logger, options = {}) => {
|
|
|
63
62
|
in: bytesin,
|
|
64
63
|
out: bytesout
|
|
65
64
|
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
req.
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
const logAbortedRequest = () => {
|
|
68
|
+
if (abortLogged || requestCompleted) return;
|
|
69
|
+
abortLogged = true;
|
|
70
|
+
const context = {
|
|
71
|
+
...getRequestContext(),
|
|
72
|
+
status: _verdaccio_core.constants.HTTP_STATUS.CLIENT_CLOSED_REQUEST
|
|
73
|
+
};
|
|
74
|
+
if (_skipLog) {
|
|
75
|
+
if (debug$1.enabled) debug$1(convertToDebugString(_verdaccio_core.constants.LOG_VERDACCIO_ABORT), context.status, context.user, context.remoteIP, context.request.method, context.request.url);
|
|
76
|
+
} else req.log.info(context, _verdaccio_core.constants.LOG_VERDACCIO_ABORT);
|
|
77
|
+
};
|
|
78
|
+
const cleanupSocketListeners = () => {
|
|
79
|
+
req.socket.removeListener("close", onClose);
|
|
80
|
+
req.socket.removeListener("error", onError);
|
|
81
|
+
};
|
|
82
|
+
const onClose = () => {
|
|
83
|
+
if (!requestCompleted) logAbortedRequest();
|
|
84
|
+
cleanupSocketListeners();
|
|
85
|
+
};
|
|
86
|
+
const onError = () => {
|
|
87
|
+
if (!requestCompleted) logAbortedRequest();
|
|
88
|
+
cleanupSocketListeners();
|
|
89
|
+
};
|
|
90
|
+
const logCompletedRequest = () => {
|
|
91
|
+
requestCompleted = true;
|
|
92
|
+
const context = getRequestContext();
|
|
93
|
+
const message = context.error ? _verdaccio_core.constants.LOG_VERDACCIO_ERROR : _verdaccio_core.constants.LOG_VERDACCIO_BYTES;
|
|
94
|
+
if (_skipLog) {
|
|
95
|
+
if (debug$1.enabled) if (context.error) debug$1(convertToDebugString(message), context.status, context.user, context.remoteIP, context.request.method, context.request.url, context.error);
|
|
96
|
+
else debug$1(convertToDebugString(message), context.status, context.user, context.remoteIP, context.request.method, context.request.url, context.bytes.in, context.bytes.out);
|
|
97
|
+
} else req.log.http(context, message);
|
|
98
|
+
cleanupSocketListeners();
|
|
82
99
|
};
|
|
83
|
-
req.on("close", function() {
|
|
84
|
-
log();
|
|
85
|
-
});
|
|
86
100
|
const _end = res.end;
|
|
87
101
|
res.end = function(...args) {
|
|
88
102
|
if (args[0]) bytesout += args[0].length;
|
|
89
103
|
_end.apply(res, args);
|
|
90
|
-
|
|
104
|
+
logCompletedRequest();
|
|
91
105
|
};
|
|
106
|
+
req.socket.on("close", onClose);
|
|
107
|
+
req.socket.on("error", onError);
|
|
92
108
|
next();
|
|
93
109
|
};
|
|
94
110
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.js","names":[],"sources":["../../src/middlewares/log.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { isNil } from 'lodash-es';\n\nimport { HEADERS } from '@verdaccio/core';\n\nimport type { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\nconst debug = buildDebug('verdaccio:middleware:log');\n\nfunction isStaticRequest(url: string): boolean {\n return url.startsWith('/-/static/');\n}\n\n//
|
|
1
|
+
{"version":3,"file":"log.js","names":[],"sources":["../../src/middlewares/log.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { isNil } from 'lodash-es';\n\nimport { HEADERS, constants } from '@verdaccio/core';\n\nimport type { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\nconst debug = buildDebug('verdaccio:middleware:log');\n\nfunction isStaticRequest(url: string): boolean {\n return url.startsWith('/-/static/') || url.startsWith('/favicon');\n}\n\n// Keep export of constants for backward compatibility\nexport const LOG_STATUS_MESSAGE = constants.LOG_STATUS_MESSAGE;\nexport const LOG_VERDACCIO_ERROR = constants.LOG_VERDACCIO_ERROR;\nexport const LOG_VERDACCIO_BYTES = constants.LOG_VERDACCIO_BYTES;\n\n// Converts all @{...} to %o for debug compatibility\nfunction convertToDebugString(template: string): string {\n return template.replace(/@\\{[^}]+\\}/g, '%o');\n}\n\nexport type LogOptions = {\n // When true, static file requests (/-/static/*) are hidden from pino logs\n // and only visible via DEBUG=verdaccio:middleware:log. Defaults to true.\n hideStaticLogs?: boolean;\n};\n\nexport const log = (logger, options: LogOptions = {}) => {\n const { hideStaticLogs = true } = options;\n\n return function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {\n // logger\n req.log = logger.child({ sub: 'in' });\n\n const _auth = req.headers.authorization;\n if (isNil(_auth) === false) {\n req.headers.authorization = '<Classified>';\n }\n\n const _cookie = req.get('cookie');\n if (isNil(_cookie) === false) {\n req.headers.cookie = '<Classified>';\n }\n\n req.url = req.originalUrl;\n const _skipLog = hideStaticLogs && isStaticRequest(req.url);\n if (_skipLog) {\n if (debug.enabled) {\n debug(convertToDebugString(constants.LOG_REQUEST_MESSAGE), req.ip, req.method, req.url);\n }\n } else {\n req.log.info({ req, ip: req.ip }, constants.LOG_REQUEST_MESSAGE);\n }\n req.originalUrl = req.url;\n\n if (isNil(_auth) === false) {\n req.headers.authorization = _auth;\n }\n\n if (isNil(_cookie) === false) {\n req.headers.cookie = _cookie;\n }\n\n let bytesin = 0;\n req.on('data', function (chunk): void {\n bytesin += chunk.length;\n });\n\n let bytesout = 0;\n const _write = res.write;\n res.write = function (...args): boolean {\n bytesout += args[0]?.length || 0;\n // @ts-ignore\n return _write.apply(res, args);\n };\n\n // Track if the request completed normally\n let requestCompleted = false;\n let abortLogged = false;\n\n const getRequestContext = () => {\n const forwardedFor = req.get(HEADERS.FORWARDED_FOR);\n const remoteAddress = req.socket.remoteAddress;\n const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;\n return {\n request: {\n method: req.method,\n url: req.originalUrl,\n },\n user: req.remote_user?.name || null,\n remoteIP,\n status: res.statusCode,\n error: res.locals._verdaccio_error,\n bytes: {\n in: bytesin,\n out: bytesout,\n },\n };\n };\n\n const logAbortedRequest = () => {\n if (abortLogged || requestCompleted) return;\n abortLogged = true;\n\n const context = {\n ...getRequestContext(),\n status: constants.HTTP_STATUS.CLIENT_CLOSED_REQUEST,\n };\n\n if (_skipLog) {\n if (debug.enabled) {\n debug(\n convertToDebugString(constants.LOG_VERDACCIO_ABORT),\n context.status,\n context.user,\n context.remoteIP,\n context.request.method,\n context.request.url\n );\n }\n } else {\n req.log.info(context, constants.LOG_VERDACCIO_ABORT);\n }\n };\n\n const cleanupSocketListeners = () => {\n req.socket.removeListener('close', onClose);\n req.socket.removeListener('error', onError);\n };\n\n const onClose = () => {\n if (!requestCompleted) {\n logAbortedRequest();\n }\n cleanupSocketListeners();\n };\n\n const onError = () => {\n if (!requestCompleted) {\n logAbortedRequest();\n }\n cleanupSocketListeners();\n };\n\n const logCompletedRequest = () => {\n requestCompleted = true;\n\n const context = getRequestContext();\n const message = context.error ? constants.LOG_VERDACCIO_ERROR : constants.LOG_VERDACCIO_BYTES;\n\n if (_skipLog) {\n if (debug.enabled) {\n if (context.error) {\n debug(\n convertToDebugString(message),\n context.status,\n context.user,\n context.remoteIP,\n context.request.method,\n context.request.url,\n context.error\n );\n } else {\n debug(\n convertToDebugString(message),\n context.status,\n context.user,\n context.remoteIP,\n context.request.method,\n context.request.url,\n context.bytes.in,\n context.bytes.out\n );\n }\n }\n } else {\n req.log.http(context, message);\n }\n\n cleanupSocketListeners();\n };\n\n const _end = res.end;\n // @ts-ignore\n res.end = function (...args): void {\n if (args[0]) {\n bytesout += args[0].length;\n }\n // @ts-ignore\n _end.apply(res, args);\n logCompletedRequest();\n };\n\n req.socket.on('close', onClose);\n req.socket.on('error', onError);\n\n next();\n };\n};\n"],"mappings":"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"}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { HEADERS } from "@verdaccio/core";
|
|
1
|
+
import { HEADERS, constants } from "@verdaccio/core";
|
|
2
2
|
import buildDebug from "debug";
|
|
3
3
|
import { isNil } from "lodash-es";
|
|
4
4
|
//#region src/middlewares/log.ts
|
|
5
5
|
var debug = buildDebug("verdaccio:middleware:log");
|
|
6
6
|
function isStaticRequest(url) {
|
|
7
|
-
return url.startsWith("/-/static/");
|
|
7
|
+
return url.startsWith("/-/static/") || url.startsWith("/favicon");
|
|
8
|
+
}
|
|
9
|
+
var LOG_STATUS_MESSAGE = constants.LOG_STATUS_MESSAGE;
|
|
10
|
+
var LOG_VERDACCIO_ERROR = constants.LOG_VERDACCIO_ERROR;
|
|
11
|
+
var LOG_VERDACCIO_BYTES = constants.LOG_VERDACCIO_BYTES;
|
|
12
|
+
function convertToDebugString(template) {
|
|
13
|
+
return template.replace(/@\{[^}]+\}/g, "%o");
|
|
8
14
|
}
|
|
9
|
-
var LOG_STATUS_MESSAGE = "@{status}, user: @{user}(@{remoteIP}), req: '@{request.method} @{request.url}'";
|
|
10
|
-
var LOG_VERDACCIO_ERROR = `${LOG_STATUS_MESSAGE}, error: @{!error}`;
|
|
11
|
-
var LOG_VERDACCIO_BYTES = `${LOG_STATUS_MESSAGE}, bytes: @{bytes.in}/@{bytes.out}`;
|
|
12
15
|
var log = (logger, options = {}) => {
|
|
13
16
|
const { hideStaticLogs = true } = options;
|
|
14
17
|
return function log(req, res, next) {
|
|
@@ -19,14 +22,12 @@ var log = (logger, options = {}) => {
|
|
|
19
22
|
if (isNil(_cookie) === false) req.headers.cookie = "<Classified>";
|
|
20
23
|
req.url = req.originalUrl;
|
|
21
24
|
const _skipLog = hideStaticLogs && isStaticRequest(req.url);
|
|
22
|
-
if (_skipLog)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
26
|
-
else req.log.info({
|
|
25
|
+
if (_skipLog) {
|
|
26
|
+
if (debug.enabled) debug(convertToDebugString(constants.LOG_REQUEST_MESSAGE), req.ip, req.method, req.url);
|
|
27
|
+
} else req.log.info({
|
|
27
28
|
req,
|
|
28
29
|
ip: req.ip
|
|
29
|
-
},
|
|
30
|
+
}, constants.LOG_REQUEST_MESSAGE);
|
|
30
31
|
req.originalUrl = req.url;
|
|
31
32
|
if (isNil(_auth) === false) req.headers.authorization = _auth;
|
|
32
33
|
if (isNil(_cookie) === false) req.headers.cookie = _cookie;
|
|
@@ -40,18 +41,16 @@ var log = (logger, options = {}) => {
|
|
|
40
41
|
bytesout += args[0]?.length || 0;
|
|
41
42
|
return _write.apply(res, args);
|
|
42
43
|
};
|
|
43
|
-
|
|
44
|
+
let requestCompleted = false;
|
|
45
|
+
let abortLogged = false;
|
|
46
|
+
const getRequestContext = () => {
|
|
44
47
|
const forwardedFor = req.get(HEADERS.FORWARDED_FOR);
|
|
45
48
|
const remoteAddress = req.socket.remoteAddress;
|
|
46
49
|
const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;
|
|
47
|
-
|
|
48
|
-
if (res.locals._verdaccio_error) message = LOG_VERDACCIO_ERROR;
|
|
49
|
-
else message = LOG_VERDACCIO_BYTES;
|
|
50
|
-
req.url = req.originalUrl;
|
|
51
|
-
if (_skipLog) debug(message, {
|
|
50
|
+
return {
|
|
52
51
|
request: {
|
|
53
52
|
method: req.method,
|
|
54
|
-
url: req.
|
|
53
|
+
url: req.originalUrl
|
|
55
54
|
},
|
|
56
55
|
user: req.remote_user?.name || null,
|
|
57
56
|
remoteIP,
|
|
@@ -61,32 +60,49 @@ var log = (logger, options = {}) => {
|
|
|
61
60
|
in: bytesin,
|
|
62
61
|
out: bytesout
|
|
63
62
|
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
req.
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
const logAbortedRequest = () => {
|
|
66
|
+
if (abortLogged || requestCompleted) return;
|
|
67
|
+
abortLogged = true;
|
|
68
|
+
const context = {
|
|
69
|
+
...getRequestContext(),
|
|
70
|
+
status: constants.HTTP_STATUS.CLIENT_CLOSED_REQUEST
|
|
71
|
+
};
|
|
72
|
+
if (_skipLog) {
|
|
73
|
+
if (debug.enabled) debug(convertToDebugString(constants.LOG_VERDACCIO_ABORT), context.status, context.user, context.remoteIP, context.request.method, context.request.url);
|
|
74
|
+
} else req.log.info(context, constants.LOG_VERDACCIO_ABORT);
|
|
75
|
+
};
|
|
76
|
+
const cleanupSocketListeners = () => {
|
|
77
|
+
req.socket.removeListener("close", onClose);
|
|
78
|
+
req.socket.removeListener("error", onError);
|
|
79
|
+
};
|
|
80
|
+
const onClose = () => {
|
|
81
|
+
if (!requestCompleted) logAbortedRequest();
|
|
82
|
+
cleanupSocketListeners();
|
|
83
|
+
};
|
|
84
|
+
const onError = () => {
|
|
85
|
+
if (!requestCompleted) logAbortedRequest();
|
|
86
|
+
cleanupSocketListeners();
|
|
87
|
+
};
|
|
88
|
+
const logCompletedRequest = () => {
|
|
89
|
+
requestCompleted = true;
|
|
90
|
+
const context = getRequestContext();
|
|
91
|
+
const message = context.error ? constants.LOG_VERDACCIO_ERROR : constants.LOG_VERDACCIO_BYTES;
|
|
92
|
+
if (_skipLog) {
|
|
93
|
+
if (debug.enabled) if (context.error) debug(convertToDebugString(message), context.status, context.user, context.remoteIP, context.request.method, context.request.url, context.error);
|
|
94
|
+
else debug(convertToDebugString(message), context.status, context.user, context.remoteIP, context.request.method, context.request.url, context.bytes.in, context.bytes.out);
|
|
95
|
+
} else req.log.http(context, message);
|
|
96
|
+
cleanupSocketListeners();
|
|
80
97
|
};
|
|
81
|
-
req.on("close", function() {
|
|
82
|
-
log();
|
|
83
|
-
});
|
|
84
98
|
const _end = res.end;
|
|
85
99
|
res.end = function(...args) {
|
|
86
100
|
if (args[0]) bytesout += args[0].length;
|
|
87
101
|
_end.apply(res, args);
|
|
88
|
-
|
|
102
|
+
logCompletedRequest();
|
|
89
103
|
};
|
|
104
|
+
req.socket.on("close", onClose);
|
|
105
|
+
req.socket.on("error", onError);
|
|
90
106
|
next();
|
|
91
107
|
};
|
|
92
108
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.mjs","names":[],"sources":["../../src/middlewares/log.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { isNil } from 'lodash-es';\n\nimport { HEADERS } from '@verdaccio/core';\n\nimport type { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\nconst debug = buildDebug('verdaccio:middleware:log');\n\nfunction isStaticRequest(url: string): boolean {\n return url.startsWith('/-/static/');\n}\n\n//
|
|
1
|
+
{"version":3,"file":"log.mjs","names":[],"sources":["../../src/middlewares/log.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { isNil } from 'lodash-es';\n\nimport { HEADERS, constants } from '@verdaccio/core';\n\nimport type { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\nconst debug = buildDebug('verdaccio:middleware:log');\n\nfunction isStaticRequest(url: string): boolean {\n return url.startsWith('/-/static/') || url.startsWith('/favicon');\n}\n\n// Keep export of constants for backward compatibility\nexport const LOG_STATUS_MESSAGE = constants.LOG_STATUS_MESSAGE;\nexport const LOG_VERDACCIO_ERROR = constants.LOG_VERDACCIO_ERROR;\nexport const LOG_VERDACCIO_BYTES = constants.LOG_VERDACCIO_BYTES;\n\n// Converts all @{...} to %o for debug compatibility\nfunction convertToDebugString(template: string): string {\n return template.replace(/@\\{[^}]+\\}/g, '%o');\n}\n\nexport type LogOptions = {\n // When true, static file requests (/-/static/*) are hidden from pino logs\n // and only visible via DEBUG=verdaccio:middleware:log. Defaults to true.\n hideStaticLogs?: boolean;\n};\n\nexport const log = (logger, options: LogOptions = {}) => {\n const { hideStaticLogs = true } = options;\n\n return function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {\n // logger\n req.log = logger.child({ sub: 'in' });\n\n const _auth = req.headers.authorization;\n if (isNil(_auth) === false) {\n req.headers.authorization = '<Classified>';\n }\n\n const _cookie = req.get('cookie');\n if (isNil(_cookie) === false) {\n req.headers.cookie = '<Classified>';\n }\n\n req.url = req.originalUrl;\n const _skipLog = hideStaticLogs && isStaticRequest(req.url);\n if (_skipLog) {\n if (debug.enabled) {\n debug(convertToDebugString(constants.LOG_REQUEST_MESSAGE), req.ip, req.method, req.url);\n }\n } else {\n req.log.info({ req, ip: req.ip }, constants.LOG_REQUEST_MESSAGE);\n }\n req.originalUrl = req.url;\n\n if (isNil(_auth) === false) {\n req.headers.authorization = _auth;\n }\n\n if (isNil(_cookie) === false) {\n req.headers.cookie = _cookie;\n }\n\n let bytesin = 0;\n req.on('data', function (chunk): void {\n bytesin += chunk.length;\n });\n\n let bytesout = 0;\n const _write = res.write;\n res.write = function (...args): boolean {\n bytesout += args[0]?.length || 0;\n // @ts-ignore\n return _write.apply(res, args);\n };\n\n // Track if the request completed normally\n let requestCompleted = false;\n let abortLogged = false;\n\n const getRequestContext = () => {\n const forwardedFor = req.get(HEADERS.FORWARDED_FOR);\n const remoteAddress = req.socket.remoteAddress;\n const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;\n return {\n request: {\n method: req.method,\n url: req.originalUrl,\n },\n user: req.remote_user?.name || null,\n remoteIP,\n status: res.statusCode,\n error: res.locals._verdaccio_error,\n bytes: {\n in: bytesin,\n out: bytesout,\n },\n };\n };\n\n const logAbortedRequest = () => {\n if (abortLogged || requestCompleted) return;\n abortLogged = true;\n\n const context = {\n ...getRequestContext(),\n status: constants.HTTP_STATUS.CLIENT_CLOSED_REQUEST,\n };\n\n if (_skipLog) {\n if (debug.enabled) {\n debug(\n convertToDebugString(constants.LOG_VERDACCIO_ABORT),\n context.status,\n context.user,\n context.remoteIP,\n context.request.method,\n context.request.url\n );\n }\n } else {\n req.log.info(context, constants.LOG_VERDACCIO_ABORT);\n }\n };\n\n const cleanupSocketListeners = () => {\n req.socket.removeListener('close', onClose);\n req.socket.removeListener('error', onError);\n };\n\n const onClose = () => {\n if (!requestCompleted) {\n logAbortedRequest();\n }\n cleanupSocketListeners();\n };\n\n const onError = () => {\n if (!requestCompleted) {\n logAbortedRequest();\n }\n cleanupSocketListeners();\n };\n\n const logCompletedRequest = () => {\n requestCompleted = true;\n\n const context = getRequestContext();\n const message = context.error ? constants.LOG_VERDACCIO_ERROR : constants.LOG_VERDACCIO_BYTES;\n\n if (_skipLog) {\n if (debug.enabled) {\n if (context.error) {\n debug(\n convertToDebugString(message),\n context.status,\n context.user,\n context.remoteIP,\n context.request.method,\n context.request.url,\n context.error\n );\n } else {\n debug(\n convertToDebugString(message),\n context.status,\n context.user,\n context.remoteIP,\n context.request.method,\n context.request.url,\n context.bytes.in,\n context.bytes.out\n );\n }\n }\n } else {\n req.log.http(context, message);\n }\n\n cleanupSocketListeners();\n };\n\n const _end = res.end;\n // @ts-ignore\n res.end = function (...args): void {\n if (args[0]) {\n bytesout += args[0].length;\n }\n // @ts-ignore\n _end.apply(res, args);\n logCompletedRequest();\n };\n\n req.socket.on('close', onClose);\n req.socket.on('error', onError);\n\n next();\n };\n};\n"],"mappings":"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"}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
const require_runtime = require("../_virtual/_rolldown/runtime.js");
|
|
2
|
-
let debug = require("debug");
|
|
3
|
-
debug = require_runtime.__toESM(debug);
|
|
4
1
|
//#region src/middlewares/request-options.ts
|
|
5
|
-
var debug$1 = (0, debug.default)("verdaccio:middleware:request-options");
|
|
6
2
|
function getRequestOptions(req) {
|
|
7
|
-
|
|
3
|
+
return {
|
|
8
4
|
host: req.host,
|
|
9
5
|
protocol: req.protocol,
|
|
10
6
|
headers: req.headers,
|
|
@@ -12,8 +8,6 @@ function getRequestOptions(req) {
|
|
|
12
8
|
byPassCache: req.query.write === "true",
|
|
13
9
|
username: req.remote_user?.name ?? void 0
|
|
14
10
|
};
|
|
15
|
-
debug$1("request options: %o", requestOptions);
|
|
16
|
-
return requestOptions;
|
|
17
11
|
}
|
|
18
12
|
//#endregion
|
|
19
13
|
exports.getRequestOptions = getRequestOptions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-options.js","names":[],"sources":["../../src/middlewares/request-options.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"request-options.js","names":[],"sources":["../../src/middlewares/request-options.ts"],"sourcesContent":["import type { IncomingHttpHeaders } from 'node:http';\n\nimport type { RequestOptions } from '@verdaccio/url';\n\nimport type { $RequestExtend } from '../types';\n\nexport function getRequestOptions(req: $RequestExtend): RequestOptions {\n return {\n // Express 5:\n // - req.host is fully supported and includes the port\n // - https://expressjs.com/en/api.html#req.host\n host: req.host,\n protocol: req.protocol,\n headers: req.headers as IncomingHttpHeaders,\n remoteAddress: req.socket.remoteAddress,\n byPassCache: req.query.write === 'true',\n username: req.remote_user?.name ?? undefined,\n };\n}\n"],"mappings":";AAMA,SAAgB,kBAAkB,KAAqC;CACrE,OAAO;EAIL,MAAM,IAAI;EACV,UAAU,IAAI;EACd,SAAS,IAAI;EACb,eAAe,IAAI,OAAO;EAC1B,aAAa,IAAI,MAAM,UAAU;EACjC,UAAU,IAAI,aAAa,QAAQ,KAAA;CACrC;AACF"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import buildDebug from "debug";
|
|
2
1
|
//#region src/middlewares/request-options.ts
|
|
3
|
-
var debug = buildDebug("verdaccio:middleware:request-options");
|
|
4
2
|
function getRequestOptions(req) {
|
|
5
|
-
|
|
3
|
+
return {
|
|
6
4
|
host: req.host,
|
|
7
5
|
protocol: req.protocol,
|
|
8
6
|
headers: req.headers,
|
|
@@ -10,8 +8,6 @@ function getRequestOptions(req) {
|
|
|
10
8
|
byPassCache: req.query.write === "true",
|
|
11
9
|
username: req.remote_user?.name ?? void 0
|
|
12
10
|
};
|
|
13
|
-
debug("request options: %o", requestOptions);
|
|
14
|
-
return requestOptions;
|
|
15
11
|
}
|
|
16
12
|
//#endregion
|
|
17
13
|
export { getRequestOptions };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-options.mjs","names":[],"sources":["../../src/middlewares/request-options.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"request-options.mjs","names":[],"sources":["../../src/middlewares/request-options.ts"],"sourcesContent":["import type { IncomingHttpHeaders } from 'node:http';\n\nimport type { RequestOptions } from '@verdaccio/url';\n\nimport type { $RequestExtend } from '../types';\n\nexport function getRequestOptions(req: $RequestExtend): RequestOptions {\n return {\n // Express 5:\n // - req.host is fully supported and includes the port\n // - https://expressjs.com/en/api.html#req.host\n host: req.host,\n protocol: req.protocol,\n headers: req.headers as IncomingHttpHeaders,\n remoteAddress: req.socket.remoteAddress,\n byPassCache: req.query.write === 'true',\n username: req.remote_user?.name ?? undefined,\n };\n}\n"],"mappings":";AAMA,SAAgB,kBAAkB,KAAqC;CACrE,OAAO;EAIL,MAAM,IAAI;EACV,UAAU,IAAI;EACd,SAAS,IAAI;EACb,eAAe,IAAI,OAAO;EAC1B,aAAa,IAAI,MAAM,UAAU;EACjC,UAAU,IAAI,aAAa,QAAQ,KAAA;CACrC;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/middleware",
|
|
3
|
-
"version": "9.0.0-next-9.
|
|
3
|
+
"version": "9.0.0-next-9.21",
|
|
4
4
|
"description": "Verdaccio Express Middleware",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"node": ">=24"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@verdaccio/config": "9.0.0-next-9.
|
|
37
|
-
"@verdaccio/core": "9.0.0-next-9.
|
|
38
|
-
"@verdaccio/url": "14.0.0-next-9.
|
|
36
|
+
"@verdaccio/config": "9.0.0-next-9.21",
|
|
37
|
+
"@verdaccio/core": "9.0.0-next-9.21",
|
|
38
|
+
"@verdaccio/url": "14.0.0-next-9.21",
|
|
39
39
|
"debug": "4.4.3",
|
|
40
40
|
"express": "5.2.1",
|
|
41
41
|
"express-rate-limit": "8.5.2",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/lodash-es": "4.17.12",
|
|
51
|
-
"@verdaccio/logger": "9.0.0-next-9.
|
|
51
|
+
"@verdaccio/logger": "9.0.0-next-9.21",
|
|
52
52
|
"@verdaccio/types": "14.0.0-next-9.11",
|
|
53
53
|
"http-errors": "2.0.1",
|
|
54
54
|
"supertest": "7.1.4",
|
|
55
55
|
"rimraf": "6.1.3",
|
|
56
|
-
"vite": "8.0.
|
|
56
|
+
"vite": "8.0.16",
|
|
57
57
|
"vitest": "4.1.7"
|
|
58
58
|
},
|
|
59
59
|
"module": "./build/index.mjs",
|