@verdaccio/logger 9.0.0-next-9.3 → 9.0.0-next-9.5
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/CHANGELOG.md +1121 -0
- package/build/_virtual/_rolldown/runtime.js +23 -0
- package/build/_virtual/_rolldown/runtime.mjs +7 -0
- package/build/colors.d.ts +1 -0
- package/build/colors.js +11 -0
- package/build/colors.js.map +1 -0
- package/build/colors.mjs +10 -0
- package/build/colors.mjs.map +1 -0
- package/build/formatter.d.ts +10 -0
- package/build/formatter.js +47 -0
- package/build/formatter.js.map +1 -0
- package/build/formatter.mjs +45 -0
- package/build/formatter.mjs.map +1 -0
- package/build/index.d.ts +13 -2
- package/build/index.js +43 -15
- package/build/index.js.map +1 -1
- package/build/index.mjs +21 -0
- package/build/index.mjs.map +1 -0
- package/build/levels.d.ts +35 -0
- package/build/levels.js +53 -0
- package/build/levels.js.map +1 -0
- package/build/levels.mjs +50 -0
- package/build/levels.mjs.map +1 -0
- package/build/logger.d.ts +9 -0
- package/build/logger.js +86 -0
- package/build/logger.js.map +1 -0
- package/build/logger.mjs +82 -0
- package/build/logger.mjs.map +1 -0
- package/build/prettify.d.ts +20 -0
- package/build/prettify.js +91 -0
- package/build/prettify.js.map +1 -0
- package/build/prettify.mjs +86 -0
- package/build/prettify.mjs.map +1 -0
- package/build/transport.d.ts +6 -0
- package/build/transport.js +33 -0
- package/build/transport.js.map +1 -0
- package/build/transport.mjs +31 -0
- package/build/transport.mjs.map +1 -0
- package/build/types.d.ts +5 -0
- package/build/utils.d.ts +5 -0
- package/build/utils.js +20 -0
- package/build/utils.js.map +1 -0
- package/build/utils.mjs +16 -0
- package/build/utils.mjs.map +1 -0
- package/package.json +30 -11
- package/src/colors.ts +8 -0
- package/src/formatter.ts +90 -0
- package/src/index.ts +28 -0
- package/src/levels.ts +60 -0
- package/src/logger.ts +126 -0
- package/src/prettify.ts +119 -0
- package/src/transport.ts +39 -0
- package/src/types.ts +6 -0
- package/src/utils.ts +18 -0
- package/test/__snapshots__/formatter.spec.ts.snap +21 -0
- package/test/createLogger.spec.ts +22 -0
- package/test/formatter.spec.ts +214 -0
- package/test/index.spec.ts +49 -0
- package/test/logger.spec.ts +368 -0
- package/test/prettify.spec.ts +387 -0
- package/test/transport.spec.ts +108 -0
- package/test/utils.test.ts +19 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +16 -0
- package/vite.config.mjs +3 -0
package/build/logger.mjs
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { fillInMsgTemplate } from "./formatter.mjs";
|
|
2
|
+
import { createPrettyTransport, isPrettyFormat } from "./transport.mjs";
|
|
3
|
+
import buildDebug from "debug";
|
|
4
|
+
//#region src/logger.ts
|
|
5
|
+
var debug = buildDebug("verdaccio:logger");
|
|
6
|
+
function isProd() {
|
|
7
|
+
return process.env.NODE_ENV === "production";
|
|
8
|
+
}
|
|
9
|
+
var DEFAULT_LOG_FORMAT = isProd() ? "json" : "pretty";
|
|
10
|
+
debug("default log format: %s", DEFAULT_LOG_FORMAT);
|
|
11
|
+
function createLogger(options = { level: "http" }, destination, format = DEFAULT_LOG_FORMAT, pino) {
|
|
12
|
+
debug("setup logger");
|
|
13
|
+
let pinoConfig = {
|
|
14
|
+
customLevels: { http: 25 },
|
|
15
|
+
level: options.level,
|
|
16
|
+
serializers: {
|
|
17
|
+
err: pino.stdSerializers.err,
|
|
18
|
+
req: pino.stdSerializers.req,
|
|
19
|
+
res: pino.stdSerializers.res
|
|
20
|
+
},
|
|
21
|
+
redact: options.redact
|
|
22
|
+
};
|
|
23
|
+
debug("has prettifier? %o", !isProd());
|
|
24
|
+
let logger;
|
|
25
|
+
if (isPrettyFormat(format) && isProd() === false) {
|
|
26
|
+
const transport = createPrettyTransport(pino, options, format);
|
|
27
|
+
logger = pino(pinoConfig, transport);
|
|
28
|
+
} else {
|
|
29
|
+
pinoConfig = {
|
|
30
|
+
...pinoConfig,
|
|
31
|
+
hooks: { logMethod(args, method, _level) {
|
|
32
|
+
const [templateObject, message, ...otherArgs] = args;
|
|
33
|
+
if (!message || !(!!templateObject && typeof templateObject === "object" ? Object.getOwnPropertyNames(templateObject) : []).length) return method.apply(this, args);
|
|
34
|
+
const hydratedMessage = fillInMsgTemplate(message, templateObject, false);
|
|
35
|
+
return method.apply(this, [
|
|
36
|
+
templateObject,
|
|
37
|
+
hydratedMessage,
|
|
38
|
+
...otherArgs
|
|
39
|
+
]);
|
|
40
|
+
} }
|
|
41
|
+
};
|
|
42
|
+
logger = pino(pinoConfig, destination);
|
|
43
|
+
}
|
|
44
|
+
if (process.env.DEBUG) logger.on("level-change", (lvl, val, prevLvl, prevVal, instance) => {
|
|
45
|
+
if (logger !== instance) return;
|
|
46
|
+
debug("%s (%d) was changed to %s (%d)", lvl, val, prevLvl, prevVal);
|
|
47
|
+
});
|
|
48
|
+
return logger;
|
|
49
|
+
}
|
|
50
|
+
var DEFAULT_LOGGER_CONF = {
|
|
51
|
+
type: "stdout",
|
|
52
|
+
format: "pretty",
|
|
53
|
+
level: "http"
|
|
54
|
+
};
|
|
55
|
+
function willUseTransport(format) {
|
|
56
|
+
return isPrettyFormat(format ?? (isProd() ? "json" : "pretty")) && isProd() === false;
|
|
57
|
+
}
|
|
58
|
+
async function prepareSetup(options = DEFAULT_LOGGER_CONF, pino) {
|
|
59
|
+
let loggerConfig = options;
|
|
60
|
+
if (!loggerConfig?.level) loggerConfig = {
|
|
61
|
+
...loggerConfig,
|
|
62
|
+
level: "http"
|
|
63
|
+
};
|
|
64
|
+
if (loggerConfig.type === "file") {
|
|
65
|
+
debug("logging file enabled");
|
|
66
|
+
if (willUseTransport(loggerConfig.format)) return createLogger(loggerConfig, void 0, loggerConfig.format, pino);
|
|
67
|
+
const destination = pino.destination(loggerConfig.path);
|
|
68
|
+
await new Promise((resolve, reject) => {
|
|
69
|
+
destination.once("ready", resolve);
|
|
70
|
+
destination.once("error", reject);
|
|
71
|
+
});
|
|
72
|
+
debug("file destination ready: %s", loggerConfig.path);
|
|
73
|
+
process.on("SIGUSR2", () => destination.reopen());
|
|
74
|
+
return createLogger(loggerConfig, destination, loggerConfig.format, pino);
|
|
75
|
+
}
|
|
76
|
+
debug("logging stdout enabled");
|
|
77
|
+
return createLogger(loggerConfig, pino.destination(1), loggerConfig.format, pino);
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
export { createLogger, prepareSetup, willUseTransport };
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=logger.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.mjs","names":[],"sources":["../src/logger.ts"],"sourcesContent":["// <reference types=\"node\" />\nimport buildDebug from 'debug';\nimport type { LoggerOptions } from 'pino';\n\nimport type { Logger, LoggerConfigItem, LoggerFormat } from '@verdaccio/types';\n\nimport { fillInMsgTemplate } from './formatter';\nimport { createPrettyTransport, isPrettyFormat } from './transport';\n\nconst debug = buildDebug('verdaccio:logger');\n\nfunction isProd() {\n return process.env.NODE_ENV === 'production';\n}\n\nconst DEFAULT_LOG_FORMAT = isProd() ? 'json' : 'pretty';\ndebug('default log format: %s', DEFAULT_LOG_FORMAT);\n\nexport type LogPlugin = {\n dest: string;\n options?: any[];\n};\n\nexport function createLogger(\n options: LoggerConfigItem = { level: 'http' },\n destination: NodeJS.WritableStream | undefined,\n format: LoggerFormat = DEFAULT_LOG_FORMAT,\n pino\n): any {\n debug('setup logger');\n let pinoConfig: LoggerOptions = {\n customLevels: {\n http: 25,\n },\n level: options.level,\n serializers: {\n err: pino.stdSerializers.err,\n req: pino.stdSerializers.req,\n res: pino.stdSerializers.res,\n },\n redact: options.redact,\n };\n\n debug('has prettifier? %o', !isProd());\n let logger;\n // pretty logs are not allowed in production for performance reasons\n if (isPrettyFormat(format) && isProd() === false) {\n const transport = createPrettyTransport(pino, options, format);\n logger = pino(pinoConfig, transport);\n } else {\n pinoConfig = {\n ...pinoConfig,\n // https://getpino.io/#/docs/api?id=hooks-object\n hooks: {\n logMethod(args: [obj: unknown, msg?: string, ...rest: unknown[]], method, _level) {\n const [templateObject, message, ...otherArgs] = args;\n const templateVars =\n !!templateObject && typeof templateObject === 'object'\n ? Object.getOwnPropertyNames(templateObject)\n : [];\n if (!message || !templateVars.length) return method.apply(this, args);\n const hydratedMessage = fillInMsgTemplate(message, templateObject as any, false);\n return method.apply(this, [templateObject, hydratedMessage, ...otherArgs] as any);\n },\n },\n };\n logger = pino(pinoConfig, destination);\n }\n\n if (process.env.DEBUG) {\n logger.on('level-change', (lvl, val, prevLvl, prevVal, instance) => {\n if (logger !== instance) {\n return;\n }\n debug('%s (%d) was changed to %s (%d)', lvl, val, prevLvl, prevVal);\n });\n }\n\n return logger;\n}\n\nconst DEFAULT_LOGGER_CONF: LoggerConfigItem = {\n type: 'stdout',\n format: 'pretty',\n level: 'http',\n};\n\nexport type LoggerConfig = LoggerConfigItem;\n\nexport function willUseTransport(format: LoggerFormat | undefined): boolean {\n const resolvedFormat = format ?? (isProd() ? 'json' : 'pretty');\n return isPrettyFormat(resolvedFormat) && isProd() === false;\n}\n\nexport async function prepareSetup(\n options: LoggerConfigItem = DEFAULT_LOGGER_CONF,\n pino\n): Promise<Logger> {\n let loggerConfig = options;\n if (!loggerConfig?.level) {\n loggerConfig = {\n ...loggerConfig,\n level: 'http',\n };\n }\n if (loggerConfig.type === 'file') {\n debug('logging file enabled');\n // Pretty format uses a pino transport that creates its own destination stream,\n // so no destination is needed here.\n if (willUseTransport(loggerConfig.format)) {\n return createLogger(loggerConfig, undefined, loggerConfig.format, pino);\n }\n // For file destinations (json format), wait for the fd to be ready\n // so we fail fast on bad paths / permissions instead of losing early logs\n const destination = pino.destination(loggerConfig.path);\n await new Promise<void>((resolve, reject) => {\n destination.once('ready', resolve);\n destination.once('error', reject);\n });\n debug('file destination ready: %s', loggerConfig.path);\n process.on('SIGUSR2', () => destination.reopen());\n return createLogger(loggerConfig, destination, loggerConfig.format, pino);\n }\n debug('logging stdout enabled');\n return createLogger(loggerConfig, pino.destination(1), loggerConfig.format, pino);\n}\n"],"mappings":";;;;AASA,IAAM,QAAQ,WAAW,mBAAmB;AAE5C,SAAS,SAAS;AAChB,QAAA,QAAA,IAAA,aAAgC;;AAGlC,IAAM,qBAAqB,QAAQ,GAAG,SAAS;AAC/C,MAAM,0BAA0B,mBAAmB;AAOnD,SAAgB,aACd,UAA4B,EAAE,OAAO,QAAQ,EAC7C,aACA,SAAuB,oBACvB,MACK;AACL,OAAM,eAAe;CACrB,IAAI,aAA4B;EAC9B,cAAc,EACZ,MAAM,IACP;EACD,OAAO,QAAQ;EACf,aAAa;GACX,KAAK,KAAK,eAAe;GACzB,KAAK,KAAK,eAAe;GACzB,KAAK,KAAK,eAAe;GAC1B;EACD,QAAQ,QAAQ;EACjB;AAED,OAAM,sBAAsB,CAAC,QAAQ,CAAC;CACtC,IAAI;AAEJ,KAAI,eAAe,OAAO,IAAI,QAAQ,KAAK,OAAO;EAChD,MAAM,YAAY,sBAAsB,MAAM,SAAS,OAAO;AAC9D,WAAS,KAAK,YAAY,UAAU;QAC/B;AACL,eAAa;GACX,GAAG;GAEH,OAAO,EACL,UAAU,MAAwD,QAAQ,QAAQ;IAChF,MAAM,CAAC,gBAAgB,SAAS,GAAG,aAAa;AAKhD,QAAI,CAAC,WAAW,EAHd,CAAC,CAAC,kBAAkB,OAAO,mBAAmB,WAC1C,OAAO,oBAAoB,eAAe,GAC1C,EAAE,EACsB,OAAQ,QAAO,OAAO,MAAM,MAAM,KAAK;IACrE,MAAM,kBAAkB,kBAAkB,SAAS,gBAAuB,MAAM;AAChF,WAAO,OAAO,MAAM,MAAM;KAAC;KAAgB;KAAiB,GAAG;KAAU,CAAQ;MAEpF;GACF;AACD,WAAS,KAAK,YAAY,YAAY;;AAGxC,KAAI,QAAQ,IAAI,MACd,QAAO,GAAG,iBAAiB,KAAK,KAAK,SAAS,SAAS,aAAa;AAClE,MAAI,WAAW,SACb;AAEF,QAAM,kCAAkC,KAAK,KAAK,SAAS,QAAQ;GACnE;AAGJ,QAAO;;AAGT,IAAM,sBAAwC;CAC5C,MAAM;CACN,QAAQ;CACR,OAAO;CACR;AAID,SAAgB,iBAAiB,QAA2C;AAE1E,QAAO,eADgB,WAAW,QAAQ,GAAG,SAAS,UACjB,IAAI,QAAQ,KAAK;;AAGxD,eAAsB,aACpB,UAA4B,qBAC5B,MACiB;CACjB,IAAI,eAAe;AACnB,KAAI,CAAC,cAAc,MACjB,gBAAe;EACb,GAAG;EACH,OAAO;EACR;AAEH,KAAI,aAAa,SAAS,QAAQ;AAChC,QAAM,uBAAuB;AAG7B,MAAI,iBAAiB,aAAa,OAAO,CACvC,QAAO,aAAa,cAAc,KAAA,GAAW,aAAa,QAAQ,KAAK;EAIzE,MAAM,cAAc,KAAK,YAAY,aAAa,KAAK;AACvD,QAAM,IAAI,SAAe,SAAS,WAAW;AAC3C,eAAY,KAAK,SAAS,QAAQ;AAClC,eAAY,KAAK,SAAS,OAAO;IACjC;AACF,QAAM,8BAA8B,aAAa,KAAK;AACtD,UAAQ,GAAG,iBAAiB,YAAY,QAAQ,CAAC;AACjD,SAAO,aAAa,cAAc,aAAa,aAAa,QAAQ,KAAK;;AAE3E,OAAM,yBAAyB;AAC/B,QAAO,aAAa,cAAc,KAAK,YAAY,EAAE,EAAE,aAAa,QAAQ,KAAK"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Transform } from 'node:stream';
|
|
2
|
+
import { default as build } from 'pino-abstract-transport';
|
|
3
|
+
import { SonicBoomOpts, default as SonicBoom } from 'sonic-boom';
|
|
4
|
+
import { fillInMsgTemplate } from './formatter';
|
|
5
|
+
import { PrettyOptionsExtended } from './types';
|
|
6
|
+
export { fillInMsgTemplate };
|
|
7
|
+
/**
|
|
8
|
+
* Creates a safe SonicBoom instance
|
|
9
|
+
*
|
|
10
|
+
* @param {object} opts Options for SonicBoom
|
|
11
|
+
*
|
|
12
|
+
* @returns {object} A new SonicBoom stream
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildSafeSonicBoom(opts: SonicBoomOpts): SonicBoom;
|
|
15
|
+
export declare function autoEnd(stream: SonicBoom & {
|
|
16
|
+
destroyed?: boolean;
|
|
17
|
+
}, eventName: string): void;
|
|
18
|
+
export { hasColors } from './colors';
|
|
19
|
+
export declare function buildPretty(opts: PrettyOptionsExtended): (chunk: any) => string;
|
|
20
|
+
export default function (opts: any): Promise<Transform & build.OnUnknown> & Transform & build.OnUnknown & Promise<Transform>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const require_runtime = require("./_virtual/_rolldown/runtime.js");
|
|
2
|
+
const require_formatter = require("./formatter.js");
|
|
3
|
+
const require_colors = require("./colors.js");
|
|
4
|
+
let node_stream = require("node:stream");
|
|
5
|
+
let node_worker_threads = require("node:worker_threads");
|
|
6
|
+
let pino_abstract_transport = require("pino-abstract-transport");
|
|
7
|
+
pino_abstract_transport = require_runtime.__toESM(pino_abstract_transport);
|
|
8
|
+
let sonic_boom = require("sonic-boom");
|
|
9
|
+
sonic_boom = require_runtime.__toESM(sonic_boom);
|
|
10
|
+
//#region src/prettify.ts
|
|
11
|
+
function noop() {}
|
|
12
|
+
/**
|
|
13
|
+
* Creates a safe SonicBoom instance
|
|
14
|
+
*
|
|
15
|
+
* @param {object} opts Options for SonicBoom
|
|
16
|
+
*
|
|
17
|
+
* @returns {object} A new SonicBoom stream
|
|
18
|
+
*/
|
|
19
|
+
function buildSafeSonicBoom(opts) {
|
|
20
|
+
const stream = new sonic_boom.default(opts);
|
|
21
|
+
stream.on("error", filterBrokenPipe);
|
|
22
|
+
if (!opts.sync && node_worker_threads.isMainThread) setupOnExit(stream);
|
|
23
|
+
return stream;
|
|
24
|
+
function filterBrokenPipe(err) {
|
|
25
|
+
if (err.code === "EPIPE") {
|
|
26
|
+
stream.write = noop;
|
|
27
|
+
stream.end = noop;
|
|
28
|
+
stream.flushSync = noop;
|
|
29
|
+
stream.destroy = noop;
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
stream.removeListener("error", filterBrokenPipe);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function autoEnd(stream, eventName) {
|
|
36
|
+
if (stream.destroyed) return;
|
|
37
|
+
if (eventName === "beforeExit") {
|
|
38
|
+
stream.flush();
|
|
39
|
+
stream.on("drain", function() {
|
|
40
|
+
stream.end();
|
|
41
|
+
});
|
|
42
|
+
} else try {
|
|
43
|
+
stream.flushSync();
|
|
44
|
+
} catch (err) {
|
|
45
|
+
if (err instanceof Error && err.message?.includes("not ready")) return;
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function setupOnExit(stream) {
|
|
50
|
+
const onExit = require("on-exit-leak-free");
|
|
51
|
+
onExit.register(stream, autoEnd);
|
|
52
|
+
stream.on("close", function() {
|
|
53
|
+
onExit.unregister(stream);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function buildPretty(opts) {
|
|
57
|
+
return (chunk) => {
|
|
58
|
+
const colors = require_colors.hasColors(opts.colors);
|
|
59
|
+
return require_formatter.printMessage(chunk, { prettyStamp: opts.prettyStamp }, colors);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function prettify_default(opts) {
|
|
63
|
+
const pretty = buildPretty(opts);
|
|
64
|
+
return (0, pino_abstract_transport.default)(function(source) {
|
|
65
|
+
const stream = new node_stream.Transform({
|
|
66
|
+
objectMode: true,
|
|
67
|
+
autoDestroy: true,
|
|
68
|
+
transform(chunk, enc, cb) {
|
|
69
|
+
cb(null, pretty(chunk) + "\n");
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
const destination = buildSafeSonicBoom({
|
|
73
|
+
dest: opts.destination || 1,
|
|
74
|
+
sync: opts.sync ?? false
|
|
75
|
+
});
|
|
76
|
+
source.on("unknown", function(line) {
|
|
77
|
+
destination.write(line + "\n");
|
|
78
|
+
});
|
|
79
|
+
(0, node_stream.pipeline)(source, stream, destination, (err) => {
|
|
80
|
+
if (err) console.error("prettify pipeline error ", err);
|
|
81
|
+
});
|
|
82
|
+
return stream;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
exports.autoEnd = autoEnd;
|
|
87
|
+
exports.buildPretty = buildPretty;
|
|
88
|
+
exports.buildSafeSonicBoom = buildSafeSonicBoom;
|
|
89
|
+
exports.default = prettify_default;
|
|
90
|
+
|
|
91
|
+
//# sourceMappingURL=prettify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prettify.js","names":[],"sources":["../src/prettify.ts"],"sourcesContent":["import type { WriteStream } from 'node:fs';\nimport { Transform, pipeline } from 'node:stream';\nimport { isMainThread } from 'node:worker_threads';\nimport build from 'pino-abstract-transport';\nimport type { SonicBoomOpts } from 'sonic-boom';\nimport SonicBoom from 'sonic-boom';\n\nimport { hasColors } from './colors';\nimport { fillInMsgTemplate, printMessage } from './formatter';\nimport type { PrettyOptionsExtended } from './types';\n\nexport { fillInMsgTemplate };\n\nfunction noop() {}\n\n/**\n * Creates a safe SonicBoom instance\n *\n * @param {object} opts Options for SonicBoom\n *\n * @returns {object} A new SonicBoom stream\n */\nexport function buildSafeSonicBoom(opts: SonicBoomOpts) {\n const stream = new SonicBoom(opts);\n stream.on('error', filterBrokenPipe);\n if (!opts.sync && isMainThread) {\n setupOnExit(stream);\n }\n return stream;\n\n function filterBrokenPipe(err) {\n if (err.code === 'EPIPE') {\n // @ts-ignore\n stream.write = noop;\n stream.end = noop;\n stream.flushSync = noop;\n stream.destroy = noop;\n return;\n }\n stream.removeListener('error', filterBrokenPipe);\n }\n}\n\nexport function autoEnd(stream: SonicBoom & { destroyed?: boolean }, eventName: string) {\n if (stream.destroyed) {\n return;\n }\n\n if (eventName === 'beforeExit') {\n stream.flush();\n stream.on('drain', function () {\n stream.end();\n });\n } else {\n // Guard against SonicBoom not being ready (file not yet opened)\n // to prevent \"sonic boom is not ready yet\" crash on early process exit\n try {\n stream.flushSync();\n } catch (err: unknown) {\n if (err instanceof Error && err.message?.includes('not ready')) {\n // Stream not ready, nothing to flush\n return;\n }\n // Re-throw real I/O errors (disk full, permission denied, etc.)\n throw err;\n }\n }\n}\n\nfunction setupOnExit(stream) {\n // WeakRef/FinalizationRegistry are guaranteed available in Node 20+ (pino v10 minimum)\n const onExit = require('on-exit-leak-free');\n onExit.register(stream, autoEnd);\n stream.on('close', function () {\n onExit.unregister(stream);\n });\n}\n\nexport { hasColors } from './colors';\n\nexport function buildPretty(opts: PrettyOptionsExtended) {\n return (chunk) => {\n const colors = hasColors(opts.colors);\n return printMessage(chunk, { prettyStamp: opts.prettyStamp }, colors);\n };\n}\n\nexport default function (opts) {\n const pretty = buildPretty(opts);\n // @ts-ignore\n return build(function (source) {\n const stream = new Transform({\n objectMode: true,\n autoDestroy: true,\n transform(chunk, enc, cb) {\n const line = pretty(chunk) + '\\n';\n cb(null, line);\n },\n });\n const destination = buildSafeSonicBoom({\n dest: opts.destination || 1,\n // Defaults to async (false). The transport runs in a worker thread,\n // so sync only blocks the worker, not the main thread.\n // Can be set to true via config for deterministic log ordering (like console.log).\n sync: opts.sync ?? false,\n }) as unknown as WriteStream;\n\n source.on('unknown', function (line) {\n destination.write(line + '\\n');\n });\n\n pipeline(source, stream, destination, (err) => {\n if (err) {\n console.error('prettify pipeline error ', err);\n }\n });\n return stream;\n });\n}\n"],"mappings":";;;;;;;;;;AAaA,SAAS,OAAO;;;;;;;;AAShB,SAAgB,mBAAmB,MAAqB;CACtD,MAAM,SAAS,IAAI,WAAA,QAAU,KAAK;AAClC,QAAO,GAAG,SAAS,iBAAiB;AACpC,KAAI,CAAC,KAAK,QAAQ,oBAAA,aAChB,aAAY,OAAO;AAErB,QAAO;CAEP,SAAS,iBAAiB,KAAK;AAC7B,MAAI,IAAI,SAAS,SAAS;AAExB,UAAO,QAAQ;AACf,UAAO,MAAM;AACb,UAAO,YAAY;AACnB,UAAO,UAAU;AACjB;;AAEF,SAAO,eAAe,SAAS,iBAAiB;;;AAIpD,SAAgB,QAAQ,QAA6C,WAAmB;AACtF,KAAI,OAAO,UACT;AAGF,KAAI,cAAc,cAAc;AAC9B,SAAO,OAAO;AACd,SAAO,GAAG,SAAS,WAAY;AAC7B,UAAO,KAAK;IACZ;OAIF,KAAI;AACF,SAAO,WAAW;UACX,KAAc;AACrB,MAAI,eAAe,SAAS,IAAI,SAAS,SAAS,YAAY,CAE5D;AAGF,QAAM;;;AAKZ,SAAS,YAAY,QAAQ;CAE3B,MAAM,SAAS,QAAQ,oBAAoB;AAC3C,QAAO,SAAS,QAAQ,QAAQ;AAChC,QAAO,GAAG,SAAS,WAAY;AAC7B,SAAO,WAAW,OAAO;GACzB;;AAKJ,SAAgB,YAAY,MAA6B;AACvD,SAAQ,UAAU;EAChB,MAAM,SAAS,eAAA,UAAU,KAAK,OAAO;AACrC,SAAO,kBAAA,aAAa,OAAO,EAAE,aAAa,KAAK,aAAa,EAAE,OAAO;;;AAIzE,SAAA,iBAAyB,MAAM;CAC7B,MAAM,SAAS,YAAY,KAAK;AAEhC,SAAA,GAAA,wBAAA,SAAa,SAAU,QAAQ;EAC7B,MAAM,SAAS,IAAI,YAAA,UAAU;GAC3B,YAAY;GACZ,aAAa;GACb,UAAU,OAAO,KAAK,IAAI;AAExB,OAAG,MADU,OAAO,MAAM,GAAG,KACf;;GAEjB,CAAC;EACF,MAAM,cAAc,mBAAmB;GACrC,MAAM,KAAK,eAAe;GAI1B,MAAM,KAAK,QAAQ;GACpB,CAAC;AAEF,SAAO,GAAG,WAAW,SAAU,MAAM;AACnC,eAAY,MAAM,OAAO,KAAK;IAC9B;AAEF,GAAA,GAAA,YAAA,UAAS,QAAQ,QAAQ,cAAc,QAAQ;AAC7C,OAAI,IACF,SAAQ,MAAM,4BAA4B,IAAI;IAEhD;AACF,SAAO;GACP"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { __require } from "./_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import { printMessage } from "./formatter.mjs";
|
|
3
|
+
import { hasColors } from "./colors.mjs";
|
|
4
|
+
import { Transform, pipeline } from "node:stream";
|
|
5
|
+
import { isMainThread } from "node:worker_threads";
|
|
6
|
+
import build from "pino-abstract-transport";
|
|
7
|
+
import SonicBoom from "sonic-boom";
|
|
8
|
+
//#region src/prettify.ts
|
|
9
|
+
function noop() {}
|
|
10
|
+
/**
|
|
11
|
+
* Creates a safe SonicBoom instance
|
|
12
|
+
*
|
|
13
|
+
* @param {object} opts Options for SonicBoom
|
|
14
|
+
*
|
|
15
|
+
* @returns {object} A new SonicBoom stream
|
|
16
|
+
*/
|
|
17
|
+
function buildSafeSonicBoom(opts) {
|
|
18
|
+
const stream = new SonicBoom(opts);
|
|
19
|
+
stream.on("error", filterBrokenPipe);
|
|
20
|
+
if (!opts.sync && isMainThread) setupOnExit(stream);
|
|
21
|
+
return stream;
|
|
22
|
+
function filterBrokenPipe(err) {
|
|
23
|
+
if (err.code === "EPIPE") {
|
|
24
|
+
stream.write = noop;
|
|
25
|
+
stream.end = noop;
|
|
26
|
+
stream.flushSync = noop;
|
|
27
|
+
stream.destroy = noop;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
stream.removeListener("error", filterBrokenPipe);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function autoEnd(stream, eventName) {
|
|
34
|
+
if (stream.destroyed) return;
|
|
35
|
+
if (eventName === "beforeExit") {
|
|
36
|
+
stream.flush();
|
|
37
|
+
stream.on("drain", function() {
|
|
38
|
+
stream.end();
|
|
39
|
+
});
|
|
40
|
+
} else try {
|
|
41
|
+
stream.flushSync();
|
|
42
|
+
} catch (err) {
|
|
43
|
+
if (err instanceof Error && err.message?.includes("not ready")) return;
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function setupOnExit(stream) {
|
|
48
|
+
const onExit = __require("on-exit-leak-free");
|
|
49
|
+
onExit.register(stream, autoEnd);
|
|
50
|
+
stream.on("close", function() {
|
|
51
|
+
onExit.unregister(stream);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function buildPretty(opts) {
|
|
55
|
+
return (chunk) => {
|
|
56
|
+
const colors = hasColors(opts.colors);
|
|
57
|
+
return printMessage(chunk, { prettyStamp: opts.prettyStamp }, colors);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function prettify_default(opts) {
|
|
61
|
+
const pretty = buildPretty(opts);
|
|
62
|
+
return build(function(source) {
|
|
63
|
+
const stream = new Transform({
|
|
64
|
+
objectMode: true,
|
|
65
|
+
autoDestroy: true,
|
|
66
|
+
transform(chunk, enc, cb) {
|
|
67
|
+
cb(null, pretty(chunk) + "\n");
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
const destination = buildSafeSonicBoom({
|
|
71
|
+
dest: opts.destination || 1,
|
|
72
|
+
sync: opts.sync ?? false
|
|
73
|
+
});
|
|
74
|
+
source.on("unknown", function(line) {
|
|
75
|
+
destination.write(line + "\n");
|
|
76
|
+
});
|
|
77
|
+
pipeline(source, stream, destination, (err) => {
|
|
78
|
+
if (err) console.error("prettify pipeline error ", err);
|
|
79
|
+
});
|
|
80
|
+
return stream;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
export { autoEnd, buildPretty, buildSafeSonicBoom, prettify_default as default };
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=prettify.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prettify.mjs","names":[],"sources":["../src/prettify.ts"],"sourcesContent":["import type { WriteStream } from 'node:fs';\nimport { Transform, pipeline } from 'node:stream';\nimport { isMainThread } from 'node:worker_threads';\nimport build from 'pino-abstract-transport';\nimport type { SonicBoomOpts } from 'sonic-boom';\nimport SonicBoom from 'sonic-boom';\n\nimport { hasColors } from './colors';\nimport { fillInMsgTemplate, printMessage } from './formatter';\nimport type { PrettyOptionsExtended } from './types';\n\nexport { fillInMsgTemplate };\n\nfunction noop() {}\n\n/**\n * Creates a safe SonicBoom instance\n *\n * @param {object} opts Options for SonicBoom\n *\n * @returns {object} A new SonicBoom stream\n */\nexport function buildSafeSonicBoom(opts: SonicBoomOpts) {\n const stream = new SonicBoom(opts);\n stream.on('error', filterBrokenPipe);\n if (!opts.sync && isMainThread) {\n setupOnExit(stream);\n }\n return stream;\n\n function filterBrokenPipe(err) {\n if (err.code === 'EPIPE') {\n // @ts-ignore\n stream.write = noop;\n stream.end = noop;\n stream.flushSync = noop;\n stream.destroy = noop;\n return;\n }\n stream.removeListener('error', filterBrokenPipe);\n }\n}\n\nexport function autoEnd(stream: SonicBoom & { destroyed?: boolean }, eventName: string) {\n if (stream.destroyed) {\n return;\n }\n\n if (eventName === 'beforeExit') {\n stream.flush();\n stream.on('drain', function () {\n stream.end();\n });\n } else {\n // Guard against SonicBoom not being ready (file not yet opened)\n // to prevent \"sonic boom is not ready yet\" crash on early process exit\n try {\n stream.flushSync();\n } catch (err: unknown) {\n if (err instanceof Error && err.message?.includes('not ready')) {\n // Stream not ready, nothing to flush\n return;\n }\n // Re-throw real I/O errors (disk full, permission denied, etc.)\n throw err;\n }\n }\n}\n\nfunction setupOnExit(stream) {\n // WeakRef/FinalizationRegistry are guaranteed available in Node 20+ (pino v10 minimum)\n const onExit = require('on-exit-leak-free');\n onExit.register(stream, autoEnd);\n stream.on('close', function () {\n onExit.unregister(stream);\n });\n}\n\nexport { hasColors } from './colors';\n\nexport function buildPretty(opts: PrettyOptionsExtended) {\n return (chunk) => {\n const colors = hasColors(opts.colors);\n return printMessage(chunk, { prettyStamp: opts.prettyStamp }, colors);\n };\n}\n\nexport default function (opts) {\n const pretty = buildPretty(opts);\n // @ts-ignore\n return build(function (source) {\n const stream = new Transform({\n objectMode: true,\n autoDestroy: true,\n transform(chunk, enc, cb) {\n const line = pretty(chunk) + '\\n';\n cb(null, line);\n },\n });\n const destination = buildSafeSonicBoom({\n dest: opts.destination || 1,\n // Defaults to async (false). The transport runs in a worker thread,\n // so sync only blocks the worker, not the main thread.\n // Can be set to true via config for deterministic log ordering (like console.log).\n sync: opts.sync ?? false,\n }) as unknown as WriteStream;\n\n source.on('unknown', function (line) {\n destination.write(line + '\\n');\n });\n\n pipeline(source, stream, destination, (err) => {\n if (err) {\n console.error('prettify pipeline error ', err);\n }\n });\n return stream;\n });\n}\n"],"mappings":";;;;;;;;AAaA,SAAS,OAAO;;;;;;;;AAShB,SAAgB,mBAAmB,MAAqB;CACtD,MAAM,SAAS,IAAI,UAAU,KAAK;AAClC,QAAO,GAAG,SAAS,iBAAiB;AACpC,KAAI,CAAC,KAAK,QAAQ,aAChB,aAAY,OAAO;AAErB,QAAO;CAEP,SAAS,iBAAiB,KAAK;AAC7B,MAAI,IAAI,SAAS,SAAS;AAExB,UAAO,QAAQ;AACf,UAAO,MAAM;AACb,UAAO,YAAY;AACnB,UAAO,UAAU;AACjB;;AAEF,SAAO,eAAe,SAAS,iBAAiB;;;AAIpD,SAAgB,QAAQ,QAA6C,WAAmB;AACtF,KAAI,OAAO,UACT;AAGF,KAAI,cAAc,cAAc;AAC9B,SAAO,OAAO;AACd,SAAO,GAAG,SAAS,WAAY;AAC7B,UAAO,KAAK;IACZ;OAIF,KAAI;AACF,SAAO,WAAW;UACX,KAAc;AACrB,MAAI,eAAe,SAAS,IAAI,SAAS,SAAS,YAAY,CAE5D;AAGF,QAAM;;;AAKZ,SAAS,YAAY,QAAQ;CAE3B,MAAM,SAAA,UAAiB,oBAAoB;AAC3C,QAAO,SAAS,QAAQ,QAAQ;AAChC,QAAO,GAAG,SAAS,WAAY;AAC7B,SAAO,WAAW,OAAO;GACzB;;AAKJ,SAAgB,YAAY,MAA6B;AACvD,SAAQ,UAAU;EAChB,MAAM,SAAS,UAAU,KAAK,OAAO;AACrC,SAAO,aAAa,OAAO,EAAE,aAAa,KAAK,aAAa,EAAE,OAAO;;;AAIzE,SAAA,iBAAyB,MAAM;CAC7B,MAAM,SAAS,YAAY,KAAK;AAEhC,QAAO,MAAM,SAAU,QAAQ;EAC7B,MAAM,SAAS,IAAI,UAAU;GAC3B,YAAY;GACZ,aAAa;GACb,UAAU,OAAO,KAAK,IAAI;AAExB,OAAG,MADU,OAAO,MAAM,GAAG,KACf;;GAEjB,CAAC;EACF,MAAM,cAAc,mBAAmB;GACrC,MAAM,KAAK,eAAe;GAI1B,MAAM,KAAK,QAAQ;GACpB,CAAC;AAEF,SAAO,GAAG,WAAW,SAAU,MAAM;AACnC,eAAY,MAAM,OAAO,KAAK;IAC9B;AAEF,WAAS,QAAQ,QAAQ,cAAc,QAAQ;AAC7C,OAAI,IACF,SAAQ,MAAM,4BAA4B,IAAI;IAEhD;AACF,SAAO;GACP"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { LoggerConfigItem, LoggerFormat } from '@verdaccio/types';
|
|
2
|
+
export declare function isPrettyFormat(format: LoggerFormat | undefined): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Create a pino pretty transport for non-production environments.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createPrettyTransport(pino: any, options: LoggerConfigItem, format: LoggerFormat): any;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require("./_virtual/_rolldown/runtime.js");
|
|
2
|
+
const require_colors = require("./colors.js");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
let node_url = require("node:url");
|
|
5
|
+
//#region src/transport.ts
|
|
6
|
+
function getCurrentDir() {
|
|
7
|
+
if (typeof __dirname !== "undefined") return __dirname;
|
|
8
|
+
return (0, node_path.dirname)((0, node_url.fileURLToPath)({}.url));
|
|
9
|
+
}
|
|
10
|
+
var prettifyPath = (0, node_path.join)(getCurrentDir(), "..", "build", "prettify.js");
|
|
11
|
+
function isPrettyFormat(format) {
|
|
12
|
+
return ["pretty-timestamped", "pretty"].includes(format ?? "pretty");
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a pino pretty transport for non-production environments.
|
|
16
|
+
*/
|
|
17
|
+
function createPrettyTransport(pino, options, format) {
|
|
18
|
+
return pino.transport({
|
|
19
|
+
target: prettifyPath,
|
|
20
|
+
options: {
|
|
21
|
+
destination: options.path || 1,
|
|
22
|
+
colors: require_colors.hasColors(options.colors),
|
|
23
|
+
prettyStamp: format === "pretty-timestamped",
|
|
24
|
+
sync: options.sync ?? false
|
|
25
|
+
},
|
|
26
|
+
worker: { name: "verdaccio-logger-prettify" }
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
exports.createPrettyTransport = createPrettyTransport;
|
|
31
|
+
exports.isPrettyFormat = isPrettyFormat;
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","names":[],"sources":["../src/transport.ts"],"sourcesContent":["import { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { LoggerConfigItem, LoggerFormat } from '@verdaccio/types';\n\nimport { hasColors } from './colors';\n\n// Pino transports run in a worker thread and require an absolute path to a built JS file.\n// __dirname works in CJS; import.meta.url works in ESM (Node 20+).\nfunction getCurrentDir(): string {\n if (typeof __dirname !== 'undefined') {\n return __dirname;\n }\n // @ts-ignore -- import.meta.url requires module: es2020+ but vite preserves it for ESM output\n return dirname(fileURLToPath(import.meta.url));\n}\nconst prettifyPath = join(getCurrentDir(), '..', 'build', 'prettify.js');\n\nexport function isPrettyFormat(format: LoggerFormat | undefined): boolean {\n return ['pretty-timestamped', 'pretty'].includes(format ?? 'pretty');\n}\n\n/**\n * Create a pino pretty transport for non-production environments.\n */\nexport function createPrettyTransport(pino: any, options: LoggerConfigItem, format: LoggerFormat) {\n return pino.transport({\n target: prettifyPath,\n options: {\n destination: options.path || 1,\n colors: hasColors(options.colors),\n prettyStamp: format === 'pretty-timestamped',\n sync: options.sync ?? false,\n },\n worker: {\n name: 'verdaccio-logger-prettify',\n },\n });\n}\n"],"mappings":";;;;;AASA,SAAS,gBAAwB;AAC/B,KAAI,OAAO,cAAc,YACvB,QAAO;AAGT,SAAA,GAAA,UAAA,UAAA,GAAA,SAAA,eAAA,EAAA,CAAyC,IAAI,CAAC;;AAEhD,IAAM,gBAAA,GAAA,UAAA,MAAoB,eAAe,EAAE,MAAM,SAAS,cAAc;AAExE,SAAgB,eAAe,QAA2C;AACxE,QAAO,CAAC,sBAAsB,SAAS,CAAC,SAAS,UAAU,SAAS;;;;;AAMtE,SAAgB,sBAAsB,MAAW,SAA2B,QAAsB;AAChG,QAAO,KAAK,UAAU;EACpB,QAAQ;EACR,SAAS;GACP,aAAa,QAAQ,QAAQ;GAC7B,QAAQ,eAAA,UAAU,QAAQ,OAAO;GACjC,aAAa,WAAW;GACxB,MAAM,QAAQ,QAAQ;GACvB;EACD,QAAQ,EACN,MAAM,6BACP;EACF,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { hasColors } from "./colors.mjs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
//#region src/transport.ts
|
|
5
|
+
function getCurrentDir() {
|
|
6
|
+
if (typeof __dirname !== "undefined") return __dirname;
|
|
7
|
+
return dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
}
|
|
9
|
+
var prettifyPath = join(getCurrentDir(), "..", "build", "prettify.js");
|
|
10
|
+
function isPrettyFormat(format) {
|
|
11
|
+
return ["pretty-timestamped", "pretty"].includes(format ?? "pretty");
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create a pino pretty transport for non-production environments.
|
|
15
|
+
*/
|
|
16
|
+
function createPrettyTransport(pino, options, format) {
|
|
17
|
+
return pino.transport({
|
|
18
|
+
target: prettifyPath,
|
|
19
|
+
options: {
|
|
20
|
+
destination: options.path || 1,
|
|
21
|
+
colors: hasColors(options.colors),
|
|
22
|
+
prettyStamp: format === "pretty-timestamped",
|
|
23
|
+
sync: options.sync ?? false
|
|
24
|
+
},
|
|
25
|
+
worker: { name: "verdaccio-logger-prettify" }
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { createPrettyTransport, isPrettyFormat };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=transport.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.mjs","names":[],"sources":["../src/transport.ts"],"sourcesContent":["import { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { LoggerConfigItem, LoggerFormat } from '@verdaccio/types';\n\nimport { hasColors } from './colors';\n\n// Pino transports run in a worker thread and require an absolute path to a built JS file.\n// __dirname works in CJS; import.meta.url works in ESM (Node 20+).\nfunction getCurrentDir(): string {\n if (typeof __dirname !== 'undefined') {\n return __dirname;\n }\n // @ts-ignore -- import.meta.url requires module: es2020+ but vite preserves it for ESM output\n return dirname(fileURLToPath(import.meta.url));\n}\nconst prettifyPath = join(getCurrentDir(), '..', 'build', 'prettify.js');\n\nexport function isPrettyFormat(format: LoggerFormat | undefined): boolean {\n return ['pretty-timestamped', 'pretty'].includes(format ?? 'pretty');\n}\n\n/**\n * Create a pino pretty transport for non-production environments.\n */\nexport function createPrettyTransport(pino: any, options: LoggerConfigItem, format: LoggerFormat) {\n return pino.transport({\n target: prettifyPath,\n options: {\n destination: options.path || 1,\n colors: hasColors(options.colors),\n prettyStamp: format === 'pretty-timestamped',\n sync: options.sync ?? false,\n },\n worker: {\n name: 'verdaccio-logger-prettify',\n },\n });\n}\n"],"mappings":";;;;AASA,SAAS,gBAAwB;AAC/B,KAAI,OAAO,cAAc,YACvB,QAAO;AAGT,QAAO,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;;AAEhD,IAAM,eAAe,KAAK,eAAe,EAAE,MAAM,SAAS,cAAc;AAExE,SAAgB,eAAe,QAA2C;AACxE,QAAO,CAAC,sBAAsB,SAAS,CAAC,SAAS,UAAU,SAAS;;;;;AAMtE,SAAgB,sBAAsB,MAAW,SAA2B,QAAsB;AAChG,QAAO,KAAK,UAAU;EACpB,QAAQ;EACR,SAAS;GACP,aAAa,QAAQ,QAAQ;GAC7B,QAAQ,UAAU,QAAQ,OAAO;GACjC,aAAa,WAAW;GACxB,MAAM,QAAQ,QAAQ;GACvB;EACD,QAAQ,EACN,MAAM,6BACP;EACF,CAAC"}
|
package/build/types.d.ts
ADDED
package/build/utils.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const FORMAT_DATE = "YYYY-MM-DD HH:mm:ss";
|
|
2
|
+
export declare const CUSTOM_PAD_LENGTH = 1;
|
|
3
|
+
export declare function isObject(obj: unknown): boolean;
|
|
4
|
+
export declare function padRight(message: string, max?: number): string;
|
|
5
|
+
export declare function formatLoggingDate(time: number, message: string): string;
|
package/build/utils.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const require_runtime = require("./_virtual/_rolldown/runtime.js");
|
|
2
|
+
let dayjs = require("dayjs");
|
|
3
|
+
dayjs = require_runtime.__toESM(dayjs);
|
|
4
|
+
//#region src/utils.ts
|
|
5
|
+
var FORMAT_DATE = "YYYY-MM-DD HH:mm:ss";
|
|
6
|
+
function isObject(obj) {
|
|
7
|
+
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
8
|
+
}
|
|
9
|
+
function padRight(message, max = message.length + 1) {
|
|
10
|
+
return message.padEnd(max, " ");
|
|
11
|
+
}
|
|
12
|
+
function formatLoggingDate(time, message) {
|
|
13
|
+
return `[${(0, dayjs.default)(time).format(FORMAT_DATE)}] ${message}`;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
exports.formatLoggingDate = formatLoggingDate;
|
|
17
|
+
exports.isObject = isObject;
|
|
18
|
+
exports.padRight = padRight;
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import dayjs from 'dayjs';\n\nexport const FORMAT_DATE = 'YYYY-MM-DD HH:mm:ss';\nexport const CUSTOM_PAD_LENGTH = 1;\n\nexport function isObject(obj: unknown): boolean {\n return typeof obj === 'object' && obj !== null && !Array.isArray(obj);\n}\n\nexport function padRight(message: string, max = message.length + CUSTOM_PAD_LENGTH) {\n return message.padEnd(max, ' ');\n}\n\nexport function formatLoggingDate(time: number, message: string): string {\n const timeFormatted = dayjs(time).format(FORMAT_DATE);\n\n return `[${timeFormatted}] ${message}`;\n}\n"],"mappings":";;;;AAEA,IAAa,cAAc;AAG3B,SAAgB,SAAS,KAAuB;AAC9C,QAAO,OAAO,QAAQ,YAAY,QAAQ,QAAQ,CAAC,MAAM,QAAQ,IAAI;;AAGvE,SAAgB,SAAS,SAAiB,MAAM,QAAQ,SAAA,GAA4B;AAClF,QAAO,QAAQ,OAAO,KAAK,IAAI;;AAGjC,SAAgB,kBAAkB,MAAc,SAAyB;AAGvE,QAAO,KAAA,GAAA,MAAA,SAFqB,KAAK,CAAC,OAAO,YAAY,CAE5B,IAAI"}
|
package/build/utils.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
//#region src/utils.ts
|
|
3
|
+
var FORMAT_DATE = "YYYY-MM-DD HH:mm:ss";
|
|
4
|
+
function isObject(obj) {
|
|
5
|
+
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
6
|
+
}
|
|
7
|
+
function padRight(message, max = message.length + 1) {
|
|
8
|
+
return message.padEnd(max, " ");
|
|
9
|
+
}
|
|
10
|
+
function formatLoggingDate(time, message) {
|
|
11
|
+
return `[${dayjs(time).format(FORMAT_DATE)}] ${message}`;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { formatLoggingDate, isObject, padRight };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import dayjs from 'dayjs';\n\nexport const FORMAT_DATE = 'YYYY-MM-DD HH:mm:ss';\nexport const CUSTOM_PAD_LENGTH = 1;\n\nexport function isObject(obj: unknown): boolean {\n return typeof obj === 'object' && obj !== null && !Array.isArray(obj);\n}\n\nexport function padRight(message: string, max = message.length + CUSTOM_PAD_LENGTH) {\n return message.padEnd(max, ' ');\n}\n\nexport function formatLoggingDate(time: number, message: string): string {\n const timeFormatted = dayjs(time).format(FORMAT_DATE);\n\n return `[${timeFormatted}] ${message}`;\n}\n"],"mappings":";;AAEA,IAAa,cAAc;AAG3B,SAAgB,SAAS,KAAuB;AAC9C,QAAO,OAAO,QAAQ,YAAY,QAAQ,QAAQ,CAAC,MAAM,QAAQ,IAAI;;AAGvE,SAAgB,SAAS,SAAiB,MAAM,QAAQ,SAAA,GAA4B;AAClF,QAAO,QAAQ,OAAO,KAAK,IAAI;;AAGjC,SAAgB,kBAAkB,MAAc,SAAyB;AAGvE,QAAO,IAFe,MAAM,KAAK,CAAC,OAAO,YAAY,CAE5B,IAAI"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/logger",
|
|
3
|
-
"version": "9.0.0-next-9.
|
|
3
|
+
"version": "9.0.0-next-9.5",
|
|
4
4
|
"description": "Verdaccio Logger",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "https",
|
|
13
13
|
"url": "https://github.com/verdaccio/verdaccio",
|
|
14
|
-
"directory": "packages/logger
|
|
14
|
+
"directory": "packages/logger"
|
|
15
15
|
},
|
|
16
16
|
"bugs": {
|
|
17
17
|
"url": "https://github.com/verdaccio/verdaccio/issues"
|
|
@@ -33,23 +33,42 @@
|
|
|
33
33
|
"node": ">=24"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@verdaccio/
|
|
37
|
-
"
|
|
36
|
+
"@verdaccio/core": "9.0.0-next-9.5",
|
|
37
|
+
"colorette": "2.0.20",
|
|
38
|
+
"dayjs": "1.11.18",
|
|
39
|
+
"debug": "4.4.3",
|
|
40
|
+
"on-exit-leak-free": "2.1.2",
|
|
41
|
+
"pino": "10.3.1",
|
|
42
|
+
"pino-abstract-transport": "3.0.0",
|
|
43
|
+
"sonic-boom": "4.2.1"
|
|
38
44
|
},
|
|
39
45
|
"devDependencies": {
|
|
40
|
-
"@verdaccio/types": "14.0.0-next-9.
|
|
46
|
+
"@verdaccio/types": "14.0.0-next-9.2",
|
|
47
|
+
"pino": "10.3.1",
|
|
48
|
+
"vitest": "4.1.0"
|
|
41
49
|
},
|
|
42
50
|
"funding": {
|
|
43
51
|
"type": "opencollective",
|
|
44
52
|
"url": "https://opencollective.com/verdaccio"
|
|
45
53
|
},
|
|
54
|
+
"module": "./build/index.mjs",
|
|
55
|
+
"exports": {
|
|
56
|
+
".": {
|
|
57
|
+
"import": {
|
|
58
|
+
"types": "./build/index.d.ts",
|
|
59
|
+
"default": "./build/index.mjs"
|
|
60
|
+
},
|
|
61
|
+
"require": {
|
|
62
|
+
"types": "./build/index.d.ts",
|
|
63
|
+
"default": "./build/index.js"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"./build/*": "./build/*"
|
|
67
|
+
},
|
|
46
68
|
"scripts": {
|
|
47
69
|
"clean": "rimraf ./build",
|
|
48
|
-
"test": "
|
|
49
|
-
"
|
|
50
|
-
"build
|
|
51
|
-
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
|
52
|
-
"watch": "pnpm build:js -- --watch",
|
|
53
|
-
"build": "pnpm run build:js && pnpm run build:types"
|
|
70
|
+
"test": "cross-env TZ=utc vitest run",
|
|
71
|
+
"watch": "vite build --watch",
|
|
72
|
+
"build": "vite build"
|
|
54
73
|
}
|
|
55
74
|
}
|
package/src/colors.ts
ADDED
package/src/formatter.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { green, red, white } from 'colorette';
|
|
2
|
+
import { inspect } from 'node:util';
|
|
3
|
+
|
|
4
|
+
import type { LevelCode } from './levels';
|
|
5
|
+
import { calculateLevel, levelsColors, subSystemLevels } from './levels';
|
|
6
|
+
import type { PrettyOptionsExtended } from './types';
|
|
7
|
+
import { formatLoggingDate, isObject, padRight } from './utils';
|
|
8
|
+
|
|
9
|
+
let LEVEL_VALUE_MAX = 0;
|
|
10
|
+
for (const l of Object.keys(levelsColors)) {
|
|
11
|
+
LEVEL_VALUE_MAX = Math.max(LEVEL_VALUE_MAX, l.length);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const ERROR_FLAG = '!';
|
|
15
|
+
|
|
16
|
+
export interface ObjectTemplate {
|
|
17
|
+
level: LevelCode;
|
|
18
|
+
msg: string;
|
|
19
|
+
sub?: string;
|
|
20
|
+
[key: string]: string | number | object | null | void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function fillInMsgTemplate(
|
|
24
|
+
msg: string,
|
|
25
|
+
templateOptions: ObjectTemplate,
|
|
26
|
+
colors: boolean
|
|
27
|
+
): string {
|
|
28
|
+
const templateRegex = /@{(!?[$A-Za-z_][$0-9A-Za-z\._]*)}/g;
|
|
29
|
+
|
|
30
|
+
return msg.replace(templateRegex, (_, name): string => {
|
|
31
|
+
let str = templateOptions;
|
|
32
|
+
let isError;
|
|
33
|
+
if (name[0] === ERROR_FLAG) {
|
|
34
|
+
name = name.slice(1);
|
|
35
|
+
isError = true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// object can be @{foo.bar.}
|
|
39
|
+
const listAccessors = name.split('.');
|
|
40
|
+
for (let property = 0; property < listAccessors.length; property++) {
|
|
41
|
+
const id = listAccessors[property];
|
|
42
|
+
if (isObject(str)) {
|
|
43
|
+
str = (str as object)[id];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (typeof str === 'string') {
|
|
48
|
+
if (colors === false || (str as string).includes('\n')) {
|
|
49
|
+
return str;
|
|
50
|
+
} else if (isError) {
|
|
51
|
+
return red(str);
|
|
52
|
+
}
|
|
53
|
+
return green(str);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// object, showHidden, depth, colors
|
|
57
|
+
return inspect(str, undefined, null, colors);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getMessage(debugLevel, msg, sub, templateObjects, hasColors: boolean) {
|
|
62
|
+
const finalMessage = fillInMsgTemplate(msg, templateObjects, hasColors);
|
|
63
|
+
|
|
64
|
+
const subSystemType = hasColors
|
|
65
|
+
? subSystemLevels.color[sub ?? 'default']
|
|
66
|
+
: subSystemLevels.white[sub ?? 'default'];
|
|
67
|
+
if (hasColors) {
|
|
68
|
+
const logString = `${levelsColors[debugLevel](padRight(debugLevel, LEVEL_VALUE_MAX))}${white(
|
|
69
|
+
`${subSystemType} ${finalMessage}`
|
|
70
|
+
)}`;
|
|
71
|
+
|
|
72
|
+
return logString;
|
|
73
|
+
}
|
|
74
|
+
const logString = `${padRight(debugLevel, LEVEL_VALUE_MAX)}${subSystemType} ${finalMessage}`;
|
|
75
|
+
|
|
76
|
+
return logString;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function printMessage(
|
|
80
|
+
templateObjects: ObjectTemplate,
|
|
81
|
+
options: Pick<PrettyOptionsExtended, 'prettyStamp'>,
|
|
82
|
+
hasColors: boolean
|
|
83
|
+
): string {
|
|
84
|
+
const { prettyStamp } = options;
|
|
85
|
+
const { level, msg, sub } = templateObjects;
|
|
86
|
+
const debugLevel = calculateLevel(level);
|
|
87
|
+
const logMessage = getMessage(debugLevel, msg, sub, templateObjects, hasColors);
|
|
88
|
+
|
|
89
|
+
return prettyStamp ? formatLoggingDate(templateObjects.time as number, logMessage) : logMessage;
|
|
90
|
+
}
|