@verdaccio/logger 6.0.0-6-next.10 → 6.0.0-6-next.13

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 CHANGED
@@ -1,5 +1,82 @@
1
1
  # @verdaccio/logger
2
2
 
3
+ ## 6.0.0-6-next.13
4
+
5
+ ### Patch Changes
6
+
7
+ - 351aeeaa: fix(deps): @verdaccio/utils should be a prod dep of local-storage
8
+ - Updated dependencies [351aeeaa]
9
+ - @verdaccio/core@6.0.0-6-next.7
10
+
11
+ ## 6.0.0-6-next.12
12
+
13
+ ### Major Changes
14
+
15
+ - 292c0a37: feat!: replace deprecated request dependency by got
16
+
17
+ This is a big refactoring of the core, fetching dependencies, improve code, more tests and better stability. This is essential for the next release, will take some time but would allow modularize more the core.
18
+
19
+ ## Notes
20
+
21
+ - Remove deprecated `request` by other `got`, retry improved, custom Agent ( got does not include it built-in)
22
+ - Remove `async` dependency from storage (used by core) it was linked with proxy somehow safe to remove now
23
+ - Refactor with promises instead callback wherever is possible
24
+ - ~Document the API~
25
+ - Improve testing, integration tests
26
+ - Bugfix
27
+ - Clean up old validations
28
+ - Improve performance
29
+
30
+ ## 💥 Breaking changes
31
+
32
+ - Plugin API methods were callbacks based are returning promises, this will break current storage plugins, check documentation for upgrade.
33
+ - Write Tarball, Read Tarball methods parameters change, a new set of options like `AbortController` signals are being provided to the `addAbortSignal` can be internally used with Streams when a request is aborted. eg: `addAbortSignal(signal, fs.createReadStream(pathName));`
34
+ - `@verdaccio/streams` stream abort support is legacy is being deprecated removed
35
+ - Remove AWS and Google Cloud packages for future refactoring [#2574](https://github.com/verdaccio/verdaccio/pull/2574).
36
+
37
+ - a3a209b5: feat: migrate to pino.js 8
38
+
39
+ ### Patch Changes
40
+
41
+ - Updated dependencies [292c0a37]
42
+ - Updated dependencies [a3a209b5]
43
+ - Updated dependencies [00d1d2a1]
44
+ - @verdaccio/core@6.0.0-6-next.6
45
+ - @verdaccio/logger-prettify@6.0.0-6-next.7
46
+
47
+ ## 6.0.0-6-next.11
48
+
49
+ ### Major Changes
50
+
51
+ - 82cb0f2b: feat!: config.logs throw an error, logging config not longer accept array or logs property
52
+
53
+ ### 💥 Breaking change
54
+
55
+ This is valid
56
+
57
+ ```yaml
58
+ log: { type: stdout, format: pretty, level: http }
59
+ ```
60
+
61
+ This is invalid
62
+
63
+ ```yaml
64
+ logs: { type: stdout, format: pretty, level: http }
65
+ ```
66
+
67
+ or
68
+
69
+ ```yaml
70
+ logs:
71
+ - [{ type: stdout, format: pretty, level: http }]
72
+ ```
73
+
74
+ ### Patch Changes
75
+
76
+ - Updated dependencies [82cb0f2b]
77
+ - Updated dependencies [5167bb52]
78
+ - @verdaccio/core@6.0.0-6-next.5
79
+
3
80
  ## 6.0.0-6-next.10
4
81
 
5
82
  ### Patch Changes
package/build/index.js CHANGED
@@ -15,6 +15,12 @@ Object.defineProperty(exports, "logger", {
15
15
  return _logger.logger;
16
16
  }
17
17
  });
