UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

181 lines (149 loc) 17.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setup = setup; exports.logger = void 0; var _prettyTimestamped = require("./logger/format/pretty-timestamped"); var _pretty = require("./logger/format/pretty"); var _json = require("./logger/format/json"); /* eslint-disable */ const cluster = require('cluster'); const Logger = require('bunyan'); const Error = require('http-errors'); const Stream = require('stream'); const pkgJSON = require('../../package.json'); const _ = require('lodash'); const dayjs = require('dayjs'); /** * A RotatingFileStream that modifies the message first */ class VerdaccioRotatingFileStream extends Logger.RotatingFileStream { // We depend on mv so that this is there write(obj) { super.write((0, _json.jsonFormat)(obj, false)); } rotate() { super.rotate(); this.emit('rotated'); } } let logger; exports.logger = logger; const DEFAULT_LOGGER_CONF = [{ type: 'stdout', format: 'pretty', level: 'http' }]; /** * Setup the Buyan logger * @param {*} logs list of log configuration */ function setup(logs, { logStart } = { logStart: true }) { const streams = []; if (logs == null) { logs = DEFAULT_LOGGER_CONF; } logs.forEach(function (target) { let level = target.level || 35; if (level === 'http') { level = 35; } // create a stream for each log configuration if (target.type === 'rotating-file') { if (target.format !== 'json') { throw new Error('Rotating file streams only work with JSON!'); } if (cluster.isWorker) { // https://github.com/trentm/node-bunyan#stream-type-rotating-file throw new Error('Cluster mode is not supported for rotating-file!'); } const stream = new VerdaccioRotatingFileStream( // @ts-ignore _.merge({}, // Defaults can be found here: https://github.com/trentm/node-bunyan#stream-type-rotating-file target.options || {}, { path: target.path, level })); const rotateStream = { type: 'raw', level, stream }; if (logStart) { stream.on('rotated', () => logger.warn('Start of logfile')); } streams.push(rotateStream); } else { const stream = new Stream(); stream.writable = true; let destination; let destinationIsTTY = false; if (target.type === 'file') { // destination stream destination = require('fs').createWriteStream(target.path, { flags: 'a', encoding: 'utf8' }); destination.on('error', function (err) { stream.emit('error', err); }); } else if (target.type === 'stdout' || target.type === 'stderr') { destination = target.type === 'stdout' ? process.stdout : process.stderr; destinationIsTTY = destination.isTTY; } else { throw Error('wrong target type for a log'); } if (target.format === 'pretty') { // making fake stream for pretty printing stream.write = obj => { destination.write((0, _pretty.pretty)(obj, destinationIsTTY)); }; } else if (target.format === 'pretty-timestamped') { // making fake stream for pretty printing stream.write = obj => { destination.write((0, _prettyTimestamped.prettyTimestamped)(obj, destinationIsTTY)); }; } else { stream.write = obj => { destination.write((0, _json.jsonFormat)(obj, destinationIsTTY)); }; } streams.push({ // @ts-ignore type: 'raw', // @ts-ignore level, // @ts-ignore stream: stream }); } }); // buyan default configuration exports.logger = logger = new Logger({ name: pkgJSON.name, streams: streams, serializers: { err: Logger.stdSerializers.err, req: Logger.stdSerializers.req, res: Logger.stdSerializers.res } }); // In case of an empty log file, we ensure there is always something logged. This also helps see if the server // was restarted in any cases if (logStart) { logger.warn('Verdaccio started'); } process.on('SIGUSR2', function () { // https://github.com/trentm/node-bunyan#stream-type-rotating-file if (logger) { /** * Note on log rotation: Often you may be using external log rotation utilities like logrotate on Linux or logadm * on SmartOS/Illumos. In those cases, unless your are ensuring "copy and truncate" semantics * (via copytruncate with logrotate or -c with logadm) then the fd for your 'file' stream will change. */ logger.reopenFileStreams(); } }); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvbG9nZ2VyLnRzIl0sIm5hbWVzIjpbImNsdXN0ZXIiLCJyZXF1aXJlIiwiTG9nZ2VyIiwiRXJyb3IiLCJTdHJlYW0iLCJwa2dKU09OIiwiXyIsImRheWpzIiwiVmVyZGFjY2lvUm90YXRpbmdGaWxlU3RyZWFtIiwiUm90YXRpbmdGaWxlU3RyZWFtIiwid3JpdGUiLCJvYmoiLCJyb3RhdGUiLCJlbWl0IiwibG9nZ2VyIiwiREVGQVVMVF9MT0dHRVJfQ09ORiIsInR5cGUiLCJmb3JtYXQiLCJsZXZlbCIsInNldHVwIiwibG9ncyIsImxvZ1N0YXJ0Iiwic3RyZWFtcyIsImZvckVhY2giLCJ0YXJnZXQiLCJpc1dvcmtlciIsInN0cmVhbSIsIm1lcmdlIiwib3B0aW9ucyIsInBhdGgiLCJyb3RhdGVTdHJlYW0iLCJvbiIsIndhcm4iLCJwdXNoIiwid3JpdGFibGUiLCJkZXN0aW5hdGlvbiIsImRlc3RpbmF0aW9uSXNUVFkiLCJjcmVhdGVXcml0ZVN0cmVhbSIsImZsYWdzIiwiZW5jb2RpbmciLCJlcnIiLCJwcm9jZXNzIiwic3Rkb3V0Iiwic3RkZXJyIiwiaXNUVFkiLCJuYW1lIiwic2VyaWFsaXplcnMiLCJzdGRTZXJpYWxpemVycyIsInJlcSIsInJlcyIsInJlb3BlbkZpbGVTdHJlYW1zIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUpBO0FBTUEsTUFBTUEsT0FBTyxHQUFHQyxPQUFPLENBQUMsU0FBRCxDQUF2Qjs7QUFDQSxNQUFNQyxNQUFNLEdBQUdELE9BQU8sQ0FBQyxRQUFELENBQXRCOztBQUNBLE1BQU1FLEtBQUssR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBckI7O0FBQ0EsTUFBTUcsTUFBTSxHQUFHSCxPQUFPLENBQUMsUUFBRCxDQUF0Qjs7QUFDQSxNQUFNSSxPQUFPLEdBQUdKLE9BQU8sQ0FBQyxvQkFBRCxDQUF2Qjs7QUFDQSxNQUFNSyxDQUFDLEdBQUdMLE9BQU8sQ0FBQyxRQUFELENBQWpC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QVosQ0FBa0Isc0JBQVdDLEdBQVgsRUFBZ0J5QixnQkFBaEIsQ0FBbEI7QUFDRCxTQUZEO0FBR0Q7O0FBRURkLE1BQUFBLE9BQU8sQ0FBQ1csSUFBUixDQUFhO0FBQ1g7QUFDQWpCLFFBQUFBLElBQUksRUFBRSxLQUZLO0FBR1g7QUFDQUUsUUFBQUEsS0FKVztBQUtYO0FBQ0FRLFFBQUFBLE1BQU0sRUFBRUE7QUFORyxPQUFiO0FBUUQ7QUFDRixHQXBGRCxFQU5zRCxDQTRGdEQ7O0FBQ0EsbUJBQUFaLE1BQU0sR0FBRyxJQUFJWixNQUFKLENBQVc7QUFDbEIyQyxJQUFBQSxJQUFJLEVBQUV4QyxPQUFPLENBQUN3QyxJQURJO0FBRWxCdkIsSUFBQUEsT0FBTyxFQUFFQSxPQUZTO0FBR2xCd0IsSUFBQUEsV0FBVyxFQUFFO0FBQ1hOLE1BQUFBLEdBQUcsRUFBRXRDLE1BQU0sQ0FBQzZDLGNBQVAsQ0FBc0JQLEdBRGhCO0FBRVhRLE1BQUFBLEdBQUcsRUFBRTlDLE1BQU0sQ0FBQzZDLGNBQVAsQ0FBc0JDLEdBRmhCO0FBR1hDLE1BQUFBLEdBQUcsRUFBRS9DLE1BQU0sQ0FBQzZDLGNBQVAsQ0FBc0JFO0FBSGhCO0FBSEssR0FBWCxDQUFULENBN0ZzRCxDQXVHdEQ7QUFDQTs7QUFDQSxNQUFJNUIsUUFBSixFQUFjO0FBQ1pQLElBQUFBLE1BQU0sQ0FBQ2tCLElBQVAsQ0FBWSxtQkFBWjtBQUNEOztBQUVEUyxFQUFBQSxPQUFPLENBQUNWLEVBQVIsQ0FBVyxTQUFYLEVBQXNCLFlBQVk7QUFDaEM7QUFDQSxRQUFJakIsTUFBSixFQUFZO0FBQ1Y7QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNNQSxNQUFBQSxNQUFNLENBQUNvQyxpQkFBUDtBQUNEO0FBQ0YsR0FWRDtBQVdEIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgKi9cblxuaW1wb3J0IHsgcHJldHR5VGltZXN0YW1wZWQgfSBmcm9tICcuL2xvZ2dlci9mb3JtYXQvcHJldHR5LXRpbWVzdGFtcGVkJztcbmltcG9ydCB7IHByZXR0eSB9IGZyb20gJy4vbG9nZ2VyL2Zvcm1hdC9wcmV0dHknO1xuaW1wb3J0IHsganNvbkZvcm1hdCB9IGZyb20gJy4vbG9nZ2VyL2Zvcm1hdC9qc29uJztcblxuY29uc3QgY2x1c3RlciA9IHJlcXVpcmUoJ2NsdXN0ZXInKTtcbmNvbnN0IExvZ2dlciA9IHJlcXVpcmUoJ2J1bnlhbicpO1xuY29uc3QgRXJyb3IgPSByZXF1aXJlKCdodHRwLWVycm9ycycpO1xuY29uc3QgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJyk7XG5jb25zdCBwa2dKU09OID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG5jb25zdCBfID0gcmVxdWlyZSgnbG9kYXNoJyk7XG5jb25zdCBkYXlqcyA9IHJlcXVpcmUoJ2RheWpzJyk7XG5cbi8qKlxuICogQSBSb3RhdGluZ0ZpbGVTdHJlYW0gdGhhdCBtb2RpZmllcyB0aGUgbWVzc2FnZSBmaXJzdFxuICovXG5jbGFzcyBWZXJkYWNjaW9Sb3RhdGluZ0ZpbGVTdHJlYW0gZXh0ZW5kcyBMb2dnZXIuUm90YXRpbmdGaWxlU3RyZWFtIHtcbiAgLy8gV2UgZGVwZW5kIG9uIG12IHNvIHRoYXQgdGhpcyBpcyB0aGVyZVxuICB3cml0ZShvYmopIHtcbiAgICBzdXBlci53cml0ZShqc29uRm9ybWF0KG9iaiwgZmFsc2UpKTtcbiAgfVxuXG4gIHJvdGF0ZSgpOiB2b2lkIHtcbiAgICBzdXBlci5yb3RhdGUoKTtcbiAgICB0aGlzLmVtaXQoJ3JvdGF0ZWQnKTtcbiAgfVxufVxuXG5sZXQgbG9nZ2VyO1xuXG5leHBvcnQgaW50ZXJmYWNlIExvZ2dlclRhcmdldCB7XG4gIHR5cGU/OiBzdHJpbmc7XG4gIGZvcm1hdD86IHN0cmluZztcbiAgbGV2ZWw/OiBzdHJpbmc7XG4gIG9wdGlvbnM/OiBhbnk7XG4gIHBhdGg/OiBzdHJpbmc7XG59XG5cbmNvbnN0IERFRkFVTFRfTE9HR0VSX0NPTkYgPSBbeyB0eXBlOiAnc3Rkb3V0JywgZm9ybWF0OiAncHJldHR5JywgbGV2ZWw6ICdodHRwJyB9XTtcblxuLyoqXG4gKiBTZXR1cCB0aGUgQnV5YW4gbG9nZ2VyXG4gKiBAcGFyYW0geyp9IGxvZ3MgbGlzdCBvZiBsb2cgY29uZmlndXJhdGlvblxuICovXG5mdW5jdGlvbiBzZXR1cChsb2dzLCB7IGxvZ1N0YXJ0IH0gPSB7IGxvZ1N0YXJ0OiB0cnVlIH0pIHtcbiAgY29uc3Qgc3RyZWFtczogYW55ID0gW107XG4gIGlmIChsb2dzID09IG51bGwpIHtcbiAgICBsb2dzID0gREVGQVVMVF9MT0dHRVJfQ09ORjtcbiAgfVxuXG4gIGxvZ3MuZm9yRWFjaChmdW5jdGlvbiAodGFyZ2V0OiBMb2dnZXJUYXJnZXQpIHtcbiAgICBsZXQgbGV2ZWwgPSB0YXJnZXQubGV2ZWwgfHwgMzU7XG4gICAgaWYgKGxldmVsID09PSAnaHR0cCcpIHtcbiAgICAgIGxldmVsID0gMzU7XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIGEgc3RyZWFtIGZvciBlYWNoIGxvZyBjb25maWd1cmF0aW9uXG4gICAgaWYgKHRhcmdldC50eXBlID09PSAncm90YXRpbmctZmlsZScpIHtcbiAgICAgIGlmICh0YXJnZXQuZm9ybWF0ICE9PSAnanNvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSb3RhdGluZyBmaWxlIHN0cmVhbXMgb25seSB3b3JrIHdpdGggSlNPTiEnKTtcbiAgICAgIH1cbiAgICAgIGlmIChjbHVzdGVyLmlzV29ya2VyKSB7XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS90cmVudG0vbm9kZS1idW55YW4jc3RyZWFtLXR5cGUtcm90YXRpbmctZmlsZVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NsdXN0ZXIgbW9kZSBpcyBub3Qgc3VwcG9ydGVkIGZvciByb3RhdGluZy1maWxlIScpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdHJlYW0gPSBuZXcgVmVyZGFjY2lvUm90YXRpbmdGaWxlU3RyZWFtKFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIF8ubWVyZ2UoXG4gICAgICAgICAge30sXG4gICAgICAgICAgLy8gRGVmYXVsdHMgY2FuIGJlIGZvdW5kIGhlcmU6IGh0dHBzOi8vZ2l0aHViLmNvbS90cmVudG0vbm9kZS1idW55YW4jc3RyZWFtLXR5cGUtcm90YXRpbmctZmlsZVxuICAgICAgICAgIHRhcmdldC5vcHRpb25zIHx8IHt9LFxuICAgICAgICAgIHsgcGF0aDogdGFyZ2V0LnBhdGgsIGxldmVsIH1cbiAgICAgICAgKVxuICAgICAgKTtcblxuICAgICAgY29uc3Qgcm90YXRlU3RyZWFtID0ge1xuICAgICAgICB0eXBlOiAncmF3JyxcbiAgICAgICAgbGV2ZWwsXG4gICAgICAgIHN0cmVhbVxuICAgICAgfTtcblxuICAgICAgaWYgKGxvZ1N0YXJ0KSB7XG4gICAgICAgIHN0cmVhbS5vbigncm90YXRlZCcsICgpID0+IGxvZ2dlci53YXJuKCdTdGFydCBvZiBsb2dmaWxlJykpO1xuICAgICAgfVxuXG4gICAgICBzdHJlYW1zLnB1c2gocm90YXRlU3RyZWFtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgc3RyZWFtID0gbmV3IFN0cmVhbSgpO1xuICAgICAgc3RyZWFtLndyaXRhYmxlID0gdHJ1ZTtcblxuICAgICAgbGV0IGRlc3RpbmF0aW9uO1xuICAgICAgbGV0IGRlc3RpbmF0aW9uSXNUVFkgPSBmYWxzZTtcbiAgICAgIGlmICh0YXJnZXQudHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAgICAgIC8vIGRlc3RpbmF0aW9uIHN0cmVhbVxuICAgICAgICBkZXN0aW5hdGlvbiA9IHJlcXVpcmUoJ2ZzJykuY3JlYXRlV3JpdGVTdHJlYW0odGFyZ2V0LnBhdGgsIHtcbiAgICAgICAgICBmbGFnczogJ2EnLFxuICAgICAgICAgIGVuY29kaW5nOiAndXRmOCdcbiAgICAgICAgfSk7XG4gICAgICAgIGRlc3RpbmF0aW9uLm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodGFyZ2V0LnR5cGUgPT09ICdzdGRvdXQnIHx8IHRhcmdldC50eXBlID09PSAnc3RkZXJyJykge1xuICAgICAgICBkZXN0aW5hdGlvbiA9IHRhcmdldC50eXBlID09PSAnc3Rkb3V0JyA/IHByb2Nlc3Muc3Rkb3V0IDogcHJvY2Vzcy5zdGRlcnI7XG4gICAgICAgIGRlc3RpbmF0aW9uSXNUVFkgPSBkZXN0aW5hdGlvbi5pc1RUWTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IEVycm9yKCd3cm9uZyB0YXJnZXQgdHlwZSBmb3IgYSBsb2cnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRhcmdldC5mb3JtYXQgPT09ICdwcmV0dHknKSB7XG4gICAgICAgIC8vIG1ha2luZyBmYWtlIHN0cmVhbSBmb3IgcHJldHR5IHByaW50aW5nXG4gICAgICAgIHN0cmVhbS53cml0ZSA9IChvYmopID0+IHtcbiAgICAgICAgICBkZXN0aW5hdGlvbi53cml0ZShwcmV0dHkob2JqLCBkZXN0aW5hdGlvbklzVFRZKSk7XG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHRhcmdldC5mb3JtYXQgPT09ICdwcmV0dHktdGltZXN0YW1wZWQnKSB7XG4gICAgICAgIC8vIG1ha2luZyBmYWtlIHN0cmVhbSBmb3IgcHJldHR5IHByaW50aW5nXG4gICAgICAgIHN0cmVhbS53cml0ZSA9IChvYmopID0+IHtcbiAgICAgICAgICBkZXN0aW5hdGlvbi53cml0ZShwcmV0dHlUaW1lc3RhbXBlZChvYmosIGRlc3RpbmF0aW9uSXNUVFkpKTtcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cmVhbS53cml0ZSA9IChvYmopID0+IHtcbiAgICAgICAgICBkZXN0aW5hdGlvbi53cml0ZShqc29uRm9ybWF0KG9iaiwgZGVzdGluYXRpb25Jc1RUWSkpO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBzdHJlYW1zLnB1c2goe1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHR5cGU6ICdyYXcnLFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGxldmVsLFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHN0cmVhbTogc3RyZWFtXG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIGJ1eWFuIGRlZmF1bHQgY29uZmlndXJhdGlvblxuICBsb2dnZXIgPSBuZXcgTG9nZ2VyKHtcbiAgICBuYW1lOiBwa2dKU09OLm5hbWUsXG4gICAgc3RyZWFtczogc3RyZWFtcyxcbiAgICBzZXJpYWxpemVyczoge1xuICAgICAgZXJyOiBMb2dnZXIuc3RkU2VyaWFsaXplcnMuZXJyLFxuICAgICAgcmVxOiBMb2dnZXIuc3RkU2VyaWFsaXplcnMucmVxLFxuICAgICAgcmVzOiBMb2dnZXIuc3RkU2VyaWFsaXplcnMucmVzXG4gICAgfVxuICB9KTtcblxuICAvLyBJbiBjYXNlIG9mIGFuIGVtcHR5IGxvZyBmaWxlLCB3ZSBlbnN1cmUgdGhlcmUgaXMgYWx3YXlzIHNvbWV0aGluZyBsb2dnZWQuIFRoaXMgYWxzbyBoZWxwcyBzZWUgaWYgdGhlIHNlcnZlclxuICAvLyB3YXMgcmVzdGFydGVkIGluIGFueSBjYXNlc1xuICBpZiAobG9nU3RhcnQpIHtcbiAgICBsb2dnZXIud2FybignVmVyZGFjY2lvIHN0YXJ0ZWQnKTtcbiAgfVxuXG4gIHByb2Nlc3Mub24oJ1NJR1VTUjInLCBmdW5jdGlvbiAoKSB7XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3RyZW50bS9ub2RlLWJ1bnlhbiNzdHJlYW0tdHlwZS1yb3RhdGluZy1maWxlXG4gICAgaWYgKGxvZ2dlcikge1xuICAgICAgLyoqXG4gICAgICAgKiBOb3RlIG9uIGxvZyByb3RhdGlvbjogT2Z0ZW4geW91IG1heSBiZSB1c2luZyBleHRlcm5hbCBsb2cgcm90YXRpb24gdXRpbGl0aWVzIGxpa2UgbG9ncm90YXRlIG9uIExpbnV4IG9yIGxvZ2FkbVxuICAgICAgICogb24gU21hcnRPUy9JbGx1bW9zLiBJbiB0aG9zZSBjYXNlcywgdW5sZXNzIHlvdXIgYXJlIGVuc3VyaW5nIFwiY29weSBhbmQgdHJ1bmNhdGVcIiBzZW1hbnRpY3NcbiAgICAgICAqICh2aWEgY29weXRydW5jYXRlIHdpdGggbG9ncm90YXRlIG9yIC1jIHdpdGggbG9nYWRtKSB0aGVuIHRoZSBmZCBmb3IgeW91ciAnZmlsZScgc3RyZWFtIHdpbGwgY2hhbmdlLlxuICAgICAgICovXG4gICAgICBsb2dnZXIucmVvcGVuRmlsZVN0cmVhbXMoKTtcbiAgICB9XG4gIH0pO1xufVxuXG5leHBvcnQgeyBzZXR1cCwgbG9nZ2VyIH07XG4iXX0=