18
+ Object.defineProperty(exports, "prepareSetup", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _logger.prepareSetup;
22
+ }
23
+ });
18
24
  Object.defineProperty(exports, "setup", {
19
25
  enumerable: true,
20
26
  get: function () {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA","sourcesContent":["export { setup, createLogger, logger } from './logger';\n"],"file":"index.js"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export { setup, createLogger, logger, prepareSetup } from './logger';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA"}
package/build/logger.js CHANGED
@@ -4,52 +4,46 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.createLogger = createLogger;
7
- exports.getLogger = getLogger;
8
7
  exports.logger = void 0;
8
+ exports.prepareSetup = prepareSetup;
9
9
  exports.setup = setup;
10
10
 
11
- var _debug = _interopRequireDefault(require("debug"));
11
+ var _colorette = require("colorette");
12
12
 
13
- var _lodash = _interopRequireDefault(require("lodash"));
13
+ var _debug = _interopRequireDefault(require("debug"));
14
14
 
15
15
  var _pino = _interopRequireDefault(require("pino"));
16
16
 
17
- var _core = require("@verdaccio/core");
18
-
19
- var _loggerPrettify = _interopRequireWildcard(require("@verdaccio/logger-prettify"));
20
-
21
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
22
-
23
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
+ var _loggerPrettify = require("@verdaccio/logger-prettify");
24
18
 
25
19
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26
20
 
21
+ // <reference types="node" />
27
22
  const debug = (0, _debug.default)('verdaccio:logger');
28
- let logger;
29
- exports.logger = logger;
30
23
 
31
24
  function isProd() {
32
25
  return process.env.NODE_ENV === 'production';
33
26
  }
34
27
 
28
+ function hasColors(colors) {
29
+ if (colors) {
30
+ return _colorette.isColorSupported;
31
+ }
32
+
33
+ return typeof colors === 'undefined' ? true : colors;
34
+ }
35
+
35
36
  const DEFAULT_LOG_FORMAT = isProd() ? 'json' : 'pretty';
36
37
 
37
38
  function createLogger(options = {
38
39
  level: 'http'
39
- }, destination = _pino.default.destination(1), format = DEFAULT_LOG_FORMAT, prettyPrintOptions = {
40
- // we hide warning since the prettifier should not be used in production
41
- // https://getpino.io/#/docs/pretty?id=prettifier-api
42
- suppressFlushSyncWarning: true
43
- }) {
44
- if (_lodash.default.isNil(format)) {
45
- format = DEFAULT_LOG_FORMAT;
46
- }
47
-
40
+ }, // eslint-disable-next-line no-undef
41
+ destination = _pino.default.destination(1), format = DEFAULT_LOG_FORMAT) {
42
+ debug('setup logger');
48
43
  let pinoConfig = {
49
44
  customLevels: {
50
45
  http: 25
51
46
  },
52
- ...options,
53
47
  level: options.level,
54
48
  serializers: {
55
49
  err: _pino.default.stdSerializers.err,
@@ -59,21 +53,24 @@ function createLogger(options = {
59
53
  };
60
54
  debug('has prettifier? %o', !isProd()); // pretty logs are not allowed in production for performance reasons
61
55
 
62
- if ((format === DEFAULT_LOG_FORMAT || format !== 'json') && isProd() === false) {
56
+ if (['pretty-timestamped', 'pretty'].includes(format) && isProd() === false) {
63
57
  pinoConfig = Object.assign({}, pinoConfig, {
64
- prettifier: _loggerPrettify.default,
65
- // more info
66
- // https://github.com/pinojs/pino-pretty/issues/37
67
- prettyPrint: {
68
- levelFirst: true,
69
- prettyStamp: format === 'pretty-timestamped',
70
- ...prettyPrintOptions
58
+ transport: {
59
+ target: '@verdaccio/logger-prettify',
60
+ options: {
61
+ // string or 1 (file descriptor for process.stdout)
62
+ destination: options.path || 1,
63
+ colors: hasColors(options.colors),
64
+ prettyStamp: format === 'pretty-timestamped'
65
+ }
71
66
  }
72
67
  });
73
68
  } else {
74
- pinoConfig = Object.assign({}, pinoConfig, {
69
+ pinoConfig = { ...pinoConfig,
75
70
  // more info
76
71
  // https://github.com/pinojs/pino/blob/v7.1.0/docs/api.md#hooks-object
72
+ // TODO: improve typings here
73
+ // @ts-ignore
77
74
  hooks: {
78
75
  logMethod(inputArgs, method) {
79
76
  const [templateObject, message, ...otherArgs] = inputArgs;
@@ -84,10 +81,13 @@ function createLogger(options = {
84
81
  }
85
82
 
86
83
  }
87
- });
84
+ };
88
85
  }
89
86
 
90
87
  const logger = (0, _pino.default)(pinoConfig, destination);
88
+ /* eslint-disable */
89
+
90
+ /* istanbul ignore next */
91
91
 
92
92
  if (process.env.DEBUG) {
93
93
  logger.on('level-change', (lvl, val, prevLvl, prevVal) => {
@@ -98,37 +98,17 @@ function createLogger(options = {
98
98
  return logger;
99
99
  }
100
100
 
101
- function getLogger() {
102
- if (_lodash.default.isNil(logger)) {
103
- // FIXME: not sure about display here a warning
104
- _core.warningUtils.emit(_core.warningUtils.Codes.VERWAR002);
105
-
106
- return;
107
- }
108
-
109
- return logger;
110
- }
111
-
112
101
  const DEFAULT_LOGGER_CONF = {
113
102
  type: 'stdout',
114
103
  format: 'pretty',
115
104
  level: 'http'
116
105
  };
117
106
 
118
- function setup(options = DEFAULT_LOGGER_CONF) {
107
+ function prepareSetup(options = DEFAULT_LOGGER_CONF) {
119
108
  var _loggerConfig;
120
109
 
121
- debug('setup logger');
122
- const isLegacyConf = Array.isArray(options);
123
-
124
- if (isLegacyConf) {
125
- _core.warningUtils.emit(_core.warningUtils.Codes.VERDEP002);
126
- } // verdaccio 5 does not allow multiple logger configuration
127
- // backward compatible, pick only the first option
128
- // next major will thrown an error
129
-
130
-
131
- let loggerConfig = isLegacyConf ? options[0] : options;
110
+ let logger;
111
+ let loggerConfig = options;
132
112
 
133
113
  if (!((_loggerConfig = loggerConfig) !== null && _loggerConfig !== void 0 && _loggerConfig.level)) {
134
114
  loggerConfig = Object.assign({}, {
@@ -144,41 +124,39 @@ function setup(options = DEFAULT_LOGGER_CONF) {
144
124
  debug('logging file enabled');
145
125
 
146
126
  const destination = _pino.default.destination(loggerConfig.path);
127
+ /* eslint-disable */
147
128
 
148
- process.on('SIGUSR2', () => destination.reopen());
149
- exports.logger = logger = createLogger(pinoConfig, destination, loggerConfig.format);
150
- } else if (loggerConfig.type === 'rotating-file') {
151
- _core.warningUtils.emit(_core.warningUtils.Codes.VERWAR003);
129
+ /* istanbul ignore next */
152
130
 
153
- debug('logging stdout enabled');
154
- exports.logger = logger = createLogger(pinoConfig, _pino.default.destination(1), loggerConfig.format);
155
- } else {
156
- debug('logging stdout enabled');
157
- exports.logger = logger = createLogger(pinoConfig, _pino.default.destination(1), loggerConfig.format);
158
- }
159
131
 
160
- if (isProd()) {
161
- // why only on prod? https://github.com/pinojs/pino/issues/920#issuecomment-710807667
162
- const finalHandler = _pino.default.final(logger, (err, finalLogger, event) => {
163
- finalLogger.info(`${event} caught`);
132
+ process.on('SIGUSR2', () => destination.reopen()); // @ts-ignore
164
133
 
165
- if (err) {
166
- finalLogger.error(err, 'error caused exit');
167
- }
134
+ logger = createLogger({
135
+ level: loggerConfig.level,
136
+ path: loggerConfig.path,
137
+ colors: loggerConfig.colors
138
+ }, destination, loggerConfig.format);
139
+ return logger;
140
+ } else {
141
+ debug('logging stdout enabled'); // @ts-ignore
168
142
 
169
- process.exit(err ? 1 : 0);
170
- });
143
+ logger = createLogger({
144
+ level: loggerConfig.level,
145
+ colors: loggerConfig.colors
146
+ }, _pino.default.destination(1), loggerConfig.format);
147
+ return logger;
148
+ }
149
+ }
150
+
151
+ let logger;
152
+ exports.logger = logger;
171
153
 
172
- process.on('uncaughtException', err => finalHandler(err, 'uncaughtException'));
173
- process.on('unhandledRejection', err => finalHandler(err, 'unhandledRejection'));
174
- process.on('beforeExit', () => finalHandler(null, 'beforeExit'));
175
- process.on('exit', () => finalHandler(null, 'exit'));
176
- process.on('uncaughtException', err => finalHandler(err, 'uncaughtException'));
177
- process.on('SIGINT', () => finalHandler(null, 'SIGINT'));
178
- process.on('SIGQUIT', () => finalHandler(null, 'SIGQUIT'));
179
- process.on('SIGTERM', () => finalHandler(null, 'SIGTERM'));
154
+ function setup(options) {
155
+ if (typeof logger !== 'undefined') {
156
+ return logger;
180
157
  }
181
158
 
159
+ exports.logger = logger = prepareSetup(options);
182
160
  return logger;
183
161
  }
184
162
  //# sourceMappingURL=logger.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/logger.ts"],"names":["debug","logger","isProd","process","env","NODE_ENV","DEFAULT_LOG_FORMAT","createLogger","options","level","destination","pino","format","prettyPrintOptions","suppressFlushSyncWarning","_","isNil","pinoConfig","customLevels","http","serializers","err","stdSerializers","req","res","Object","assign","prettifier","prettyPrint","levelFirst","prettyStamp","hooks","logMethod","inputArgs","method","templateObject","message","otherArgs","templateVars","getOwnPropertyNames","length","apply","hydratedMessage","DEBUG","on","lvl","val","prevLvl","prevVal","getLogger","warningUtils","emit","Codes","VERWAR002","DEFAULT_LOGGER_CONF","type","setup","isLegacyConf","Array","isArray","VERDEP002","loggerConfig","path","reopen","VERWAR003","finalHandler","final","finalLogger","event","info","error","exit"],"mappings":"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","sourcesContent":["import buildDebug from 'debug';\nimport _ from 'lodash';\nimport pino from 'pino';\n\nimport { warningUtils } from '@verdaccio/core';\nimport prettifier, { fillInMsgTemplate } from '@verdaccio/logger-prettify';\n\nconst debug = buildDebug('verdaccio:logger');\n\nexport let logger;\n\nfunction isProd() {\n return process.env.NODE_ENV === 'production';\n}\n\nconst DEFAULT_LOG_FORMAT = isProd() ? 'json' : 'pretty';\n\nexport type LogPlugin = {\n dest: string;\n options?: any[];\n};\n\nexport type LogType = 'file' | 'stdout';\nexport type LogFormat = 'json' | 'pretty-timestamped' | 'pretty';\n\nexport function createLogger(\n options = { level: 'http' },\n destination = pino.destination(1),\n format: LogFormat = DEFAULT_LOG_FORMAT,\n prettyPrintOptions = {\n // we hide warning since the prettifier should not be used in production\n // https://getpino.io/#/docs/pretty?id=prettifier-api\n suppressFlushSyncWarning: true,\n }\n) {\n if (_.isNil(format)) {\n format = DEFAULT_LOG_FORMAT;\n }\n\n let pinoConfig = {\n customLevels: {\n http: 25,\n },\n ...options,\n level: options.level,\n serializers: {\n err: pino.stdSerializers.err,\n req: pino.stdSerializers.req,\n res: pino.stdSerializers.res,\n },\n };\n\n debug('has prettifier? %o', !isProd());\n // pretty logs are not allowed in production for performance reasons\n if ((format === DEFAULT_LOG_FORMAT || format !== 'json') && isProd() === false) {\n pinoConfig = Object.assign({}, pinoConfig, {\n prettifier,\n // more info\n // https://github.com/pinojs/pino-pretty/issues/37\n prettyPrint: {\n levelFirst: true,\n prettyStamp: format === 'pretty-timestamped',\n ...prettyPrintOptions,\n },\n });\n } else {\n pinoConfig = Object.assign({}, pinoConfig, {\n // more info\n // https://github.com/pinojs/pino/blob/v7.1.0/docs/api.md#hooks-object\n hooks: {\n logMethod(inputArgs, method) {\n const [templateObject, message, ...otherArgs] = inputArgs;\n const templateVars =\n !!templateObject && typeof templateObject === 'object'\n ? Object.getOwnPropertyNames(templateObject)\n : [];\n if (!message || !templateVars.length) return method.apply(this, inputArgs);\n const hydratedMessage = fillInMsgTemplate(message, templateObject, false);\n return method.apply(this, [templateObject, hydratedMessage, ...otherArgs]);\n },\n },\n });\n }\n const logger = pino(pinoConfig, destination);\n\n if (process.env.DEBUG) {\n logger.on('level-change', (lvl, val, prevLvl, prevVal) => {\n debug('%s (%d) was changed to %s (%d)', lvl, val, prevLvl, prevVal);\n });\n }\n\n return logger;\n}\n\nexport function getLogger() {\n if (_.isNil(logger)) {\n // FIXME: not sure about display here a warning\n warningUtils.emit(warningUtils.Codes.VERWAR002);\n return;\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 LoggerConfigItem = {\n type?: LogType;\n plugin?: LogPlugin;\n format?: LogFormat;\n path?: string;\n level?: string;\n};\n\nexport type LoggerConfig = LoggerConfigItem[];\n\nexport function setup(options: LoggerConfig | LoggerConfigItem = DEFAULT_LOGGER_CONF) {\n debug('setup logger');\n const isLegacyConf = Array.isArray(options);\n if (isLegacyConf) {\n warningUtils.emit(warningUtils.Codes.VERDEP002);\n }\n\n // verdaccio 5 does not allow multiple logger configuration\n // backward compatible, pick only the first option\n // next major will thrown an error\n let loggerConfig = isLegacyConf ? options[0] : options;\n if (!loggerConfig?.level) {\n loggerConfig = Object.assign(\n {},\n {\n level: 'http',\n },\n loggerConfig\n );\n }\n const pinoConfig = { level: loggerConfig.level };\n if (loggerConfig.type === 'file') {\n debug('logging file enabled');\n const destination = pino.destination(loggerConfig.path);\n process.on('SIGUSR2', () => destination.reopen());\n logger = createLogger(pinoConfig, destination, loggerConfig.format);\n } else if (loggerConfig.type === 'rotating-file') {\n warningUtils.emit(warningUtils.Codes.VERWAR003);\n debug('logging stdout enabled');\n logger = createLogger(pinoConfig, pino.destination(1), loggerConfig.format);\n } else {\n debug('logging stdout enabled');\n logger = createLogger(pinoConfig, pino.destination(1), loggerConfig.format);\n }\n\n if (isProd()) {\n // why only on prod? https://github.com/pinojs/pino/issues/920#issuecomment-710807667\n const finalHandler = pino.final(logger, (err, finalLogger, event) => {\n finalLogger.info(`${event} caught`);\n if (err) {\n finalLogger.error(err, 'error caused exit');\n }\n process.exit(err ? 1 : 0);\n });\n\n process.on('uncaughtException', (err) => finalHandler(err, 'uncaughtException'));\n process.on('unhandledRejection', (err) => finalHandler(err as Error, 'unhandledRejection'));\n process.on('beforeExit', () => finalHandler(null, 'beforeExit'));\n process.on('exit', () => finalHandler(null, 'exit'));\n process.on('uncaughtException', (err) => finalHandler(err, 'uncaughtException'));\n process.on('SIGINT', () => finalHandler(null, 'SIGINT'));\n process.on('SIGQUIT', () => finalHandler(null, 'SIGQUIT'));\n process.on('SIGTERM', () => finalHandler(null, 'SIGTERM'));\n }\n\n return logger;\n}\n"],"file":"logger.js"}
1
+ {"version":3,"file":"logger.js","names":["debug","buildDebug","isProd","process","env","NODE_ENV","hasColors","colors","isColorSupported","DEFAULT_LOG_FORMAT","createLogger","options","level","destination","pino","format","pinoConfig","customLevels","http","serializers","err","stdSerializers","req","res","includes","Object","assign","transport","target","path","prettyStamp","hooks","logMethod","inputArgs","method","templateObject","message","otherArgs","templateVars","getOwnPropertyNames","length","apply","hydratedMessage","fillInMsgTemplate","logger","DEBUG","on","lvl","val","prevLvl","prevVal","DEFAULT_LOGGER_CONF","type","prepareSetup","loggerConfig","reopen","setup"],"sources":["../src/logger.ts"],"sourcesContent":["// <reference types=\"node\" />\nimport { isColorSupported } from 'colorette';\nimport buildDebug from 'debug';\nimport pino, { Logger } from 'pino';\n\nimport { fillInMsgTemplate } from '@verdaccio/logger-prettify';\nimport { LoggerConfigItem, LoggerFormat } from '@verdaccio/types';\n\nconst debug = buildDebug('verdaccio:logger');\n\nfunction isProd() {\n return process.env.NODE_ENV === 'production';\n}\n\nfunction hasColors(colors: boolean | undefined) {\n if (colors) {\n return isColorSupported;\n }\n return typeof colors === 'undefined' ? true : colors;\n}\n\nconst DEFAULT_LOG_FORMAT = isProd() ? 'json' : 'pretty';\n\nexport type LogPlugin = {\n dest: string;\n options?: any[];\n};\n\ntype LoggerOptions = { level?: string; path?: string; colors?: boolean; sync?: boolean };\n\nexport function createLogger(\n options: LoggerOptions = { level: 'http' },\n // eslint-disable-next-line no-undef\n destination: NodeJS.WritableStream = pino.destination(1),\n format: LoggerFormat = DEFAULT_LOG_FORMAT\n) {\n debug('setup logger');\n let pinoConfig = {\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 };\n\n debug('has prettifier? %o', !isProd());\n // pretty logs are not allowed in production for performance reasons\n if (['pretty-timestamped', 'pretty'].includes(format) && isProd() === false) {\n pinoConfig = Object.assign({}, pinoConfig, {\n transport: {\n target: '@verdaccio/logger-prettify',\n options: {\n // string or 1 (file descriptor for process.stdout)\n destination: options.path || 1,\n colors: hasColors(options.colors),\n prettyStamp: format === 'pretty-timestamped',\n },\n },\n });\n } else {\n pinoConfig = {\n ...pinoConfig,\n // more info\n // https://github.com/pinojs/pino/blob/v7.1.0/docs/api.md#hooks-object\n // TODO: improve typings here\n // @ts-ignore\n hooks: {\n logMethod(\n inputArgs: [any, any, ...any[]],\n method: {\n apply: (arg0: { logMethod: (inputArgs: any, method: any) => any }, arg1: any[]) => any;\n }\n ) {\n const [templateObject, message, ...otherArgs] = inputArgs;\n const templateVars =\n !!templateObject && typeof templateObject === 'object'\n ? Object.getOwnPropertyNames(templateObject)\n : [];\n if (!message || !templateVars.length) return method.apply(this, inputArgs);\n const hydratedMessage = fillInMsgTemplate(message, templateObject, false);\n return method.apply(this, [templateObject, hydratedMessage, ...otherArgs]);\n },\n },\n };\n }\n const logger = pino(pinoConfig, destination);\n\n /* eslint-disable */\n /* istanbul ignore next */\n if (process.env.DEBUG) {\n logger.on('level-change', (lvl, val, prevLvl, prevVal) => {\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 prepareSetup(options: LoggerConfigItem = DEFAULT_LOGGER_CONF) {\n let logger: Logger<{\n customLevels: { http: number };\n level: string | undefined;\n serializers: { err: any; req: any; res: any };\n }>;\n let loggerConfig = options;\n if (!loggerConfig?.level) {\n loggerConfig = Object.assign(\n {},\n {\n level: 'http',\n },\n loggerConfig\n );\n }\n const pinoConfig = { level: loggerConfig.level };\n if (loggerConfig.type === 'file') {\n debug('logging file enabled');\n const destination = pino.destination(loggerConfig.path);\n /* eslint-disable */\n /* istanbul ignore next */\n process.on('SIGUSR2', () => destination.reopen());\n // @ts-ignore\n logger = createLogger(\n { level: loggerConfig.level, path: loggerConfig.path, colors: loggerConfig.colors },\n destination,\n loggerConfig.format\n );\n return logger;\n } else {\n debug('logging stdout enabled');\n // @ts-ignore\n logger = createLogger(\n { level: loggerConfig.level, colors: loggerConfig.colors },\n pino.destination(1),\n loggerConfig.format\n );\n return logger;\n }\n}\n\nexport let logger: Logger;\n\nexport function setup(options: LoggerConfigItem) {\n if (typeof logger !== 'undefined') {\n return logger;\n }\n\n logger = prepareSetup(options);\n return logger;\n}\n"],"mappings":"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"}
package/jest.config.js CHANGED
@@ -1,5 +1,10 @@
1
1
  const config = require('../../jest/config');
2
2
 
3
3
  module.exports = Object.assign({}, config, {
4
- verbose: true,
4
+ coverageThreshold: {
5
+ global: {
6
+ // FIXME: increase to 90
7
+ lines: 39,
8
+ },
9
+ },
5
10
  });
package/package.json CHANGED
@@ -1,55 +1,56 @@
1
1
  {
2
- "name": "@verdaccio/logger",
3
- "version": "6.0.0-6-next.10",
4
- "description": "logger",
5
- "main": "./build/index.js",
6
- "types": "build/index.d.ts",
7
- "author": {
8
- "name": "Juan Picado",
9
- "email": "juanpicado19@gmail.com"
10
- },
11
- "repository": {
12
- "type": "https",
13
- "url": "https://github.com/verdaccio/verdaccio"
14
- },
15
- "license": "MIT",
16
- "homepage": "https://verdaccio.org",
17
- "keywords": [
18
- "private",
19
- "package",
20
- "repository",
21
- "registry",
22
- "enterprise",
23
- "modules",
24
- "proxy",
25
- "server",
26
- "verdaccio"
27
- ],
28
- "engines": {
29
- "node": ">=14",
30
- "npm": ">=6"
31
- },
32
- "dependencies": {
33
- "@verdaccio/core": "6.0.0-6-next.4",
34
- "@verdaccio/logger-prettify": "6.0.0-6-next.6",
35
- "debug": "4.3.3",
36
- "lodash": "4.17.21",
37
- "pino": "7.6.4"
38
- },
39
- "devDependencies": {
40
- "@verdaccio/types": "11.0.0-6-next.10"
41
- },
42
- "funding": {
43
- "type": "opencollective",
44
- "url": "https://opencollective.com/verdaccio"
45
- },
46
- "scripts": {
47
- "clean": "rimraf ./build",
48
- "test": "cross-env NODE_ENV=test BABEL_ENV=test jest --runTestsByPath",
49
- "type-check": "tsc --noEmit -p tsconfig.build.json",
50
- "build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
51
- "build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
52
- "watch": "pnpm build:js -- --watch",
53
- "build": "cross-env BABEL_ENV=registry babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps"
54
- }
55
- }
2
+ "name": "@verdaccio/logger",
3
+ "version": "6.0.0-6-next.13",
4
+ "description": "logger",
5
+ "main": "./build/index.js",
6
+ "types": "build/index.d.ts",
7
+ "author": {
8
+ "name": "Juan Picado",
9
+ "email": "juanpicado19@gmail.com"
10
+ },
11
+ "repository": {
12
+ "type": "https",
13
+ "url": "https://github.com/verdaccio/verdaccio"
14
+ },
15
+ "license": "MIT",
16
+ "homepage": "https://verdaccio.org",
17
+ "keywords": [
18
+ "private",
19
+ "package",
20
+ "repository",
21
+ "registry",
22
+ "enterprise",
23
+ "modules",
24
+ "proxy",
25
+ "server",
26
+ "verdaccio"
27
+ ],
28
+ "engines": {
29
+ "node": ">=14",
30
+ "npm": ">=6"
31
+ },
32
+ "dependencies": {
33
+ "@verdaccio/core": "6.0.0-6-next.7",
34
+ "@verdaccio/logger-prettify": "6.0.0-6-next.7",
35
+ "debug": "4.3.4",
36
+ "colorette": "2.0.19",
37
+ "pino": "8.4.2"
38
+ },
39
+ "devDependencies": {
40
+ "@verdaccio/types": "11.0.0-6-next.15"
41
+ },
42
+ "funding": {
43
+ "type": "opencollective",
44
+ "url": "https://opencollective.com/verdaccio"
45
+ },
46
+ "scripts": {
47
+ "clean": "rimraf ./build",
48
+ "test": "cross-env TZ=utc jest",
49
+ "type-check": "tsc --noEmit -p tsconfig.build.json",
50
+ "build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
51
+ "build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
52
+ "watch": "pnpm build:js -- --watch",
53
+ "build": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps"
54
+ },
55
+ "readme": "# @verdaccio/logger\n\n[![backers](https://opencollective.com/verdaccio/tiers/backer/badge.svg?label=Backer&color=brightgreen)](https://opencollective.com/verdaccio)\n[![stackshare](https://img.shields.io/badge/Follow%20on-StackShare-blue.svg?logo=stackshare&style=flat)](https://stackshare.io/verdaccio)\n[![MIT](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/verdaccio/verdaccio/blob/master/LICENSE)\n[![Crowdin](https://d322cqt584bo4o.cloudfront.net/verdaccio/localized.svg)](https://crowdin.com/project/verdaccio)\n[![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/verdaccio/verdaccio)](https://www.tickgit.com/browse?repo=github.com/verdaccio/verdaccio)\n\n[![Twitter followers](https://img.shields.io/twitter/follow/verdaccio_npm.svg?style=social&label=Follow)](https://twitter.com/verdaccio_npm)\n[![Github](https://img.shields.io/github/stars/verdaccio/verdaccio.svg?style=social&label=Stars)](https://github.com/verdaccio/verdaccio/stargazers)\n\n## Donations\n\nVerdaccio is run by **volunteers**; nobody is working full-time on it. If you find this project to be useful and would like to support its development, consider making a donation - **your logo might end up in this readme.** 😉\n\n**[Donate](https://opencollective.com/verdaccio)** 💵👍🏻 starting from _\\$1/month_ or just one single contribution.\n\n## Report a vulnerability\n\nIf you want to report a security vulnerability, please follow the steps which we have defined for you in our [security policy](https://github.com/verdaccio/verdaccio/security/policy).\n\n## Open Collective Sponsors\n\nSupport this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/verdaccio#sponsor)]\n\n[![sponsor](https://opencollective.com/verdaccio/sponsor/0/avatar.svg)](https://opencollective.com/verdaccio/sponsor/0/website)\n[![sponsor](https://opencollective.com/verdaccio/sponsor/1/avatar.svg)](https://opencollective.com/verdaccio/sponsor/1/website)\n[![sponsor](https://opencollective.com/verdaccio/sponsor/2/avatar.svg)](https://opencollective.com/verdaccio/sponsor/2/website)\n[![sponsor](https://opencollective.com/verdaccio/sponsor/3/avatar.svg)](https://opencollective.com/verdaccio/sponsor/3/website)\n[![sponsor](https://opencollective.com/verdaccio/sponsor/4/avatar.svg)](https://opencollective.com/verdaccio/sponsor/4/website)\n[![sponsor](https://opencollective.com/verdaccio/sponsor/5/avatar.svg)](https://opencollective.com/verdaccio/sponsor/5/website)\n[![sponsor](https://opencollective.com/verdaccio/sponsor/6/avatar.svg)](https://opencollective.com/verdaccio/sponsor/6/website)\n[![sponsor](https://opencollective.com/verdaccio/sponsor/7/avatar.svg)](https://opencollective.com/verdaccio/sponsor/7/website)\n[![sponsor](https://opencollective.com/verdaccio/sponsor/8/avatar.svg)](https://opencollective.com/verdaccio/sponsor/8/website)\n[![sponsor](https://opencollective.com/verdaccio/sponsor/9/avatar.svg)](https://opencollective.com/verdaccio/sponsor/9/website)\n\n## Open Collective Backers\n\nThank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/verdaccio#backer)]\n\n[![backers](https://opencollective.com/verdaccio/backers.svg?width=890)](https://opencollective.com/verdaccio#backers)\n\n## Special Thanks\n\nThanks to the following companies to help us to achieve our goals providing free open source licenses.\n\n[![jetbrain](assets/thanks/jetbrains/logo.png)](https://www.jetbrains.com/)\n[![crowdin](assets/thanks/crowdin/logo.png)](https://crowdin.com/)\n[![balsamiq](assets/thanks/balsamiq/logo.jpg)](https://balsamiq.com/)\n\n## Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n\n[![contributors](https://opencollective.com/verdaccio/contributors.svg?width=890&button=true)](../../graphs/contributors)\n\n### FAQ / Contact / Troubleshoot\n\nIf you have any issue you can try the following options, do no desist to ask or check our issues database, perhaps someone has asked already what you are looking for.\n\n- [Blog](https://verdaccio.org/blog/)\n- [Donations](https://opencollective.com/verdaccio)\n- [Reporting an issue](https://github.com/verdaccio/verdaccio/blob/master/CONTRIBUTING.md#reporting-a-bug)\n- [Running discussions](https://github.com/verdaccio/verdaccio/issues?q=is%3Aissue+is%3Aopen+label%3Adiscuss)\n- [Chat](http://chat.verdaccio.org/)\n- [Logos](https://verdaccio.org/docs/en/logo)\n- [Docker Examples](https://github.com/verdaccio/docker-examples)\n- [FAQ](https://github.com/verdaccio/verdaccio/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3Aquestion%20)\n\n### License\n\nVerdaccio is [MIT licensed](https://github.com/verdaccio/verdaccio/blob/master/LICENSE)\n\nThe Verdaccio documentation and logos (excluding /thanks, e.g., .md, .png, .sketch) files within the /assets folder) is\n[Creative Commons licensed](https://github.com/verdaccio/verdaccio/blob/master/LICENSE-docs).\n"
56
+ }
package/src/index.ts CHANGED
@@ -1 +1 @@
1
- export { setup, createLogger, logger } from './logger';
1
+ export { setup, createLogger, logger, prepareSetup } from './logger';
package/src/logger.ts CHANGED
@@ -1,18 +1,24 @@
1
+ // <reference types="node" />
2
+ import { isColorSupported } from 'colorette';
1
3
  import buildDebug from 'debug';
2
- import _ from 'lodash';
3
- import pino from 'pino';
4
+ import pino, { Logger } from 'pino';
4
5
 
5
- import { warningUtils } from '@verdaccio/core';
6
- import prettifier, { fillInMsgTemplate } from '@verdaccio/logger-prettify';
6
+ import { fillInMsgTemplate } from '@verdaccio/logger-prettify';
7
+ import { LoggerConfigItem, LoggerFormat } from '@verdaccio/types';
7
8
 
8
9
  const debug = buildDebug('verdaccio:logger');
9
10
 
10
- export let logger;
11
-
12
11
  function isProd() {
13
12
  return process.env.NODE_ENV === 'production';
14
13
  }
15
14
 
15
+ function hasColors(colors: boolean | undefined) {
16
+ if (colors) {
17
+ return isColorSupported;
18
+ }
19
+ return typeof colors === 'undefined' ? true : colors;
20
+ }
21
+
16
22
  const DEFAULT_LOG_FORMAT = isProd() ? 'json' : 'pretty';
17
23
 
18
24
  export type LogPlugin = {
@@ -20,28 +26,19 @@ export type LogPlugin = {
20
26
  options?: any[];
21
27
  };
22
28
 
23
- export type LogType = 'file' | 'stdout';
24
- export type LogFormat = 'json' | 'pretty-timestamped' | 'pretty';
29
+ type LoggerOptions = { level?: string; path?: string; colors?: boolean; sync?: boolean };
25
30
 
26
31
  export function createLogger(
27
- options = { level: 'http' },
28
- destination = pino.destination(1),
29
- format: LogFormat = DEFAULT_LOG_FORMAT,
30
- prettyPrintOptions = {
31
- // we hide warning since the prettifier should not be used in production
32
- // https://getpino.io/#/docs/pretty?id=prettifier-api
33
- suppressFlushSyncWarning: true,
34
- }
32
+ options: LoggerOptions = { level: 'http' },
33
+ // eslint-disable-next-line no-undef
34
+ destination: NodeJS.WritableStream = pino.destination(1),
35
+ format: LoggerFormat = DEFAULT_LOG_FORMAT
35
36
  ) {
36
- if (_.isNil(format)) {
37
- format = DEFAULT_LOG_FORMAT;
38
- }
39
-
37
+ debug('setup logger');
40
38
  let pinoConfig = {
41
39
  customLevels: {
42
40
  http: 25,
43
41
  },
44
- ...options,
45
42
  level: options.level,
46
43
  serializers: {
47
44
  err: pino.stdSerializers.err,
@@ -52,23 +49,32 @@ export function createLogger(
52
49
 
53
50
  debug('has prettifier? %o', !isProd());
54
51
  // pretty logs are not allowed in production for performance reasons
55
- if ((format === DEFAULT_LOG_FORMAT || format !== 'json') && isProd() === false) {
52
+ if (['pretty-timestamped', 'pretty'].includes(format) && isProd() === false) {
56
53
  pinoConfig = Object.assign({}, pinoConfig, {
57
- prettifier,
58
- // more info
59
- // https://github.com/pinojs/pino-pretty/issues/37
60
- prettyPrint: {
61
- levelFirst: true,
62
- prettyStamp: format === 'pretty-timestamped',
63
- ...prettyPrintOptions,
54
+ transport: {
55
+ target: '@verdaccio/logger-prettify',
56
+ options: {
57
+ // string or 1 (file descriptor for process.stdout)
58
+ destination: options.path || 1,
59
+ colors: hasColors(options.colors),
60
+ prettyStamp: format === 'pretty-timestamped',
61
+ },
64
62
  },
65
63
  });
66
64
  } else {
67
- pinoConfig = Object.assign({}, pinoConfig, {
65
+ pinoConfig = {
66
+ ...pinoConfig,
68
67
  // more info
69
68
  // https://github.com/pinojs/pino/blob/v7.1.0/docs/api.md#hooks-object
69
+ // TODO: improve typings here
70
+ // @ts-ignore
70
71
  hooks: {
71
- logMethod(inputArgs, method) {
72
+ logMethod(
73
+ inputArgs: [any, any, ...any[]],
74
+ method: {
75
+ apply: (arg0: { logMethod: (inputArgs: any, method: any) => any }, arg1: any[]) => any;
76
+ }
77
+ ) {
72
78
  const [templateObject, message, ...otherArgs] = inputArgs;
73
79
  const templateVars =
74
80
  !!templateObject && typeof templateObject === 'object'
@@ -79,10 +85,12 @@ export function createLogger(
79
85
  return method.apply(this, [templateObject, hydratedMessage, ...otherArgs]);
80
86
  },
81
87
  },
82
- });
88
+ };
83
89
  }
84
90
  const logger = pino(pinoConfig, destination);
85
91
 
92
+ /* eslint-disable */
93
+ /* istanbul ignore next */
86
94
  if (process.env.DEBUG) {
87
95
  logger.on('level-change', (lvl, val, prevLvl, prevVal) => {
88
96
  debug('%s (%d) was changed to %s (%d)', lvl, val, prevLvl, prevVal);
@@ -92,43 +100,21 @@ export function createLogger(
92
100
  return logger;
93
101
  }
94
102
 
95
- export function getLogger() {
96
- if (_.isNil(logger)) {
97
- // FIXME: not sure about display here a warning
98
- warningUtils.emit(warningUtils.Codes.VERWAR002);
99
- return;
100
- }
101
-
102
- return logger;
103
- }
104
-
105
103
  const DEFAULT_LOGGER_CONF: LoggerConfigItem = {
106
104
  type: 'stdout',
107
105
  format: 'pretty',
108
106
  level: 'http',
109
107
  };
110
108
 
111
- export type LoggerConfigItem = {
112
- type?: LogType;
113
- plugin?: LogPlugin;
114
- format?: LogFormat;
115
- path?: string;
116
- level?: string;
117
- };
109
+ export type LoggerConfig = LoggerConfigItem;
118
110
 
119
- export type LoggerConfig = LoggerConfigItem[];
120
-
121
- export function setup(options: LoggerConfig | LoggerConfigItem = DEFAULT_LOGGER_CONF) {
122
- debug('setup logger');
123
- const isLegacyConf = Array.isArray(options);
124
- if (isLegacyConf) {
125
- warningUtils.emit(warningUtils.Codes.VERDEP002);
126
- }
127
-
128
- // verdaccio 5 does not allow multiple logger configuration
129
- // backward compatible, pick only the first option
130
- // next major will thrown an error
131
- let loggerConfig = isLegacyConf ? options[0] : options;
111
+ export function prepareSetup(options: LoggerConfigItem = DEFAULT_LOGGER_CONF) {
112
+ let logger: Logger<{
113
+ customLevels: { http: number };
114
+ level: string | undefined;
115
+ serializers: { err: any; req: any; res: any };
116
+ }>;
117
+ let loggerConfig = options;
132
118
  if (!loggerConfig?.level) {
133
119
  loggerConfig = Object.assign(
134
120
  {},
@@ -142,36 +128,35 @@ export function setup(options: LoggerConfig | LoggerConfigItem = DEFAULT_LOGGER_
142
128
  if (loggerConfig.type === 'file') {
143
129
  debug('logging file enabled');
144
130
  const destination = pino.destination(loggerConfig.path);
131
+ /* eslint-disable */
132
+ /* istanbul ignore next */
145
133
  process.on('SIGUSR2', () => destination.reopen());
146
- logger = createLogger(pinoConfig, destination, loggerConfig.format);
147
- } else if (loggerConfig.type === 'rotating-file') {
148
- warningUtils.emit(warningUtils.Codes.VERWAR003);
149
- debug('logging stdout enabled');
150
- logger = createLogger(pinoConfig, pino.destination(1), loggerConfig.format);
134
+ // @ts-ignore
135
+ logger = createLogger(
136
+ { level: loggerConfig.level, path: loggerConfig.path, colors: loggerConfig.colors },
137
+ destination,
138
+ loggerConfig.format
139
+ );
140
+ return logger;
151
141
  } else {
152
142
  debug('logging stdout enabled');
153
- logger = createLogger(pinoConfig, pino.destination(1), loggerConfig.format);
143
+ // @ts-ignore
144
+ logger = createLogger(
145
+ { level: loggerConfig.level, colors: loggerConfig.colors },
146
+ pino.destination(1),
147
+ loggerConfig.format
148
+ );
149
+ return logger;
154
150
  }
151
+ }
155
152
 
156
- if (isProd()) {
157
- // why only on prod? https://github.com/pinojs/pino/issues/920#issuecomment-710807667
158
- const finalHandler = pino.final(logger, (err, finalLogger, event) => {
159
- finalLogger.info(`${event} caught`);
160
- if (err) {
161
- finalLogger.error(err, 'error caused exit');
162
- }
163
- process.exit(err ? 1 : 0);
164
- });
153
+ export let logger: Logger;
165
154
 
166
- process.on('uncaughtException', (err) => finalHandler(err, 'uncaughtException'));
167
- process.on('unhandledRejection', (err) => finalHandler(err as Error, 'unhandledRejection'));
168
- process.on('beforeExit', () => finalHandler(null, 'beforeExit'));
169
- process.on('exit', () => finalHandler(null, 'exit'));
170
- process.on('uncaughtException', (err) => finalHandler(err, 'uncaughtException'));
171
- process.on('SIGINT', () => finalHandler(null, 'SIGINT'));
172
- process.on('SIGQUIT', () => finalHandler(null, 'SIGQUIT'));
173
- process.on('SIGTERM', () => finalHandler(null, 'SIGTERM'));
155
+ export function setup(options: LoggerConfigItem) {
156
+ if (typeof logger !== 'undefined') {
157
+ return logger;
174
158
  }
175
159
 
160
+ logger = prepareSetup(options);
176
161
  return logger;
177
162
  }
@@ -0,0 +1,20 @@
1
+ import { Writable } from 'stream';
2
+
3
+ import { createLogger } from '../src';
4
+
5
+ describe('logger test', () => {
6
+ describe('json format', () => {
7
+ test('should write json to a stream', () => {
8
+ const stream = new Writable({
9
+ write(chunk, encoding, callback) {
10
+ expect(JSON.parse(chunk.toString())).toEqual(
11
+ expect.objectContaining({ level: 30, msg: 'test' })
12
+ );
13
+ callback();
14
+ },
15
+ });
16
+ const logger = createLogger({ level: 'http' }, stream, 'json');
17
+ logger.info('test');
18
+ });
19
+ });
20
+ });
@@ -1,53 +1,115 @@
1
- import { warningUtils } from '@verdaccio/core';
2
-
3
- import { logger, setup } from '../src';
4
-
5
- const mockWarningUtils = jest.fn();
6
-
7
- jest.mock('@verdaccio/core', () => {
8
- const original = jest.requireActual('@verdaccio/core');
9
- return {
10
- warningUtils: {
11
- ...original.warningUtils,
12
- emit: (...args) => {
13
- mockWarningUtils(...args);
14
- },
15
- },
16
- };
17
- });
1
+ import { readFile } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import { setTimeout } from 'timers/promises';
18
4
 
19
- describe('logger', () => {
20
- beforeEach(() => {
21
- jest.clearAllMocks();
22
- });
5
+ import { fileUtils } from '@verdaccio/core';
23
6
 
24
- test.skip('should write message logger', () => {
25
- jest.spyOn(process.stdout, 'write');
26
- setup([
27
- {
28
- level: 'info',
29
- },
30
- ]);
7
+ import { prepareSetup } from '../src';
8
+
9
+ async function readLogFile(path: string) {
10
+ await setTimeout(1000, 'resolved');
11
+ return readFile(path, 'utf8');
12
+ }
31
13
 
32
- logger.info({ packageName: 'test' }, `publishing or updating a new version for @{packageName}`);
33
- // FIXME: check expect
34
- // expect(spyOn).toHaveBeenCalledTimes(2);
14
+ async function createLogFile() {
15
+ const folder = await fileUtils.createTempFolder('logger-1');
16
+ const file = join(folder, 'logger.log');
17
+ return file;
18
+ }
19
+
20
+ const defaultOptions = {
21
+ format: 'json',
22
+ level: 'http',
23
+ colors: false,
24
+ };
25
+
26
+ describe('logger test', () => {
27
+ describe('basic', () => {
28
+ test('should include default level', async () => {
29
+ const file = await createLogFile();
30
+ const logger = prepareSetup({ type: 'file', path: file, colors: false });
31
+ logger.info({ packageName: 'test' }, `testing @{packageName}`);
32
+ // Note: this should not be logged
33
+ logger.debug(`this should not be logged`);
34
+ // Note: this should not be logged
35
+ logger.trace(`this should not be logged`);
36
+ logger.error(`this should logged`);
37
+ const content = await readLogFile(file);
38
+ expect(content).toBe('info --- testing test \nerror--- this should logged \n');
39
+ });
40
+
41
+ test('should include all logging level', async () => {
42
+ const file = await createLogFile();
43
+ const logger = prepareSetup({ type: 'file', level: 'trace', path: file, colors: false });
44
+ logger.info({ packageName: 'test' }, `testing @{packageName}`);
45
+ logger.debug(`this should not be logged`);
46
+ logger.trace(`this should not be logged`);
47
+ logger.error(`this should logged`);
48
+ const content = await readLogFile(file);
49
+ expect(content).toBe(
50
+ 'info --- testing test \ndebug--- this should not be logged \ntrace--- this should not be logged \nerror--- this should logged \n'
51
+ );
52
+ });
35
53
  });
36
54
 
37
- test('throw deprecation warning if multiple loggers configured', () => {
38
- setup([
39
- {
55
+ describe('json format', () => {
56
+ test('should log into a file with json format', async () => {
57
+ const file = await createLogFile();
58
+ const logger = prepareSetup({
59
+ ...defaultOptions,
60
+ format: 'json',
61
+ type: 'file',
62
+ path: file,
40
63
  level: 'info',
41
- },
42
- {
43
- level: 'http',
44
- },
45
- ]);
46
- expect(mockWarningUtils).toHaveBeenCalledWith(warningUtils.Codes.VERDEP002);
64
+ });
65
+ logger.info(
66
+ { packageName: 'test' },
67
+ `publishing or updating a new version for @{packageName}`
68
+ );
69
+ const content = await readLogFile(file);
70
+ expect(JSON.parse(content)).toEqual(
71
+ expect.objectContaining({
72
+ level: 30,
73
+ msg: 'publishing or updating a new version for test',
74
+ })
75
+ );
76
+ });
47
77
  });
48
78
 
49
- test('regression: do not throw deprecation warning if no logger config is provided', () => {
50
- setup();
51
- expect(mockWarningUtils).not.toHaveBeenCalled();
79
+ describe('pretty format', () => {
80
+ test('should log into a file with pretty', async () => {
81
+ const file = await createLogFile();
82
+ const logger = prepareSetup({
83
+ format: 'pretty',
84
+ type: 'file',
85
+ path: file,
86
+ level: 'trace',
87
+ colors: false,
88
+ });
89
+ logger.info(
90
+ { packageName: 'test' },
91
+ `publishing or updating a new version for @{packageName}`
92
+ );
93
+ const content = await readLogFile(file);
94
+ expect(content).toEqual('info --- publishing or updating a new version for test \n');
95
+ });
96
+
97
+ test('should log into a file with pretty-timestamped', async () => {
98
+ const file = await createLogFile();
99
+ const logger = prepareSetup({
100
+ format: 'pretty-timestamped',
101
+ type: 'file',
102
+ path: file,
103
+ level: 'trace',
104
+ colors: false,
105
+ });
106
+ logger.info(
107
+ { packageName: 'test' },
108
+ `publishing or updating a new version for @{packageName}`
109
+ );
110
+ const content = await readLogFile(file);
111
+ // TODO: we might want mock time for testing
112
+ expect(content).toMatch('info --- publishing or updating a new version for test \n');
113
+ });
52
114
  });
53
115
  });