From b43c953e8afbebb44d05227e630046dbe6ffd9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Fri, 27 Apr 2018 15:24:27 +0200 Subject: [PATCH 01/22] WIP --- config/test.json | 8 + index.js | 55 +- lib/get-loc.js | 20 + lib/logger.js | 137 ++-- lib/prom-transport.js | 28 + lib/transports.js | 5 + logs/.gitignore | 0 logs/test.log | 3 + package.json | 6 +- test/feature/logging-test.js | 308 ++++----- test/helpers/test-transport.js | 17 + test/log-messages-test.js | 64 ++ test/logger-test.js | 25 + yarn-error.log | 1140 +++++++++++++++++++++++++++++++ yarn.lock | 1155 ++++++++++++++++++++++++++++++++ 15 files changed, 2740 insertions(+), 231 deletions(-) create mode 100644 config/test.json create mode 100644 lib/get-loc.js create mode 100644 lib/prom-transport.js create mode 100644 lib/transports.js create mode 100644 logs/.gitignore create mode 100644 logs/test.log create mode 100644 test/helpers/test-transport.js create mode 100644 test/log-messages-test.js create mode 100644 test/logger-test.js create mode 100644 yarn-error.log create mode 100644 yarn.lock diff --git a/config/test.json b/config/test.json new file mode 100644 index 0000000..def1cff --- /dev/null +++ b/config/test.json @@ -0,0 +1,8 @@ +{ + "logging": { + "log": "file", + "logLevel": "debug", + "logJson": true, + "truncateLog": true + } +} diff --git a/index.js b/index.js index ef54eba..88c66a3 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,56 @@ "use strict"; -const logger = require("./lib/logger"); +const appConfig = require("exp-config"); +const winston = require("winston"); +const path = require("path"); +require("winston-syslog").Syslog; // eslint-disable-line no-unused-expressions -module.exports = logger; +const PromTransport = require("./lib/prom-transport"); +const callingAppName = require(`${process.cwd()}/package.json`).name; +const config = appConfig.logging; + +const transports = [new PromTransport()]; + +if (appConfig.envName === "test") { + transports.push(require("./test/helpers/test-transport")); +} + +if (config.log === "file") { + const fileName = path.join(process.cwd(), "logs", `${appConfig.envName}.log`); + const options = config.truncateLog ? { flags: "w" } : { flags: "a" }; + transports.push(new winston.transports.File({ + filename: fileName, + json: config.logJson, + options: options, + stringify, + prettyPrint: true + })); +} + +if (config.log === "stdout") { + transports.push(new winston.transports.Console({ + colorize: false, + timestamp: true, + json: config.logJson, + stringify + })); +} + +if (config.sysLogOpts) { + transports.push(new winston.transports.Syslog(Object.assign({ + localhost: process.env.HOSTNAME, + app_name: callingAppName, // eslint-disable-line camelcase + eol: "\n", + json: config.logJson, + stringify + }, config.sysLogOpts))); +} + +function stringify(obj) { + return config.logJson ? JSON.stringify(obj) : obj.replace(/\n/g, " "); +} + +module.exports = winston.createLogger({ + level: config.logLevel || "info", + transports: transports +}); diff --git a/lib/get-loc.js b/lib/get-loc.js new file mode 100644 index 0000000..63c6f5e --- /dev/null +++ b/lib/get-loc.js @@ -0,0 +1,20 @@ +"use strict"; +const path = require("path"); + +function getLoc() { + const originalPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = (_, stack) => stack; + const stack = new Error().stack[3]; + Error.prepareStackTrace = originalPrepareStackTrace; + + let calleePath; + if (process.cwd()) { + calleePath = path.relative(process.cwd(), stack.getFileName()); + } else { + calleePath = stack.getFileName(); + } + + return `${calleePath}:${stack.getLineNumber()}`; +} + +module.exports = getLoc; diff --git a/lib/logger.js b/lib/logger.js index 138a5bb..2d03c54 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -2,33 +2,31 @@ const path = require("path"); const winston = require("winston"); +const util = require("util"); /* eslint-disable no-unused-expressions */ require("winston-syslog").Syslog; const prometheusClient = require("prom-client"); -const logLevels = { - emerg: 0, - alert: 1, - crit: 2, - error: 3, - warning: 4, - notice: 5, - info: 6, - debug: 7 -}; +const logLevels = [ + {short: "emerg", num: 0, fnName: "emergency"}, + {short: "alert", num: 1, fnName: "alert"}, + {short: "crit", num: 2, fnName: "critical"}, + {short: "error", num: 3, fnName: "error"}, + {short: "warning", num: 4, fnName: "warning"}, + {short: "notice", num: 5, fnName: "notice"}, + {short: "info", num: 6, fnName: "info"}, + {short: "debug", num: 7, fnName: "debug"} +]; -const invertedLevels = Object.assign({}, ...Object.entries(logLevels).map(([a, b]) => ({ [b]: a }))); +const callingAppName = require(`${process.cwd()}/package.json`).name; function init(config) { if (!config) { throw new Error("Error initializing logger, configuration object missing"); } - const callingAppName = require(`${process.cwd()}/package.json`).name; const callingAppMetricName = !callingAppName ? "undefined" : callingAppName.replace(/-/g, ""); - const logCounterName = `${callingAppMetricName}_logged_total`; - let logCounter = prometheusClient.register.getSingleMetric(logCounterName); if (!logCounter) { @@ -42,16 +40,22 @@ function init(config) { const logLevel = config.logLevel || "info"; const logJson = (config.logJson === undefined) ? true : config.logJson; - const root = path.resolve(__dirname.split("node_modules")[0]); + const root = process.cwd(); const fileName = path.join(root, "logs", `${process.env.NODE_ENV || "development"}.log`); + const options = config.truncateLog ? { flags: "w" } : { flags: "a" }; + + const stringify = stringifyFn.bind(stringifyFn, logJson); const transports = []; if (config.log === "file") { - transports.push(new winston.transports.File({ + const transport = new winston.transports.File({ filename: fileName, json: logJson, - stringify: (obj) => logJson ? JSON.stringify(obj) : obj.split("\n").join(" "), - })); + options: options, + stringify: stringify, + }); + + transports.push(transport); } if (config.log === "stdout") { @@ -59,7 +63,7 @@ function init(config) { colorize: false, timestamp: true, json: logJson, - stringify: (obj) => logJson ? JSON.stringify(obj) : obj.split("\n").join(" "), + stringify: stringify, })); } @@ -69,7 +73,7 @@ function init(config) { app_name: callingAppName, // eslint-disable-line camelcase eol: "\n", json: logJson, - stringify: (obj) => logJson ? JSON.stringify(obj) : obj.split("\n").join(" ") + stringify: stringify }, config.sysLogOpts))); } @@ -79,65 +83,52 @@ function init(config) { transports: transports }); - function prepLogObject(level, logObject) { - if (!logObject) { - logObject = {}; - } else { - logObject = JSON.parse(JSON.stringify(logObject)); - } + function api(logObject = {}) { + const logs = {}; + logLevels.forEach((level) => { + logs[level.fnName] = (...args) => { + const label = util.format(...args); + logger[level.num](label, prepLogObject(level.num, logObject)); + logCounter.inc({ level: level.fnName }); + }; + }); - const logData = {metaData: logObject}; + logs.winstone = logger; + return logs; + } - if (level === logLevels.debug) { - logData.location = getLoc(); - } + return Object.assign(api, api()); +} + +function prepLogObject(level, logObject, metaData = {}) { + if (!logObject) { + logObject = metaData; + } else { + logObject = JSON.parse(JSON.stringify(logObject)); + } - logData.logLevel = invertedLevels[level]; + const logData = {metaData: logObject}; + const correlationId = (typeof metaData === "string") ? metaData : null; - return logData; + if (metaData) { + if (logData.metaData && logData.metaData.meta) { + logData.metaData.meta.correlationId = correlationId; + } else { + logData.metaData = { meta: {correlationId}}; + } } - return { - emergency: (label, logObject) => { - logger.emerg(label, prepLogObject(logLevels.emerg, logObject)); - logCounter.inc({ level: "emergency" }); - }, - - alert: (label, logObject) => { - logger.alert(label, prepLogObject(logLevels.alert, logObject)); - logCounter.inc({ level: "alert" }); - }, - - critical: (label, logObject) => { - logger.crit(label, prepLogObject(logLevels.crit, logObject)); - logCounter.inc({ level: "crit" }); - }, - - error: (label, logObject) => { - logger.error(label, prepLogObject(logLevels.error, logObject)); - logCounter.inc({ level: "error" }); - }, - - warning: (label, logObject) => { - logger.warning(label, prepLogObject(logLevels.warning, logObject)); - logCounter.inc({ level: "warning" }); - }, - - notice: (label, logObject) => { - logger.notice(label, prepLogObject(logLevels.notice, logObject)); - logCounter.inc({ level: "notice" }); - }, - - info: (label, logObject) => { - logger.info(label, prepLogObject(logLevels.info, logObject)); - logCounter.inc({ level: "info" }); - }, - - debug: (label, logObject) => { - logger.debug(label, prepLogObject(logLevels.debug, logObject)); - logCounter.inc({ level: "debug" }); - }, - }; + if (level.fnName === "debug" || level.fnName === "error") { + logData.location = getLoc(); + } + + logData.logLevel = String(level.num); + + return logData; +} + +function stringifyFn(logJson, obj) { + return logJson ? JSON.stringify(obj) : obj.replace(/\n/g, " "); } function getLoc() { diff --git a/lib/prom-transport.js b/lib/prom-transport.js new file mode 100644 index 0000000..42cc7f5 --- /dev/null +++ b/lib/prom-transport.js @@ -0,0 +1,28 @@ +"use strict"; + +const Transport = require("winston-transport"); +const prometheusClient = require("prom-client"); +const callingAppName = require(`${process.cwd()}/package.json`).name; + +class PromTransport extends Transport { + constructor(opts) { + super(opts); + this.name = "prom-transport"; + const callingAppMetricName = callingAppName && callingAppName.replace(/-/g, ""); + const logCounterName = `${callingAppMetricName}_logged_total`; + this.logCounter = prometheusClient.register.getSingleMetric(logCounterName); + + if (!this.logCounter) { + this.logCounter = new prometheusClient.Counter({ + name: logCounterName, + help: "Counts number of logs with loglevel as label", + labelNames: ["level"] + }); + } + } + log(level) { + this.logCounter.inc({level}); + } +} + +module.exports = PromTransport; diff --git a/lib/transports.js b/lib/transports.js new file mode 100644 index 0000000..16c19a1 --- /dev/null +++ b/lib/transports.js @@ -0,0 +1,5 @@ +"use strict"; + + + +module.exports = ConsoleTransport; diff --git a/logs/.gitignore b/logs/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/logs/test.log b/logs/test.log new file mode 100644 index 0000000..dc8e8ef --- /dev/null +++ b/logs/test.log @@ -0,0 +1,3 @@ +info: foobar +info: some message {"some":"info"} +info: one {"0":"t","1":"w","2":"o"} diff --git a/package.json b/package.json index 2f5b075..5772124 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,11 @@ "license": "MIT", "main": "index.js", "dependencies": { + "exp-config": "^2.0.1", "prom-client": "^10.2.2", - "winston": "^2.4.0", - "winston-syslog": "^1.0.0" + "winston": "^3.0.0-rc5", + "winston-syslog": "^1.0.0", + "winston-transport": "^3.2.1" }, "devDependencies": { "chai": "^3.5.0", diff --git a/test/feature/logging-test.js b/test/feature/logging-test.js index 2ace3fb..18686ac 100644 --- a/test/feature/logging-test.js +++ b/test/feature/logging-test.js @@ -1,154 +1,154 @@ -"use strict"; - -const createLogger = require("../../lib/logger"); -const intercept = require("intercept-stdout"); -const prometheusClient = require("prom-client"); - -Feature("Logging", () => { - Scenario("Logging with JSON format", () => { - let unhook; - let stdoutContents = ""; - - const config = { - "log": "stdout", - "logLevel": "debug", - "logJson": true - }; - const message = "Message"; - const data = { - "meta": { - "createdAt": "2017-09-24-00:00T00:00:00.000Z", - "updatedAt": "2017-09-24-00:00T00:00:00.000Z", - "correlationId": "sample-correlation-id" - } - }; - - When("initializing the logger and doing some JSON logging", () => { - const logger = createLogger(config); - - unhook = intercept((txt) => { - stdoutContents += txt; - }); - - logger.debug(message, data); - - unhook(); - }); - - Then("log output should be JSON", () => { - const logContent = JSON.parse(stdoutContents.trim()); - logContent.logLevel.should.equal("debug"); - logContent.location.should.be.ok; // eslint-disable-line no-unused-expressions - logContent.metaData.should.deep.equal(data); - logContent.message.should.equal(message); - }); - }); - - Scenario("Logging with string format", () => { - let unhook; - let stdoutContents = ""; - - const config = { - "log": "stdout", - "logLevel": "debug", - "logJson": false - }; - const message = "Message"; - const data = { - "meta": { - "createdAt": "2017-09-24-00:00T00:00:00.000Z", - "updatedAt": "2017-09-24-00:00T00:00:00.000Z", - "correlationId": "sample-correlation-id" - } - }; - - When("initializing the logger and doing some string logging", () => { - const logger = createLogger(config); - - unhook = intercept((txt) => { - stdoutContents += txt; - }); - - logger.debug(message, data); - - unhook(); - }); - - Then("log output should be string", (done) => { - stdoutContents.should.be.a("string"); - - try { - JSON.parse(stdoutContents); - done("No error thrown"); - } catch (err) { - done(); - } - }); - }); - - Scenario("Logging should inc metric", () => { - const config = { - "log": "stdout", - "logLevel": "debug", - "logJson": false, - "metricPrefix": "test" - }; - const message = "Message"; - - before(() => { - prometheusClient.register.resetMetrics(); - }); - - When("initializing the logger and doing some string logging", () => { - const logger = createLogger(config); - - logger.emergency(message); - - logger.alert(message); - logger.alert(message); - - logger.critical(message); - logger.critical(message); - logger.critical(message); - - logger.error(message); - logger.error(message); - logger.error(message); - logger.error(message); - - logger.warning(message); - logger.warning(message); - logger.warning(message); - logger.warning(message); - logger.warning(message); - - logger.notice(message); - - logger.info(message); - - logger.debug(message); - }); - - Then("the logCounter metric should be incremented", () => { - - const counterMetric = prometheusClient.register.getSingleMetric("lulogger_logged_total"); - const emergencyCount = counterMetric.hashMap["level:emergency"].value; - const alertCount = counterMetric.hashMap["level:alert"].value; - const criticalCount = counterMetric.hashMap["level:crit"].value; - const errorCount = counterMetric.hashMap["level:error"].value; - const warningCount = counterMetric.hashMap["level:warning"].value; - const noticeCount = counterMetric.hashMap["level:notice"].value; - const infoCount = counterMetric.hashMap["level:info"].value; - const debugCount = counterMetric.hashMap["level:debug"].value; - - emergencyCount.should.eql(1); - alertCount.should.eql(2); - criticalCount.should.eql(3); - errorCount.should.eql(4); - warningCount.should.eql(5); - noticeCount.should.eql(1); - infoCount.should.eql(1); - debugCount.should.eql(1); - }); - }); -}); +// "use strict"; + +// const createLogger = require("../../lib/logger"); +// const intercept = require("intercept-stdout"); +// const prometheusClient = require("prom-client"); + +// Feature("Logging", () => { +// Scenario("Logging with JSON format", () => { +// let unhook; +// let stdoutContents = ""; + +// const config = { +// log: "stdout", +// logLevel: "debug", +// logJson: true +// }; +// const message = "Message"; +// const data = { +// "meta": { +// "createdAt": "2017-09-24-00:00T00:00:00.000Z", +// "updatedAt": "2017-09-24-00:00T00:00:00.000Z", +// "correlationId": "sample-correlation-id" +// } +// }; + +// When("initializing the logger and doing some JSON logging", () => { +// const logger = createLogger(config); + +// unhook = intercept((txt) => { +// stdoutContents += txt; +// }); + +// logger.debug(message, data); + +// unhook(); +// }); + +// Then("log output should be JSON", () => { +// const logContent = JSON.parse(stdoutContents.trim()); +// logContent.logLevel.should.equal("debug"); +// logContent.location.should.be.ok; // eslint-disable-line no-unused-expressions +// logContent.metaData.should.deep.equal(data); +// logContent.message.should.equal(message); +// }); +// }); + +// Scenario("Logging with string format", () => { +// let unhook; +// let stdoutContents = ""; + +// const config = { +// "log": "stdout", +// "logLevel": "debug", +// "logJson": false +// }; +// const message = "Message"; +// const data = { +// "meta": { +// "createdAt": "2017-09-24-00:00T00:00:00.000Z", +// "updatedAt": "2017-09-24-00:00T00:00:00.000Z", +// "correlationId": "sample-correlation-id" +// } +// }; + +// When("initializing the logger and doing some string logging", () => { +// const logger = createLogger(config); + +// unhook = intercept((txt) => { +// stdoutContents += txt; +// }); + +// logger.debug(message, data); + +// unhook(); +// }); + +// Then("log output should be string", (done) => { +// stdoutContents.should.be.a("string"); + +// try { +// JSON.parse(stdoutContents); +// done("No error thrown"); +// } catch (err) { +// done(); +// } +// }); +// }); + +// Scenario("Logging should inc metric", () => { +// const config = { +// "log": "stdout", +// "logLevel": "debug", +// "logJson": false, +// "metricPrefix": "test" +// }; +// const message = "Message"; + +// before(() => { +// prometheusClient.register.resetMetrics(); +// }); + +// When("initializing the logger and doing some string logging", () => { +// const logger = createLogger(config); + +// logger.emergency(message); + +// logger.alert(message); +// logger.alert(message); + +// logger.critical(message); +// logger.critical(message); +// logger.critical(message); + +// logger.error(message); +// logger.error(message); +// logger.error(message); +// logger.error(message); + +// logger.warning(message); +// logger.warning(message); +// logger.warning(message); +// logger.warning(message); +// logger.warning(message); + +// logger.notice(message); + +// logger.info(message); + +// logger.debug(message); +// }); + +// Then("the logCounter metric should be incremented", () => { + +// const counterMetric = prometheusClient.register.getSingleMetric("lulogger_logged_total"); +// const emergencyCount = counterMetric.hashMap["level:emergency"].value; +// const alertCount = counterMetric.hashMap["level:alert"].value; +// const criticalCount = counterMetric.hashMap["level:crit"].value; +// const errorCount = counterMetric.hashMap["level:error"].value; +// const warningCount = counterMetric.hashMap["level:warning"].value; +// const noticeCount = counterMetric.hashMap["level:notice"].value; +// const infoCount = counterMetric.hashMap["level:info"].value; +// const debugCount = counterMetric.hashMap["level:debug"].value; + +// emergencyCount.should.eql(1); +// alertCount.should.eql(2); +// criticalCount.should.eql(3); +// errorCount.should.eql(4); +// warningCount.should.eql(5); +// noticeCount.should.eql(1); +// infoCount.should.eql(1); +// debugCount.should.eql(1); +// }); +// }); +// }); diff --git a/test/helpers/test-transport.js b/test/helpers/test-transport.js new file mode 100644 index 0000000..9445fc4 --- /dev/null +++ b/test/helpers/test-transport.js @@ -0,0 +1,17 @@ +"use strict"; + +const Transport = require("winston-transport"); + + +class CustomTransport extends Transport { + constructor(opts) { + super(opts); + this.name = "test-transport"; + this.logs = []; + } + log(level, message, meta) { + this.logs.push({level, message, meta}); + } +} + +module.exports = new CustomTransport(); diff --git a/test/log-messages-test.js b/test/log-messages-test.js new file mode 100644 index 0000000..e93c00b --- /dev/null +++ b/test/log-messages-test.js @@ -0,0 +1,64 @@ +// "use strict"; + +// const path = require("path"); +// const fs = require("fs"); +// const createLogger = require("../lib/logger"); +// const fileName = path.join(__dirname, "..", "logs", "test.log"); +// const logger = createLogger({ +// log: "file", +// logLevel: "debug", +// logJson: true, +// truncateLog: true +// }); + +// describe("logging a message", () => { +// const data = { +// "meta": { +// "createdAt": "2017-09-24-00:00T00:00:00.000Z", +// "updatedAt": "2017-09-24-00:00T00:00:00.000Z", +// "correlationId": "sample-correlation-id" +// } +// }; + +// const log = []; + +// before(() => { +// logger.winstone.on("logged", (args) => { +// console.log("logged", args); +// }); + +// logger(data).debug("some message"); +// logger.info("some message", data); +// logger.info("some message"); +// logger("sample-correlation-id").info("some message"); +// log.push(...readLog()); +// }); + +// it("should log a message with metaData", () => { +// log[log.length - 4].message.should.eql("some message"); +// log[log.length - 4].metaData.shoud.eql(data); +// }); + + +// it("should log a message", () => { +// log[log.length - 3].message.should.eql("some message"); +// log[log.length - 3].metaData.shoud.eql(data); +// }); + +// it("should not log meta if not given", () => { +// log[log.length - 2].message.should.eql("some message"); +// log[log.length - 2].metaData.should.eql({}); +// }); + +// it("should log correlationId if given as first argument", () => { +// log[log.length - 1].message.should.eql("some message"); +// log[log.length - 1].metaData.meta.correlationId.should.eql("sample-correlation-id"); +// }); +// }); + +// function readLog() { +// return fs.readFileSync(fileName, {"encoding": "utf-8"}) +// .trim() +// .split("\n") +// .map(JSON.parse); +// } diff --git a/test/logger-test.js b/test/logger-test.js new file mode 100644 index 0000000..6043fd8 --- /dev/null +++ b/test/logger-test.js @@ -0,0 +1,25 @@ +"use strict"; + +const logger = require("../"); +const transport = require("./helpers/test-transport"); + +describe("logger", () => { + it("should log", () => { + logger.info("foobar"); + const log = transport.logs.shift(); + log.should.eql({level: "info", message: "foobar", meta: {}}); + }); + + it("should log objects", () => { + logger.info("some message", {"some": "info"}); + const log = transport.logs.shift(); + log.should.eql({level: "info", message: "some message", meta: { "some": "info"}}); + }); + + it("should log objects anything", () => { + logger.info("one", "two", "threee", "four"); + const log = transport.logs.shift(); + log.should.eql({level: "info", message: "some message", meta: { "some": "info"}}); + }); + +}); diff --git a/yarn-error.log b/yarn-error.log new file mode 100644 index 0000000..3ab98d9 --- /dev/null +++ b/yarn-error.log @@ -0,0 +1,1140 @@ +Arguments: + /Users/jens.carlen/.nvm/versions/node/v8.9.4/bin/node /Users/jens.carlen/.nvm/versions/node/v8.9.4/bin/yarn add winstone + +PATH: + ./node_modules/.bin:/Users/jens.carlen/.nvm/versions/node/v8.9.4/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + +Yarn version: + 1.5.1 + +Node version: + 8.9.4 + +Platform: + darwin x64 + +npm manifest: + { + "name": "lu-logger", + "description": "Logging for the lu-greenfield project", + "author": "Bonnier News", + "contributors": [ + "Jens-Peter Olsson", + "Ivan Malmberg", + "Markus Ekholm" + ], + "version": "1.5.0", + "scripts": { + "test": "node_modules/.bin/mocha", + "posttest": "eslint --cache ." + }, + "repository": "https://github.com/BonnierNews/lu-logger.git", + "keywords": [ + "logging", + "logger" + ], + "license": "MIT", + "main": "index.js", + "dependencies": { + "exp-config": "^2.0.1", + "prom-client": "^10.2.2", + "winston-syslog": "^1.0.0", + "winston-transport": "^3.2.1" + }, + "devDependencies": { + "chai": "^3.5.0", + "eslint": "^4.18.0", + "intercept-stdout": "^0.1.2", + "mocha": "^3.1.2", + "mocha-cakes-2": "^2.0.1" + } + } + +yarn manifest: + No manifest + +Lockfile: + # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + # yarn lockfile v1 + + + acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + + acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + + acorn@^5.5.0: + version "5.5.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" + + ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + + ajv@^5.2.3, ajv@^5.3.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + + ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + + ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + + ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + + ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + + ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + + argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + dependencies: + sprintf-js "~1.0.2" + + array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + + array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + + arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + + assertion-error@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + + async@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" + + babel-code-frame@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + + balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + + bindings@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.1.1.tgz#951f7ae010302ffc50b265b124032017ed2bf6f3" + + bintrees@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.1.tgz#0e655c9b9c2435eaab68bf4027226d2b55a34524" + + brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + + browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + + buffer-from@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" + + caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + + callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + + chai@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" + dependencies: + assertion-error "^1.0.1" + deep-eql "^0.1.3" + type-detect "^1.0.0" + + chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + + chalk@^2.0.0, chalk@^2.1.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + + chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + + circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + + cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + + cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + + co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + + color-convert@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + dependencies: + color-name "^1.1.1" + + color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + + colors@1.0.x: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + + commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + + concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + + concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + + core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + + cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + + cycle@1.0.x, cycle@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + + debug@2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + + debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + + deep-eql@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + dependencies: + type-detect "0.1.1" + + deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + + del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + + diff@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + + doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + dependencies: + esutils "^2.0.2" + + dotenv@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-2.0.0.tgz#bd759c357aaa70365e01c96b7b0bec08a6e0d949" + + escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + + eslint-scope@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + + eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + + eslint@^4.18.0: + version "4.19.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" + dependencies: + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.4" + esquery "^1.0.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^1.0.1" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "4.0.2" + text-table "~0.2.0" + + espree@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + + esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + + esquery@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + dependencies: + estraverse "^4.0.0" + + esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + dependencies: + estraverse "^4.1.0" + + estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + + esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + + exp-config@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/exp-config/-/exp-config-2.0.1.tgz#68d844b9f98601e652d7390a9df45aee925ca55f" + dependencies: + dotenv "~2.0.0" + lodash.merge "^4.6.0" + + external-editor@^2.0.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + + eyes@0.1.x: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + + fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + + fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + + fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + + figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + + file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + + flat-cache@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + + fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + + functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + + glob@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + + glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + + globals@^11.0.1: + version "11.5.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.5.0.tgz#6bc840de6771173b191f13d3a9c94d441ee92642" + + globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + + glossy@0.x.x: + version "0.1.7" + resolved "https://registry.yarnpkg.com/glossy/-/glossy-0.1.7.tgz#769b5984a96f6066ab9ea758224825ee6c210f0b" + + graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + + "graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + + growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + + has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + + has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + + has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + + he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + + iconv-lite@^0.4.17: + version "0.4.21" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.21.tgz#c47f8733d02171189ebc4a400f3218d348094798" + dependencies: + safer-buffer "^2.1.0" + + ignore@^3.3.3: + version "3.3.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.8.tgz#3f8e9c35d38708a3a7e0e9abb6c73e7ee7707b2b" + + imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + + inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + + inherits@2, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + + inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + + intercept-stdout@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/intercept-stdout/-/intercept-stdout-0.1.2.tgz#126abf1fae6c509a428a98c61a631559042ae9fd" + dependencies: + lodash.toarray "^3.0.0" + + is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + + is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + + is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + dependencies: + is-path-inside "^1.0.0" + + is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + dependencies: + path-is-inside "^1.0.1" + + is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + + is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + + isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + + isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + + isstream@0.1.x: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + + js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + + js-yaml@^3.9.1: + version "3.11.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + + json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + + json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + + json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + + levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + + lodash._arraycopy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" + + lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + + lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + + lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + + lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + + lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + + lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + + lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + + lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + + lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + + lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + + lodash.merge@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" + + lodash.toarray@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-3.0.2.tgz#2b204f0fa4f51c285c6f00c81d1cea5a23041179" + dependencies: + lodash._arraycopy "^3.0.0" + lodash._basevalues "^3.0.0" + lodash.keys "^3.0.0" + + lodash@^4.17.4, lodash@^4.3.0: + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" + + lru-cache@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + + mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + + minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + + minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + + mkdirp@0.5.1, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + + mocha-cakes-2@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mocha-cakes-2/-/mocha-cakes-2-2.1.0.tgz#9f0a7f7ba47d30e226ac643e76bcb8fb23d56590" + + mocha@^3.1.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d" + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.6.8" + diff "3.2.0" + escape-string-regexp "1.0.5" + glob "7.1.1" + growl "1.9.2" + he "1.1.1" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + + ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + + mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + + nan@~2.3.2: + version "2.3.5" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.3.5.tgz#822a0dc266290ce4cd3a12282ca3e7e364668a08" + + natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + + object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + + once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + + onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + + optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + + os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + + path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + + path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + + pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + + pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + + pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + + pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + + prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + + process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + + progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + + prom-client@^10.2.2: + version "10.2.3" + resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-10.2.3.tgz#a51bf21c239c954a6c5be4b1361fdd380218bb41" + dependencies: + tdigest "^0.1.1" + + pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + + readable-stream@^2.2.2: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + + regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + + require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + + resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + + restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + + rimraf@^2.2.8: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + + run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + + rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + + rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + + safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + + safer-buffer@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + + semver@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + + shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + + shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + + signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + + slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + dependencies: + is-fullwidth-code-point "^2.0.0" + + sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + + stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + + string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + + string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + + strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + + strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + + strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + + supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" + + supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + + supports-color@^5.3.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + dependencies: + has-flag "^3.0.0" + + table@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + dependencies: + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" + + tdigest@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/tdigest/-/tdigest-0.1.1.tgz#2e3cb2c39ea449e55d1e6cd91117accca4588021" + dependencies: + bintrees "1.0.1" + + text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + + through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + + tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + + type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + + type-detect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + + type-detect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" + + typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + + unix-dgram@~0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/unix-dgram/-/unix-dgram-0.2.3.tgz#eab7330f1f1041d48f9c179d9f4c5a996cafceb5" + dependencies: + bindings "~1.1.1" + nan "~2.3.2" + + util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + + which@^1.2.9: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + + winston-syslog@^1.0.0: + version "1.2.6" + resolved "https://registry.yarnpkg.com/winston-syslog/-/winston-syslog-1.2.6.tgz#4e7990ed0a9f1932187ddd6ec9e038357980961f" + dependencies: + cycle "~1.0.3" + glossy "0.x.x" + optionalDependencies: + unix-dgram "~0.2.1" + + winston-transport@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-3.2.1.tgz#5b79b294096b1a18bfe502e769491553a2cb1042" + + winston@^2.4.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.2.tgz#3ca01f763116fc48db61053b7544e750431f8db0" + dependencies: + async "~1.0.0" + colors "1.0.x" + cycle "1.0.x" + eyes "0.1.x" + isstream "0.1.x" + stack-trace "0.0.x" + + wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + + wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + + write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + + yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +Trace: + Error: Couldn't find package "winstone" on the "npm" registry. + at new MessageError (/Users/jens.carlen/.nvm/versions/node/v8.9.4/lib/node_modules/yarn/lib/cli.js:186:110) + at NpmResolver. (/Users/jens.carlen/.nvm/versions/node/v8.9.4/lib/node_modules/yarn/lib/cli.js:51625:15) + at Generator.next () + at step (/Users/jens.carlen/.nvm/versions/node/v8.9.4/lib/node_modules/yarn/lib/cli.js:98:30) + at /Users/jens.carlen/.nvm/versions/node/v8.9.4/lib/node_modules/yarn/lib/cli.js:109:13 + at + at process._tickCallback (internal/process/next_tick.js:188:7) diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..e100597 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,1155 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.5.0: + version "5.5.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" + +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + +ajv@^5.2.3, ajv@^5.3.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + dependencies: + sprintf-js "~1.0.2" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +assertion-error@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + +async@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" + dependencies: + lodash "^4.14.0" + +babel-code-frame@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +bindings@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.1.1.tgz#951f7ae010302ffc50b265b124032017ed2bf6f3" + +bintrees@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.1.tgz#0e655c9b9c2435eaab68bf4027226d2b55a34524" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + +buffer-from@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +chai@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" + dependencies: + assertion-error "^1.0.1" + deep-eql "^0.1.3" + type-detect "^1.0.0" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.1.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +color-convert@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd" + +color-convert@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + dependencies: + color-name "^1.1.1" + +color-name@^1.0.0, color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +color-string@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" + dependencies: + color-name "^1.0.0" + +color@0.8.x: + version "0.8.0" + resolved "https://registry.yarnpkg.com/color/-/color-0.8.0.tgz#890c07c3fd4e649537638911cf691e5458b6fca5" + dependencies: + color-convert "^0.5.0" + color-string "^0.3.0" + +colornames@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/colornames/-/colornames-0.0.2.tgz#d811fd6c84f59029499a8ac4436202935b92be31" + +colors@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.1.tgz#f4a3d302976aaf042356ba1ade3b1a2c62d9d794" + +colorspace@1.0.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.0.1.tgz#c99c796ed31128b9876a52e1ee5ee03a4a719749" + dependencies: + color "0.8.x" + text-hex "0.0.x" + +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cycle@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + +debug@2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +deep-eql@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + dependencies: + type-detect "0.1.1" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +diagnostics@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.0.tgz#e1090900b49523e8527be20f081275205f2ae36a" + dependencies: + colorspace "1.0.x" + enabled "1.0.x" + kuler "0.0.x" + +diff@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + dependencies: + esutils "^2.0.2" + +dotenv@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-2.0.0.tgz#bd759c357aaa70365e01c96b7b0bec08a6e0d949" + +enabled@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93" + dependencies: + env-variable "0.0.x" + +env-variable@0.0.x: + version "0.0.4" + resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.4.tgz#0d6280cf507d84242befe35a512b5ae4be77c54e" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +eslint-scope@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + +eslint@^4.18.0: + version "4.19.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" + dependencies: + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.4" + esquery "^1.0.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^1.0.1" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "4.0.2" + text-table "~0.2.0" + +espree@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +esquery@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +exp-config@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/exp-config/-/exp-config-2.0.1.tgz#68d844b9f98601e652d7390a9df45aee925ca55f" + dependencies: + dotenv "~2.0.0" + lodash.merge "^4.6.0" + +external-editor@^2.0.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +fecha@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +flat-cache@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + +glob@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.0.1: + version "11.5.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.5.0.tgz#6bc840de6771173b191f13d3a9c94d441ee92642" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +glossy@0.x.x: + version "0.1.7" + resolved "https://registry.yarnpkg.com/glossy/-/glossy-0.1.7.tgz#769b5984a96f6066ab9ea758224825ee6c210f0b" + +graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + +iconv-lite@^0.4.17: + version "0.4.21" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.21.tgz#c47f8733d02171189ebc4a400f3218d348094798" + dependencies: + safer-buffer "^2.1.0" + +ignore@^3.3.3: + version "3.3.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.8.tgz#3f8e9c35d38708a3a7e0e9abb6c73e7ee7707b2b" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +intercept-stdout@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/intercept-stdout/-/intercept-stdout-0.1.2.tgz#126abf1fae6c509a428a98c61a631559042ae9fd" + dependencies: + lodash.toarray "^3.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + dependencies: + path-is-inside "^1.0.1" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.9.1: + version "3.11.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + +kuler@0.0.x: + version "0.0.0" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-0.0.0.tgz#b66bb46b934e550f59d818848e0abba4f7f5553c" + dependencies: + colornames "0.0.2" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lodash._arraycopy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.merge@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" + +lodash.toarray@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-3.0.2.tgz#2b204f0fa4f51c285c6f00c81d1cea5a23041179" + dependencies: + lodash._arraycopy "^3.0.0" + lodash._basevalues "^3.0.0" + lodash.keys "^3.0.0" + +lodash@^4.14.0, lodash@^4.17.4, lodash@^4.3.0: + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" + +logform@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-1.6.0.tgz#1104c93af10269864f2d98e7661abbea3690d83f" + dependencies: + colors "^1.2.1" + fecha "^2.3.3" + ms "^2.1.1" + triple-beam "^1.2.0" + +lru-cache@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + +minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@0.5.1, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha-cakes-2@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mocha-cakes-2/-/mocha-cakes-2-2.1.0.tgz#9f0a7f7ba47d30e226ac643e76bcb8fb23d56590" + +mocha@^3.1.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d" + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.6.8" + diff "3.2.0" + escape-string-regexp "1.0.5" + glob "7.1.1" + growl "1.9.2" + he "1.1.1" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +nan@~2.3.2: + version "2.3.5" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.3.5.tgz#822a0dc266290ce4cd3a12282ca3e7e364668a08" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +one-time@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + +prom-client@^10.2.2: + version "10.2.3" + resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-10.2.3.tgz#a51bf21c239c954a6c5be4b1361fdd380218bb41" + dependencies: + tdigest "^0.1.1" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +readable-stream@^2.2.2: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +rimraf@^2.2.8: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +safer-buffer@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + +semver@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + dependencies: + is-fullwidth-code-point "^2.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + +string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^5.3.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + dependencies: + has-flag "^3.0.0" + +table@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + dependencies: + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" + +tdigest@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/tdigest/-/tdigest-0.1.1.tgz#2e3cb2c39ea449e55d1e6cd91117accca4588021" + dependencies: + bintrees "1.0.1" + +text-hex@0.0.x: + version "0.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-0.0.0.tgz#578fbc85a6a92636e42dd17b41d0218cce9eb2b3" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + +triple-beam@^1.0.1, triple-beam@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.2.0.tgz#8b5c1f3d491229bf6ddcf721c0ba84cef5ab51fa" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +type-detect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + +type-detect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +unix-dgram@~0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/unix-dgram/-/unix-dgram-0.2.3.tgz#eab7330f1f1041d48f9c179d9f4c5a996cafceb5" + dependencies: + bindings "~1.1.1" + nan "~2.3.2" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +which@^1.2.9: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + +winston-syslog@^1.0.0: + version "1.2.6" + resolved "https://registry.yarnpkg.com/winston-syslog/-/winston-syslog-1.2.6.tgz#4e7990ed0a9f1932187ddd6ec9e038357980961f" + dependencies: + cycle "~1.0.3" + glossy "0.x.x" + optionalDependencies: + unix-dgram "~0.2.1" + +winston-transport@^3.1.0, winston-transport@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-3.2.1.tgz#5b79b294096b1a18bfe502e769491553a2cb1042" + +winston@^3.0.0-rc5: + version "3.0.0-rc5" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.0.0-rc5.tgz#bc383d32b0e774d387a66e77290fe78766468f34" + dependencies: + async "^2.6.0" + diagnostics "^1.0.1" + is-stream "^1.1.0" + logform "^1.4.1" + one-time "0.0.4" + stack-trace "0.0.x" + triple-beam "^1.0.1" + winston-transport "^3.1.0" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" From 8c9779bdb205b14706ddbebc9eea514885457a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Mon, 30 Apr 2018 07:51:58 +0200 Subject: [PATCH 02/22] WIP --- .gitignore | 1 + index.js | 3 ++- lib/transports.js | 9 +++++++-- logs/test.log | 3 --- 4 files changed, 10 insertions(+), 6 deletions(-) delete mode 100644 logs/test.log diff --git a/.gitignore b/.gitignore index e94e0a9..0625314 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ config/_revision # Atom CTAGS .tags +logs diff --git a/index.js b/index.js index 88c66a3..6050a68 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,7 @@ const winston = require("winston"); const path = require("path"); require("winston-syslog").Syslog; // eslint-disable-line no-unused-expressions +const fooTransport = require("./lib/transports"); const PromTransport = require("./lib/prom-transport"); const callingAppName = require(`${process.cwd()}/package.json`).name; const config = appConfig.logging; @@ -18,7 +19,7 @@ if (appConfig.envName === "test") { if (config.log === "file") { const fileName = path.join(process.cwd(), "logs", `${appConfig.envName}.log`); const options = config.truncateLog ? { flags: "w" } : { flags: "a" }; - transports.push(new winston.transports.File({ + transports.push(new fooTransport({ filename: fileName, json: config.logJson, options: options, diff --git a/lib/transports.js b/lib/transports.js index 16c19a1..ccf6524 100644 --- a/lib/transports.js +++ b/lib/transports.js @@ -1,5 +1,10 @@ "use strict"; +const winston = require("winston"); +const util = require() - - +class ConsoleTransport extends winston.transports.File { + log(...args) { + super.log(util.format(...args), args[args.length -1]); + } +} module.exports = ConsoleTransport; diff --git a/logs/test.log b/logs/test.log deleted file mode 100644 index dc8e8ef..0000000 --- a/logs/test.log +++ /dev/null @@ -1,3 +0,0 @@ -info: foobar -info: some message {"some":"info"} -info: one {"0":"t","1":"w","2":"o"} From 9951d7f0b55ad1c43f2a510fb9ec2fb22916796a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Wed, 16 Jan 2019 14:38:21 +0100 Subject: [PATCH 03/22] Bumped winston version --- package.json | 2 +- yarn.lock | 130 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 85 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index c17818d..f214ab2 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "dependencies": { "exp-config": "^2.0.1", "prom-client": "^10.2.2", - "winston": "^3.0.0-rc5", + "winston": "^3.1.0", "winston-syslog": "^1.0.0", "winston-transport": "^3.2.1" }, diff --git a/yarn.lock b/yarn.lock index 038a9ad..8524930 100644 --- a/yarn.lock +++ b/yarn.lock @@ -175,11 +175,7 @@ co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" -color-convert@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd" - -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" dependencies: @@ -189,33 +185,38 @@ color-name@1.1.3, color-name@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" -color-string@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== dependencies: color-name "^1.0.0" + simple-swizzle "^0.2.2" -color@0.8.x: - version "0.8.0" - resolved "https://registry.yarnpkg.com/color/-/color-0.8.0.tgz#890c07c3fd4e649537638911cf691e5458b6fca5" +color@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" + integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== dependencies: - color-convert "^0.5.0" - color-string "^0.3.0" + color-convert "^1.9.1" + color-string "^1.5.2" -colornames@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/colornames/-/colornames-0.0.2.tgz#d811fd6c84f59029499a8ac4436202935b92be31" +colornames@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" + integrity sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y= colors@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.1.tgz#f4a3d302976aaf042356ba1ade3b1a2c62d9d794" -colorspace@1.0.x: - version "1.0.1" - resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.0.1.tgz#c99c796ed31128b9876a52e1ee5ee03a4a719749" +colorspace@1.1.x: + version "1.1.1" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.1.tgz#9ac2491e1bc6f8fb690e2176814f8d091636d972" + integrity sha512-pI3btWyiuz7Ken0BWh9Elzsmv2bM9AhA7psXib4anUXy/orfZ/E0MbQwhSOG/9L8hLlalqrU0UhOuqxW1YjmVw== dependencies: - color "0.8.x" - text-hex "0.0.x" + color "3.0.x" + text-hex "1.0.x" commander@2.15.1: version "2.15.1" @@ -284,13 +285,14 @@ del@^2.0.2: pinkie-promise "^2.0.0" rimraf "^2.2.8" -diagnostics@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.0.tgz#e1090900b49523e8527be20f081275205f2ae36a" +diagnostics@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" + integrity sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ== dependencies: - colorspace "1.0.x" + colorspace "1.1.x" enabled "1.0.x" - kuler "0.0.x" + kuler "1.0.x" diff@3.5.0: version "3.5.0" @@ -432,6 +434,11 @@ fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" +fast-safe-stringify@^2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2" + integrity sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg== + fecha@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" @@ -579,6 +586,11 @@ intercept-stdout@^0.1.2: dependencies: lodash.toarray "^3.0.0" +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -638,11 +650,12 @@ json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" -kuler@0.0.x: - version "0.0.0" - resolved "https://registry.yarnpkg.com/kuler/-/kuler-0.0.0.tgz#b66bb46b934e550f59d818848e0abba4f7f5553c" +kuler@1.0.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6" + integrity sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ== dependencies: - colornames "0.0.2" + colornames "^1.1.1" levn@^0.3.0, levn@~0.3.0: version "0.3.0" @@ -699,11 +712,13 @@ lodash@^4.17.4, lodash@^4.3.0: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" -logform@^1.4.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-1.6.0.tgz#1104c93af10269864f2d98e7661abbea3690d83f" +logform@^1.9.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-1.10.0.tgz#c9d5598714c92b546e23f4e78147c40f1e02012e" + integrity sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg== dependencies: colors "^1.2.1" + fast-safe-stringify "^2.0.4" fecha "^2.3.3" ms "^2.1.1" triple-beam "^1.2.0" @@ -859,7 +874,7 @@ pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" -readable-stream@^2.2.2: +readable-stream@^2.2.2, readable-stream@^2.3.6: version "2.3.6" resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: @@ -941,6 +956,13 @@ signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + slice-ansi@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" @@ -1017,9 +1039,10 @@ tdigest@^0.1.1: dependencies: bintrees "1.0.1" -text-hex@0.0.x: - version "0.0.0" - resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-0.0.0.tgz#578fbc85a6a92636e42dd17b41d0218cce9eb2b3" +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== text-table@~0.2.0: version "0.2.0" @@ -1035,10 +1058,15 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -triple-beam@^1.0.1, triple-beam@^1.2.0: +triple-beam@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.2.0.tgz#8b5c1f3d491229bf6ddcf721c0ba84cef5ab51fa" +triple-beam@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" + integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -1084,22 +1112,32 @@ winston-syslog@^1.0.0: optionalDependencies: unix-dgram "~0.2.1" -winston-transport@^3.1.0, winston-transport@^3.2.1: +winston-transport@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-3.2.1.tgz#5b79b294096b1a18bfe502e769491553a2cb1042" -winston@^3.0.0-rc5: - version "3.0.0-rc5" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.0.0-rc5.tgz#bc383d32b0e774d387a66e77290fe78766468f34" +winston-transport@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.3.0.tgz#df68c0c202482c448d9b47313c07304c2d7c2c66" + integrity sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A== + dependencies: + readable-stream "^2.3.6" + triple-beam "^1.2.0" + +winston@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.1.0.tgz#80724376aef164e024f316100d5b178d78ac5331" + integrity sha512-FsQfEE+8YIEeuZEYhHDk5cILo1HOcWkGwvoidLrDgPog0r4bser1lEIOco2dN9zpDJ1M88hfDgZvxe5z4xNcwg== dependencies: async "^2.6.0" - diagnostics "^1.0.1" + diagnostics "^1.1.1" is-stream "^1.1.0" - logform "^1.4.1" + logform "^1.9.1" one-time "0.0.4" + readable-stream "^2.3.6" stack-trace "0.0.x" - triple-beam "^1.0.1" - winston-transport "^3.1.0" + triple-beam "^1.3.0" + winston-transport "^4.2.0" wordwrap@~1.0.0: version "1.0.0" From 406958ad25ad2fed3a9960bb09ea4c7dafd6b48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Wed, 16 Jan 2019 15:55:30 +0100 Subject: [PATCH 04/22] Came up with nice way of testing logger --- config/test.json | 4 +-- index.js | 47 ++++++++++++++++------------------ lib/prom-transport.js | 6 +++-- lib/splat-entry.js | 23 +++++++++++++++++ test/helpers/test-transport.js | 4 ++- test/logger-test.js | 22 ++++++++++++---- 6 files changed, 71 insertions(+), 35 deletions(-) create mode 100644 lib/splat-entry.js diff --git a/config/test.json b/config/test.json index def1cff..b7dc33d 100644 --- a/config/test.json +++ b/config/test.json @@ -1,8 +1,8 @@ -{ +{ "logging": { "log": "file", "logLevel": "debug", - "logJson": true, + "logJson": false, "truncateLog": true } } diff --git a/index.js b/index.js index 6050a68..1ab6eb1 100644 --- a/index.js +++ b/index.js @@ -3,55 +3,52 @@ const appConfig = require("exp-config"); const winston = require("winston"); const path = require("path"); +const callingAppName = require(`${process.cwd()}/package.json`).name; +const splatEntry = require("./lib/splat-entry"); + require("winston-syslog").Syslog; // eslint-disable-line no-unused-expressions -const fooTransport = require("./lib/transports"); const PromTransport = require("./lib/prom-transport"); -const callingAppName = require(`${process.cwd()}/package.json`).name; const config = appConfig.logging; - const transports = [new PromTransport()]; -if (appConfig.envName === "test") { - transports.push(require("./test/helpers/test-transport")); -} +const defaultFormatter = winston.format.printf((info) => `${info.timestamp} - ${info.level}: ${info.message}`); +const formatter = config.logJson ? winston.format.logstash() : defaultFormatter; if (config.log === "file") { const fileName = path.join(process.cwd(), "logs", `${appConfig.envName}.log`); const options = config.truncateLog ? { flags: "w" } : { flags: "a" }; - transports.push(new fooTransport({ + transports.push(new winston.transports.File({ filename: fileName, - json: config.logJson, - options: options, - stringify, - prettyPrint: true + options: options })); } if (config.log === "stdout") { - transports.push(new winston.transports.Console({ - colorize: false, - timestamp: true, - json: config.logJson, - stringify - })); + transports.push(new winston.transports.Console()); } if (config.sysLogOpts) { transports.push(new winston.transports.Syslog(Object.assign({ localhost: process.env.HOSTNAME, app_name: callingAppName, // eslint-disable-line camelcase - eol: "\n", - json: config.logJson, - stringify + eol: "\n" }, config.sysLogOpts))); } -function stringify(obj) { - return config.logJson ? JSON.stringify(obj) : obj.replace(/\n/g, " "); -} -module.exports = winston.createLogger({ +const logger = winston.createLogger({ level: config.logLevel || "info", - transports: transports + transports: transports, + format: winston.format.combine( + winston.format.metadata({key: "meta"}), + winston.format.timestamp(), + winston.format(splatEntry)(), + formatter + ), + defaultMeta: {appName: callingAppName}, }); + +module.exports = { + logger +}; diff --git a/lib/prom-transport.js b/lib/prom-transport.js index 42cc7f5..13ed1c3 100644 --- a/lib/prom-transport.js +++ b/lib/prom-transport.js @@ -20,8 +20,10 @@ class PromTransport extends Transport { }); } } - log(level) { - this.logCounter.inc({level}); + log(info) { + if (info.level === "foo") { + this.logCounter.inc({level: info.level}); + } } } diff --git a/lib/splat-entry.js b/lib/splat-entry.js new file mode 100644 index 0000000..0b569cc --- /dev/null +++ b/lib/splat-entry.js @@ -0,0 +1,23 @@ +"use strict"; +const util = require("util"); +const config = require("exp-config").logging; + +function splatEntry(info) { + const splat = info[Symbol.for("splat")]; + if (!splat || splat.length === 1) { + return info; + } + + const message = [...splat]; + if (typeof message[message.length - 1] === "object") { + info.meta = message.pop(); + } + + info.message = util.format(info.message, ...message); + if (!config.pretty) { + info.message = info.message.replace(/\n\s*/gm, " "); + } + return info; +} + +module.exports = splatEntry; diff --git a/test/helpers/test-transport.js b/test/helpers/test-transport.js index 9445fc4..2ca4a06 100644 --- a/test/helpers/test-transport.js +++ b/test/helpers/test-transport.js @@ -9,8 +9,10 @@ class CustomTransport extends Transport { this.name = "test-transport"; this.logs = []; } - log(level, message, meta) { + log(info, callback) { + const {level, message, meta} = info; this.logs.push({level, message, meta}); + callback(); } } diff --git a/test/logger-test.js b/test/logger-test.js index 6043fd8..c49cf18 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -1,7 +1,8 @@ "use strict"; -const logger = require("../"); +const {logger} = require("../"); const transport = require("./helpers/test-transport"); +logger.add(transport); describe("logger", () => { it("should log", () => { @@ -10,16 +11,27 @@ describe("logger", () => { log.should.eql({level: "info", message: "foobar", meta: {}}); }); - it("should log objects", () => { + it("should log with meta", () => { logger.info("some message", {"some": "info"}); const log = transport.logs.shift(); log.should.eql({level: "info", message: "some message", meta: { "some": "info"}}); }); - it("should log objects anything", () => { - logger.info("one", "two", "threee", "four"); + it("should log splat multiple arguments with meta", () => { + logger.info("one", "two", "three", "four", {"some": "info"}); const log = transport.logs.shift(); - log.should.eql({level: "info", message: "some message", meta: { "some": "info"}}); + log.should.eql({level: "info", message: "one two three four", meta: { "some": "info"}}); + }); + + it("should log splat multiple arguments without meta", () => { + logger.info("one", "two", "three", "four"); + const log = transport.logs.shift(); + log.should.eql({level: "info", message: "one two three four", meta: {}}); }); + it("should log splat multiple objects with meta", () => { + logger.info("one", "two", {three: 3, four: 4}, {"correlationId": "coobar"}); + const log = transport.logs.shift(); + log.should.eql({level: "info", message: "one two { three: 3, four: 4 }", meta: {correlationId: "coobar"}}); + }); }); From 0a3cc17c68db2fb90c7e1137c7c2cf8f1f69bc62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Wed, 16 Jan 2019 16:31:32 +0100 Subject: [PATCH 05/22] Getting there --- .eslintrc.json | 23 +++++++++++++++-------- .nvmrc | 1 + config/levels.js | 12 ++++++++++++ index.js | 4 +++- test/config/setup.js | 3 +++ test/helpers/test-transport.js | 8 +++++--- test/logger-test.js | 29 +++++++++++++++++++++++------ 7 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 .nvmrc create mode 100644 config/levels.js diff --git a/.eslintrc.json b/.eslintrc.json index 4b65754..3010464 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,6 @@ { "parserOptions": { - "ecmaVersion": 6 + "ecmaVersion": 2018 }, "env": { "node": true, @@ -10,18 +10,18 @@ "rules": { "arrow-parens": 2, "arrow-spacing": 2, - "brace-style": [2, "1tbs", { "allowSingleLine": false }], + "brace-style": [2, "1tbs", {"allowSingleLine": false}], "callback-return": 2, "camelcase": 1, "comma-spacing": 1, "curly": [2, "multi-line"], - "dot-notation": [2, { "allowKeywords": true }], + "dot-notation": [2, {"allowKeywords": true}], "eol-last": 2, "eqeqeq": 2, "handle-callback-err": 2, - "key-spacing": [1, { "beforeColon": false, "afterColon": true }], + "key-spacing": [1, {"beforeColon": false, "afterColon": true}], "keyword-spacing": 1, - "indent": [1, 2, { "SwitchCase": 1, "MemberExpression": 1 }], + "indent": [1, 2, {"SwitchCase": 1, "MemberExpression": 1}], "new-cap": 2, "new-parens": 1, "no-alert": 2, @@ -65,17 +65,24 @@ "no-use-before-define": [2, "nofunc"], "no-var": 2, "no-with": 2, + "object-curly-spacing": ["error", "never"], "prefer-arrow-callback": 2, "prefer-const": ["error", {"destructuring": "all"}], "prefer-template": 1, - "quotes": [1, "double"], + "quotes": [1, "double", {"avoidEscape": true}], "semi": [2, "always"], "semi-spacing": [1, {"before": false, "after": true}], "space-before-blocks": 1, "space-before-function-paren": [1, {"anonymous": "always", "named": "never"}], "space-infix-ops": 1, - "space-unary-ops": [1, { "words": true, "nonwords": false }], + "space-unary-ops": [1, {"words": true, "nonwords": false}], + "space-in-parens": ["error", "never"], "strict": [2, "global"], - "yoda": [1, "never"] + "template-curly-spacing": ["error", "never"], + "yoda": [1, "never"], + "require-await": ["error"], + "no-restricted-modules": ["warn", { + "patterns": ["test-data/*"] + }] } } diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +10 diff --git a/config/levels.js b/config/levels.js new file mode 100644 index 0000000..ac432b9 --- /dev/null +++ b/config/levels.js @@ -0,0 +1,12 @@ +"use strict"; + +module.exports = { + emergency: 0, + alert: 1, + critical: 2, + error: 3, + warning: 4, + notice: 5, + info: 6, + debug: 7 +}; diff --git a/index.js b/index.js index 1ab6eb1..0e000f4 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,7 @@ const winston = require("winston"); const path = require("path"); const callingAppName = require(`${process.cwd()}/package.json`).name; const splatEntry = require("./lib/splat-entry"); +const logLevels = require("./config/levels"); require("winston-syslog").Syslog; // eslint-disable-line no-unused-expressions @@ -17,7 +18,7 @@ const formatter = config.logJson ? winston.format.logstash() : defaultFormatter; if (config.log === "file") { const fileName = path.join(process.cwd(), "logs", `${appConfig.envName}.log`); - const options = config.truncateLog ? { flags: "w" } : { flags: "a" }; + const options = config.truncateLog ? {flags: "w"} : {flags: "a"}; transports.push(new winston.transports.File({ filename: fileName, options: options @@ -39,6 +40,7 @@ if (config.sysLogOpts) { const logger = winston.createLogger({ level: config.logLevel || "info", + levels: logLevels, transports: transports, format: winston.format.combine( winston.format.metadata({key: "meta"}), diff --git a/test/config/setup.js b/test/config/setup.js index 9f5c91f..bf9c8b4 100644 --- a/test/config/setup.js +++ b/test/config/setup.js @@ -13,3 +13,6 @@ chai.config.includeStack = true; Object.assign(global, { should: chai.should() }); + +const {logger} = require("../../."); +logger.add(require("../helpers/test-transport")); diff --git a/test/helpers/test-transport.js b/test/helpers/test-transport.js index 2ca4a06..12c4196 100644 --- a/test/helpers/test-transport.js +++ b/test/helpers/test-transport.js @@ -2,7 +2,6 @@ const Transport = require("winston-transport"); - class CustomTransport extends Transport { constructor(opts) { super(opts); @@ -10,8 +9,11 @@ class CustomTransport extends Transport { this.logs = []; } log(info, callback) { - const {level, message, meta} = info; - this.logs.push({level, message, meta}); + let message = info.message; + if (!message) { + message = info[Symbol.for("message")]; + } + this.logs.push({...info, message}); callback(); } } diff --git a/test/logger-test.js b/test/logger-test.js index c49cf18..aba5f6f 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -1,37 +1,54 @@ "use strict"; +const logLevels = -require("../config/levels"); const {logger} = require("../"); const transport = require("./helpers/test-transport"); -logger.add(transport); +const should = require("chai").should(); describe("logger", () => { it("should log", () => { logger.info("foobar"); const log = transport.logs.shift(); - log.should.eql({level: "info", message: "foobar", meta: {}}); + log.should.include({level: "info", message: "foobar"}); + log.meta.should.eql({}); }); it("should log with meta", () => { logger.info("some message", {"some": "info"}); const log = transport.logs.shift(); - log.should.eql({level: "info", message: "some message", meta: { "some": "info"}}); + log.should.include({level: "info", message: "some message"}); + log.meta.should.eql({"some": "info"}); }); it("should log splat multiple arguments with meta", () => { logger.info("one", "two", "three", "four", {"some": "info"}); const log = transport.logs.shift(); - log.should.eql({level: "info", message: "one two three four", meta: { "some": "info"}}); + log.should.include({level: "info", message: "one two three four"}); + log.meta.should.eql({"some": "info"}); }); it("should log splat multiple arguments without meta", () => { logger.info("one", "two", "three", "four"); const log = transport.logs.shift(); - log.should.eql({level: "info", message: "one two three four", meta: {}}); + log.should.include({level: "info", message: "one two three four"}); + log.meta.should.eql({}); }); it("should log splat multiple objects with meta", () => { logger.info("one", "two", {three: 3, four: 4}, {"correlationId": "coobar"}); const log = transport.logs.shift(); - log.should.eql({level: "info", message: "one two { three: 3, four: 4 }", meta: {correlationId: "coobar"}}); + log.should.include({level: "info", message: "one two { three: 3, four: 4 }"}); + log.meta.should.eql({correlationId: "coobar"}); + }); + + describe("levels", () => { + Object.keys(logLevels).forEach((level) => { + it(`should log ${level}`, () => { + logger.log(level, "message"); + const log = transport.logs.shift(); + should.exist(log); + log.level.should.eql(level); + }); + }); }); }); From a510767b59715bf2c054a31703dfbd24655d9c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Wed, 16 Jan 2019 16:33:16 +0100 Subject: [PATCH 06/22] Hackety hack --- config/test.json | 2 +- test/helpers/test-transport.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/test.json b/config/test.json index b7dc33d..9d2a37f 100644 --- a/config/test.json +++ b/config/test.json @@ -2,7 +2,7 @@ "logging": { "log": "file", "logLevel": "debug", - "logJson": false, + "logJson": true, "truncateLog": true } } diff --git a/test/helpers/test-transport.js b/test/helpers/test-transport.js index 12c4196..d484537 100644 --- a/test/helpers/test-transport.js +++ b/test/helpers/test-transport.js @@ -12,6 +12,8 @@ class CustomTransport extends Transport { let message = info.message; if (!message) { message = info[Symbol.for("message")]; + info._message = message; + message = JSON.parse(message)["@message"]; } this.logs.push({...info, message}); callback(); From c9d91641845e207fc664228891a6be652883b79a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Wed, 16 Jan 2019 16:59:36 +0100 Subject: [PATCH 07/22] Started refactoring logger --- index.js | 18 ++++--- .../{logging-test.js => logging-feature.js} | 49 +++---------------- test/helpers/test-transport.js | 1 - 3 files changed, 20 insertions(+), 48 deletions(-) rename test/feature/{logging-test.js => logging-feature.js} (84%) diff --git a/index.js b/index.js index 0e000f4..4136ea1 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ const appConfig = require("exp-config"); const winston = require("winston"); +const {format} = winston; const path = require("path"); const callingAppName = require(`${process.cwd()}/package.json`).name; const splatEntry = require("./lib/splat-entry"); @@ -13,8 +14,8 @@ const PromTransport = require("./lib/prom-transport"); const config = appConfig.logging; const transports = [new PromTransport()]; -const defaultFormatter = winston.format.printf((info) => `${info.timestamp} - ${info.level}: ${info.message}`); -const formatter = config.logJson ? winston.format.logstash() : defaultFormatter; +const defaultFormatter = format.printf((info) => `${info.timestamp} - ${info.level}: ${info.message}`); +const formatter = config.logJson ? format.logstash() : defaultFormatter; if (config.log === "file") { const fileName = path.join(process.cwd(), "logs", `${appConfig.envName}.log`); @@ -37,15 +38,20 @@ if (config.sysLogOpts) { }, config.sysLogOpts))); } +function logLevel(info) { + info.logLevel = info.level; + return info; +} const logger = winston.createLogger({ level: config.logLevel || "info", levels: logLevels, transports: transports, - format: winston.format.combine( - winston.format.metadata({key: "meta"}), - winston.format.timestamp(), - winston.format(splatEntry)(), + format: format.combine( + format.metadata({key: "metaData"}), + format.timestamp(), + format(logLevel)(), + format(splatEntry)(), formatter ), defaultMeta: {appName: callingAppName}, diff --git a/test/feature/logging-test.js b/test/feature/logging-feature.js similarity index 84% rename from test/feature/logging-test.js rename to test/feature/logging-feature.js index 4e84c3b..f4290db 100644 --- a/test/feature/logging-test.js +++ b/test/feature/logging-feature.js @@ -1,19 +1,12 @@ "use strict"; -const createLogger = require("../../lib/logger"); +const {logger} = require("../../"); +const transport = require("../helpers/test-transport"); const intercept = require("intercept-stdout"); const prometheusClient = require("prom-client"); Feature("Logging", () => { Scenario("Logging debug with JSON format", () => { - let unhook; - let stdoutContents = ""; - - const config = { - "log": "stdout", - "logLevel": "debug", - "logJson": true - }; const message = "Message"; const data = { "meta": { @@ -23,37 +16,21 @@ Feature("Logging", () => { } }; - When("initializing the logger and doing some JSON logging", () => { - const logger = createLogger(config); - - unhook = intercept((txt) => { - stdoutContents += txt; - }); - + When("doing some JSON logging", () => { logger.debug(message, data); - - unhook(); }); Then("log output should be JSON", () => { - const logContent = JSON.parse(stdoutContents.trim()); + const logContent = transport.logs.shift(); logContent.logLevel.should.equal("debug"); - logContent.location.should.be.ok; // eslint-disable-line no-unused-expressions logContent.metaData.should.deep.equal(data); logContent.message.should.equal(message); + // logContent.location.should.be.ok; // eslint-disable-line no-unused-expressions }); }); Scenario("Logging a too big message JSON format", () => { - let unhook; - let stdoutContents = ""; - - const config = { - "log": "stdout", - "logLevel": "debug", - "logJson": true - }; const message = "Message".repeat(9000); const data = { "meta": { @@ -63,22 +40,12 @@ Feature("Logging", () => { } }; - When("initializing the logger and doing some JSON logging", () => { - const logger = createLogger(config); - - unhook = intercept((txt) => { - stdoutContents += txt; - }); - + When("logging a huge message", () => { logger.debug(message, data); - - unhook(); }); - Then("log output should be JSON", () => { - const logContent = JSON.parse(stdoutContents.trim()); - logContent.logLevel.should.equal("debug"); - logContent.location.should.be.ok; // eslint-disable-line no-unused-expressions + Then("log output should be trimmed", () => { + const logContent = transport.logs.shift(); logContent.metaData.should.deep.equal(data); logContent.message.should.equal("too big to log"); }); diff --git a/test/helpers/test-transport.js b/test/helpers/test-transport.js index d484537..612ba46 100644 --- a/test/helpers/test-transport.js +++ b/test/helpers/test-transport.js @@ -1,7 +1,6 @@ "use strict"; const Transport = require("winston-transport"); - class CustomTransport extends Transport { constructor(opts) { super(opts); From f576b63205d240ebf6f966ebc561f9c1b5c59efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 08:41:18 +0100 Subject: [PATCH 08/22] Fixes --- index.js | 84 ++++++++++++++++++++++++--------------------- lib/splat-entry.js | 2 +- test/logger-test.js | 10 +++--- 3 files changed, 51 insertions(+), 45 deletions(-) diff --git a/index.js b/index.js index 4136ea1..16490f3 100644 --- a/index.js +++ b/index.js @@ -12,51 +12,57 @@ require("winston-syslog").Syslog; // eslint-disable-line no-unused-expressions const PromTransport = require("./lib/prom-transport"); const config = appConfig.logging; -const transports = [new PromTransport()]; - -const defaultFormatter = format.printf((info) => `${info.timestamp} - ${info.level}: ${info.message}`); -const formatter = config.logJson ? format.logstash() : defaultFormatter; - -if (config.log === "file") { - const fileName = path.join(process.cwd(), "logs", `${appConfig.envName}.log`); - const options = config.truncateLog ? {flags: "w"} : {flags: "a"}; - transports.push(new winston.transports.File({ - filename: fileName, - options: options - })); -} - -if (config.log === "stdout") { - transports.push(new winston.transports.Console()); -} - -if (config.sysLogOpts) { - transports.push(new winston.transports.Syslog(Object.assign({ - localhost: process.env.HOSTNAME, - app_name: callingAppName, // eslint-disable-line camelcase - eol: "\n" - }, config.sysLogOpts))); -} function logLevel(info) { info.logLevel = info.level; return info; } -const logger = winston.createLogger({ - level: config.logLevel || "info", - levels: logLevels, - transports: transports, - format: format.combine( - format.metadata({key: "metaData"}), - format.timestamp(), - format(logLevel)(), - format(splatEntry)(), - formatter - ), - defaultMeta: {appName: callingAppName}, -}); +function createLogger() { + const transports = [new PromTransport()]; + + const defaultFormatter = format.printf((info) => `${info.timestamp} - ${info.level}: ${info.message}`); + const formatter = config.logJson ? format.logstash() : defaultFormatter; + + if (config.log === "file") { + const fileName = path.join(process.cwd(), "logs", `${appConfig.envName}.log`); + const options = config.truncateLog ? {flags: "w"} : {flags: "a"}; + transports.push(new winston.transports.File({ + filename: fileName, + options: options + })); + } + + if (config.log === "stdout") { + transports.push(new winston.transports.Console()); + } + + if (config.sysLogOpts) { + transports.push(new winston.transports.Syslog(Object.assign({ + localhost: process.env.HOSTNAME, + app_name: callingAppName, // eslint-disable-line camelcase + eol: "\n" + }, config.sysLogOpts))); + } + + + const logger = winston.createLogger({ + level: config.logLevel || "info", + levels: logLevels, + transports: transports, + format: format.combine( + format.metadata({key: "metaData"}), + format.timestamp(), + format(logLevel)(), + format(splatEntry)(), + formatter + ) + }); + + return logger; +} module.exports = { - logger + logger: createLogger(), + createLogger }; diff --git a/lib/splat-entry.js b/lib/splat-entry.js index 0b569cc..062703e 100644 --- a/lib/splat-entry.js +++ b/lib/splat-entry.js @@ -10,7 +10,7 @@ function splatEntry(info) { const message = [...splat]; if (typeof message[message.length - 1] === "object") { - info.meta = message.pop(); + info.metaData = message.pop(); } info.message = util.format(info.message, ...message); diff --git a/test/logger-test.js b/test/logger-test.js index aba5f6f..c1f9f15 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -10,35 +10,35 @@ describe("logger", () => { logger.info("foobar"); const log = transport.logs.shift(); log.should.include({level: "info", message: "foobar"}); - log.meta.should.eql({}); + log.metaData.should.eql({}); }); it("should log with meta", () => { logger.info("some message", {"some": "info"}); const log = transport.logs.shift(); log.should.include({level: "info", message: "some message"}); - log.meta.should.eql({"some": "info"}); + log.metaData.should.eql({"some": "info"}); }); it("should log splat multiple arguments with meta", () => { logger.info("one", "two", "three", "four", {"some": "info"}); const log = transport.logs.shift(); log.should.include({level: "info", message: "one two three four"}); - log.meta.should.eql({"some": "info"}); + log.metaData.should.eql({"some": "info"}); }); it("should log splat multiple arguments without meta", () => { logger.info("one", "two", "three", "four"); const log = transport.logs.shift(); log.should.include({level: "info", message: "one two three four"}); - log.meta.should.eql({}); + log.metaData.should.eql({}); }); it("should log splat multiple objects with meta", () => { logger.info("one", "two", {three: 3, four: 4}, {"correlationId": "coobar"}); const log = transport.logs.shift(); log.should.include({level: "info", message: "one two { three: 3, four: 4 }"}); - log.meta.should.eql({correlationId: "coobar"}); + log.metaData.should.eql({correlationId: "coobar"}); }); describe("levels", () => { From 02520e42f040575938b6d1a04042dbcbf816fc0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 09:34:56 +0100 Subject: [PATCH 09/22] Aliases --- config/levels.js | 24 +++++++++++++++++++++++- index.js | 7 ++++--- test/logger-test.js | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/config/levels.js b/config/levels.js index ac432b9..2161a04 100644 --- a/config/levels.js +++ b/config/levels.js @@ -1,6 +1,6 @@ "use strict"; -module.exports = { +const levels = { emergency: 0, alert: 1, critical: 2, @@ -10,3 +10,25 @@ module.exports = { info: 6, debug: 7 }; +const aliases = { + emergency: "emerg", + critical: "crit", +}; + +const colors = { + emergency: "blue", + alert: "darkred", + critical: "cyan", + error: "red", + warning: "yellow", + notice: "magenta", + info: "green", + debug: "gray" +}; + +module.exports = { + levels, + aliases, + colors +}; + diff --git a/index.js b/index.js index 16490f3..6fad9fa 100644 --- a/index.js +++ b/index.js @@ -14,7 +14,7 @@ const PromTransport = require("./lib/prom-transport"); const config = appConfig.logging; function logLevel(info) { - info.logLevel = info.level; + info.logLevel = logLevels.aliases[info.level] || info.level; return info; } @@ -22,7 +22,7 @@ function createLogger() { const transports = [new PromTransport()]; const defaultFormatter = format.printf((info) => `${info.timestamp} - ${info.level}: ${info.message}`); - const formatter = config.logJson ? format.logstash() : defaultFormatter; + const formatter = config.logJson ? format.json() : defaultFormatter; if (config.log === "file") { const fileName = path.join(process.cwd(), "logs", `${appConfig.envName}.log`); @@ -48,7 +48,8 @@ function createLogger() { const logger = winston.createLogger({ level: config.logLevel || "info", - levels: logLevels, + levels: logLevels.levels, + colors: logLevel.colors, transports: transports, format: format.combine( format.metadata({key: "metaData"}), diff --git a/test/logger-test.js b/test/logger-test.js index c1f9f15..5baa0f5 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -50,5 +50,24 @@ describe("logger", () => { log.level.should.eql(level); }); }); + describe("logLevel aliases", () => { + it("should mark emergency with emerg", () => { + logger.emergency("foobar"); + const log = transport.logs.shift(); + log.logLevel.should.eql("emerg"); + }); + + it("should mark critical with crit", () => { + logger.critical("foobar"); + const log = transport.logs.shift(); + log.logLevel.should.eql("crit"); + }); + + it("should keep levels when no alias", () => { + logger.warning("foobar"); + const log = transport.logs.shift(); + log.logLevel.should.eql("warning"); + }); + }); }); }); From 4b063ad698f14ae2891da3939e27c60e35aeadbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 09:57:06 +0100 Subject: [PATCH 10/22] Handling too big message --- index.js | 16 ++++++++++++ lib/truncate-utf8-bytes.js | 45 +++++++++++++++++++++++++++++++++ test/feature/logging-feature.js | 2 +- 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 lib/truncate-utf8-bytes.js diff --git a/index.js b/index.js index 6fad9fa..20da50d 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,8 @@ const path = require("path"); const callingAppName = require(`${process.cwd()}/package.json`).name; const splatEntry = require("./lib/splat-entry"); const logLevels = require("./config/levels"); +const getLoc = require("./lib/get-loc"); +const truncate = require("./lib/truncate-utf8-bytes"); require("winston-syslog").Syslog; // eslint-disable-line no-unused-expressions @@ -18,6 +20,18 @@ function logLevel(info) { return info; } +function location(info) { + info.location = getLoc(); + return info; +} + +function truncateTooLong(info) { + if (Buffer.byteLength(info.message, "utf8") > 60 * 1024) { + info.message = truncate(info.message, 60 * 1024); + } + return info; +} + function createLogger() { const transports = [new PromTransport()]; @@ -56,6 +70,8 @@ function createLogger() { format.timestamp(), format(logLevel)(), format(splatEntry)(), + format(location)(), + format(truncateTooLong)(), formatter ) }); diff --git a/lib/truncate-utf8-bytes.js b/lib/truncate-utf8-bytes.js new file mode 100644 index 0000000..7b8cd73 --- /dev/null +++ b/lib/truncate-utf8-bytes.js @@ -0,0 +1,45 @@ +"use strict"; +// stolen from: https://raw.githubusercontent.com/parshap/truncate-utf8-bytes/master/lib/truncate.js + + +function isHighSurrogate(codePoint) { + return codePoint >= 0xd800 && codePoint <= 0xdbff; +} + +function isLowSurrogate(codePoint) { + return codePoint >= 0xdc00 && codePoint <= 0xdfff; +} + +const getLength = Buffer.byteLength.bind(Buffer); + +// Truncate string by size in bytes +module.exports = function truncate(string, byteLength) { + if (typeof string !== "string") { + throw new Error("Input must be string"); + } + + const charLength = string.length; + let curByteLength = 0; + let codePoint; + let segment; + + for (let i = 0; i < charLength; i += 1) { + codePoint = string.charCodeAt(i); + segment = string[i]; + + if (isHighSurrogate(codePoint) && isLowSurrogate(string.charCodeAt(i + 1))) { + i += 1; + segment += string[i]; + } + + curByteLength += getLength(segment); + + if (curByteLength === byteLength) { + return string.slice(0, i + 1); + } else if (curByteLength > byteLength) { + return string.slice(0, i - segment.length + 1); + } + } + + return string; +}; diff --git a/test/feature/logging-feature.js b/test/feature/logging-feature.js index f4290db..3c02e3c 100644 --- a/test/feature/logging-feature.js +++ b/test/feature/logging-feature.js @@ -25,7 +25,7 @@ Feature("Logging", () => { logContent.logLevel.should.equal("debug"); logContent.metaData.should.deep.equal(data); logContent.message.should.equal(message); - // logContent.location.should.be.ok; // eslint-disable-line no-unused-expressions + logContent.location.should.be.ok; // eslint-disable-line no-unused-expressions }); }); From 7a9066399606120d16987de471ceb7280edda387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 15:19:21 +0100 Subject: [PATCH 11/22] Reimplementing old stuff --- config/test.json | 3 +- index.js | 4 +- lib/prom-transport.js | 15 ++++++-- test/feature/logging-feature.js | 67 +++------------------------------ 4 files changed, 22 insertions(+), 67 deletions(-) diff --git a/config/test.json b/config/test.json index 9d2a37f..39fc33e 100644 --- a/config/test.json +++ b/config/test.json @@ -3,6 +3,7 @@ "log": "file", "logLevel": "debug", "logJson": true, - "truncateLog": true + "truncateLog": true, + "metricPrefix": "test" } } diff --git a/index.js b/index.js index 20da50d..72bb9eb 100644 --- a/index.js +++ b/index.js @@ -8,7 +8,7 @@ const callingAppName = require(`${process.cwd()}/package.json`).name; const splatEntry = require("./lib/splat-entry"); const logLevels = require("./config/levels"); const getLoc = require("./lib/get-loc"); -const truncate = require("./lib/truncate-utf8-bytes"); +// const truncate = require("./lib/truncate-utf8-bytes"); require("winston-syslog").Syslog; // eslint-disable-line no-unused-expressions @@ -27,7 +27,7 @@ function location(info) { function truncateTooLong(info) { if (Buffer.byteLength(info.message, "utf8") > 60 * 1024) { - info.message = truncate(info.message, 60 * 1024); + info.message = "too big to log"; } return info; } diff --git a/lib/prom-transport.js b/lib/prom-transport.js index 13ed1c3..bcb3c25 100644 --- a/lib/prom-transport.js +++ b/lib/prom-transport.js @@ -3,6 +3,7 @@ const Transport = require("winston-transport"); const prometheusClient = require("prom-client"); const callingAppName = require(`${process.cwd()}/package.json`).name; +const getEventName = require("./get-event-name"); class PromTransport extends Transport { constructor(opts) { @@ -20,10 +21,18 @@ class PromTransport extends Transport { }); } } - log(info) { - if (info.level === "foo") { - this.logCounter.inc({level: info.level}); + log(info, callback) { + const metricLabels = {level: info.level}; + if (info.level === "error") { + const eventName = getEventName(info.metaData); + if (eventName) { + metricLabels.eventName = eventName; + } else { + metricLabels.eventName = ""; + } } + this.logCounter.inc(metricLabels); + callback(); } } diff --git a/test/feature/logging-feature.js b/test/feature/logging-feature.js index 3c02e3c..f4e68fc 100644 --- a/test/feature/logging-feature.js +++ b/test/feature/logging-feature.js @@ -2,7 +2,6 @@ const {logger} = require("../../"); const transport = require("../helpers/test-transport"); -const intercept = require("intercept-stdout"); const prometheusClient = require("prom-client"); Feature("Logging", () => { @@ -53,14 +52,6 @@ Feature("Logging", () => { Scenario("Logging error with JSON format", () => { - let unhook; - let stdoutContents = ""; - - const config = { - "log": "stdout", - "logLevel": "debug", - "logJson": true - }; const message = "Message"; const data = { "meta": { @@ -70,20 +61,12 @@ Feature("Logging", () => { } }; - When("initializing the logger and doing some JSON logging", () => { - const logger = createLogger(config); - - unhook = intercept((txt) => { - stdoutContents += txt; - }); - + When("doing some JSON logging", () => { logger.error(message, data); - - unhook(); }); Then("log output should be JSON", () => { - const logContent = JSON.parse(stdoutContents.trim()); + const logContent = transport.logs.shift(); logContent.logLevel.should.equal("error"); logContent.location.should.be.ok; // eslint-disable-line no-unused-expressions logContent.metaData.should.deep.equal(data); @@ -92,14 +75,7 @@ Feature("Logging", () => { }); Scenario("Logging with string format", () => { - let unhook; - let stdoutContents = ""; - - const config = { - "log": "stdout", - "logLevel": "debug", - "logJson": false - }; + const stdoutContents = ""; const message = "Message"; const data = { "meta": { @@ -110,36 +86,15 @@ Feature("Logging", () => { }; When("initializing the logger and doing some string logging", () => { - const logger = createLogger(config); - - unhook = intercept((txt) => { - stdoutContents += txt; - }); - logger.debug(message, data); - - unhook(); }); - Then("log output should be string", (done) => { + Then("log output should be string", () => { stdoutContents.should.be.a("string"); - - try { - JSON.parse(stdoutContents); - done("No error thrown"); - } catch (err) { - done(); - } }); }); Scenario("Logging should inc metric", () => { - const config = { - "log": "stdout", - "logLevel": "debug", - "logJson": false, - "metricPrefix": "test" - }; const message = "Message"; before(() => { @@ -147,8 +102,6 @@ Feature("Logging", () => { }); When("initializing the logger and doing some string logging", () => { - const logger = createLogger(config); - logger.emergency(message); logger.alert(message); @@ -177,12 +130,11 @@ Feature("Logging", () => { }); Then("the logCounter metric should be incremented", () => { - const counterMetric = prometheusClient.register.getSingleMetric("lulogger_logged_total"); const emergencyCount = counterMetric.hashMap["level:emergency"].value; const alertCount = counterMetric.hashMap["level:alert"].value; - const criticalCount = counterMetric.hashMap["level:crit"].value; - const errorCount = counterMetric.hashMap["level:error"].value; + const criticalCount = counterMetric.hashMap["level:critical"].value; + const errorCount = counterMetric.hashMap["eventName:,level:error"].value; const warningCount = counterMetric.hashMap["level:warning"].value; const noticeCount = counterMetric.hashMap["level:notice"].value; const infoCount = counterMetric.hashMap["level:info"].value; @@ -200,12 +152,6 @@ Feature("Logging", () => { }); Scenario("Logging error with routingKey in logObject should inc metric with eventName as label", () => { - const config = { - "log": "stdout", - "logLevel": "debug", - "logJson": false, - "metricPrefix": "test" - }; const message = "Message"; const routingKey = "namespace.event-name.some.cool.key"; @@ -214,7 +160,6 @@ Feature("Logging", () => { }); When("initializing the logger and doing some string logging", () => { - const logger = createLogger(config); logger.error(message, {meta: {routingKey}}); }); From 6e37b6472dab092fef2454a7d78f01abaa9573fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 15:25:04 +0100 Subject: [PATCH 12/22] Fixed all failing tests --- lib/logger.js | 16 +- lib/transports.js | 4 +- package.json | 7 +- test/logger-test.js | 4 + yarn.lock | 485 +++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 497 insertions(+), 19 deletions(-) diff --git a/lib/logger.js b/lib/logger.js index 208bb6d..f24fa7f 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -18,7 +18,7 @@ const logLevels = { debug: 7 }; -const invertedLevels = Object.assign({}, ...Object.entries(logLevels).map(([a, b]) => ({ [b]: a }))); +const invertedLevels = Object.assign({}, ...Object.entries(logLevels).map(([a, b]) => ({[b]: a}))); function init(config) { if (!config) { @@ -101,17 +101,17 @@ function init(config) { return { emergency: (label, logObject) => { logger.emerg(label, prepLogObject(logLevels.emerg, logObject)); - logCounter.inc({ level: "emergency" }); + logCounter.inc({level: "emergency"}); }, alert: (label, logObject) => { logger.alert(label, prepLogObject(logLevels.alert, logObject)); - logCounter.inc({ level: "alert" }); + logCounter.inc({level: "alert"}); }, critical: (label, logObject) => { logger.crit(label, prepLogObject(logLevels.crit, logObject)); - logCounter.inc({ level: "crit" }); + logCounter.inc({level: "crit"}); }, error: (label, logObject) => { @@ -126,22 +126,22 @@ function init(config) { warning: (label, logObject) => { logger.warning(label, prepLogObject(logLevels.warning, logObject)); - logCounter.inc({ level: "warning" }); + logCounter.inc({level: "warning"}); }, notice: (label, logObject) => { logger.notice(label, prepLogObject(logLevels.notice, logObject)); - logCounter.inc({ level: "notice" }); + logCounter.inc({level: "notice"}); }, info: (label, logObject) => { logger.info(label, prepLogObject(logLevels.info, logObject)); - logCounter.inc({ level: "info" }); + logCounter.inc({level: "info"}); }, debug: (label, logObject) => { logger.debug(label, prepLogObject(logLevels.debug, logObject)); - logCounter.inc({ level: "debug" }); + logCounter.inc({level: "debug"}); }, }; } diff --git a/lib/transports.js b/lib/transports.js index ccf6524..3864cc4 100644 --- a/lib/transports.js +++ b/lib/transports.js @@ -1,10 +1,10 @@ "use strict"; const winston = require("winston"); -const util = require() +const util = require(); class ConsoleTransport extends winston.transports.File { log(...args) { - super.log(util.format(...args), args[args.length -1]); + super.log(util.format(...args), args[args.length - 1]); } } module.exports = ConsoleTransport; diff --git a/package.json b/package.json index f214ab2..7692934 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,10 @@ ], "version": "1.9.1", "scripts": { - "test": "node_modules/.bin/mocha", - "posttest": "eslint --cache ." + "test": "mocha --exit && eslint . --cache && depcheck --ignores=\"prettier\"", + "posttest": "eslint --cache .", + "lint": "eslint --cache .", + "format": "prettier **/*.js --write && eslint . --fix" }, "repository": "https://github.com/BonnierNews/lu-logger.git", "keywords": [ @@ -28,6 +30,7 @@ }, "devDependencies": { "chai": "^3.5.0", + "depcheck": "^0.6.11", "eslint": "^4.19.1", "intercept-stdout": "^0.1.2", "mocha": "^5.2.0", diff --git a/test/logger-test.js b/test/logger-test.js index 5baa0f5..f0790e5 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -6,6 +6,10 @@ const transport = require("./helpers/test-transport"); const should = require("chai").should(); describe("logger", () => { + before(() => { + transport.logs = []; + }); + it("should log", () => { logger.info("foobar"); const log = transport.logs.shift(); diff --git a/yarn.lock b/yarn.lock index 8524930..036a56b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -81,7 +81,7 @@ async@^2.6.0: dependencies: lodash "^4.14.0" -babel-code-frame@^6.22.0: +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -89,6 +89,51 @@ babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.2" +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-traverse@^6.7.3: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.1.21, babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -117,6 +162,11 @@ buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" +builtin-modules@^1.0.0, builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -127,6 +177,11 @@ callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + chai@^3.5.0: version "3.5.0" resolved "http://registry.npmjs.org/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" @@ -171,10 +226,24 @@ cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -235,11 +304,16 @@ concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" +core-js@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944" + integrity sha512-NdBPF/RVwPW6jr0NCILuyN9RiqLo2b1mddWHkUL+VnvcB7dzlnBJ1bXYntjpTGOgkZiiLWj2JxmOr7eGE3qK6g== + core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -cross-spawn@^5.1.0: +cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: @@ -257,12 +331,24 @@ debug@3.1.0: dependencies: ms "2.0.0" +debug@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" dependencies: ms "^2.1.1" +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + deep-eql@^0.1.3: version "0.1.3" resolved "http://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" @@ -285,6 +371,33 @@ del@^2.0.2: pinkie-promise "^2.0.0" rimraf "^2.2.8" +depcheck@^0.6.11: + version "0.6.11" + resolved "https://registry.yarnpkg.com/depcheck/-/depcheck-0.6.11.tgz#6b616f2cf8c44ddcfdc5d7c7f7759bc53b479262" + integrity sha512-wTVJ8cNilB8NfkzoBblcYqsB8LRfbjqKEwAOLD3YXIRigktSM7/lS9xQfVkAVujhjstmiQMZR0hkdHSnQxzb9A== + dependencies: + babel-traverse "^6.7.3" + babylon "^6.1.21" + builtin-modules "^1.1.1" + deprecate "^1.0.0" + deps-regex "^0.1.4" + js-yaml "^3.4.2" + lodash "^4.5.1" + minimatch "^3.0.2" + require-package-name "^2.0.1" + walkdir "0.0.11" + yargs "^8.0.2" + +deprecate@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/deprecate/-/deprecate-1.1.0.tgz#bbd069d62b232175b4e8459b2650cd2bad51f4b8" + integrity sha512-b5dDNQYdy2vW9WXUD8+RQlfoxvqztLLhDE+T7Gd37I5E8My7nJkKu6FmhdDeRWJ8B+yjZKuwjCta8pgi8kgSqA== + +deps-regex@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deps-regex/-/deps-regex-0.1.4.tgz#518667b7691460a5e7e0a341be76eb7ce8090184" + integrity sha1-UYZnt2kUYKXn4KNBvnbrfOgJAYQ= + diagnostics@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" @@ -318,6 +431,13 @@ env-variable@0.0.x: version "0.0.4" resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.4.tgz#0d6280cf507d84242befe35a512b5ae4be77c54e" +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -407,6 +527,19 @@ esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + exp-config@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/exp-config/-/exp-config-2.0.1.tgz#68d844b9f98601e652d7390a9df45aee925ca55f" @@ -456,6 +589,13 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + flat-cache@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" @@ -473,6 +613,16 @@ functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + glob@7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" @@ -499,6 +649,11 @@ globals@^11.0.1: version "11.8.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.8.0.tgz#c1ef45ee9bed6badf0663c5cb90e8d1adec1321d" +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + globby@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" @@ -536,6 +691,11 @@ he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + iconv-lite@^0.4.17: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -586,11 +746,42 @@ intercept-stdout@^0.1.2: dependencies: lodash.toarray "^3.0.0" +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + is-arrayish@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= + dependencies: + builtin-modules "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -631,10 +822,23 @@ isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" +js-yaml@^3.4.2: + version "3.12.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" + integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@^3.9.1: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" @@ -657,6 +861,13 @@ kuler@1.0.x: dependencies: colornames "^1.1.1" +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -664,6 +875,24 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + lodash._arraycopy@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" @@ -708,7 +937,7 @@ lodash@^4.14.0: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" -lodash@^4.17.4, lodash@^4.3.0: +lodash@^4.17.4, lodash@^4.3.0, lodash@^4.5.1: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -723,6 +952,13 @@ logform@^1.9.1: ms "^2.1.1" triple-beam "^1.2.0" +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + lru-cache@^4.0.1: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" @@ -730,6 +966,13 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= + dependencies: + mimic-fn "^1.0.0" + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -791,6 +1034,28 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +normalize-package-data@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + object-assign@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -822,10 +1087,55 @@ optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -834,6 +1144,18 @@ path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + pify@^2.0.0: version "2.3.0" resolved "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -874,6 +1196,23 @@ pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + readable-stream@^2.2.2, readable-stream@^2.3.6: version "2.3.6" resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -886,10 +1225,30 @@ readable-stream@^2.2.2, readable-stream@^2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + regexpp@^1.0.1: version "1.1.0" resolved "http://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-package-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9" + integrity sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk= + require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" @@ -938,10 +1297,15 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" -semver@^5.3.0: +"semver@2 || 3 || 4 || 5", semver@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -952,7 +1316,7 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" -signal-exit@^3.0.2: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -969,6 +1333,32 @@ slice-ansi@1.0.0: dependencies: is-fullwidth-code-point "^2.0.0" +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" + integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -977,7 +1367,16 @@ stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" -string-width@^2.1.0, string-width@^2.1.1: +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: @@ -990,7 +1389,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0: +strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" dependencies: @@ -1002,6 +1401,16 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -1058,6 +1467,11 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + triple-beam@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.2.0.tgz#8b5c1f3d491229bf6ddcf721c0ba84cef5ab51fa" @@ -1097,6 +1511,24 @@ util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +walkdir@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.11.tgz#a16d025eb931bd03b52f308caed0f40fcebe9532" + integrity sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -1143,6 +1575,14 @@ wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -1153,6 +1593,37 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= + dependencies: + camelcase "^4.1.0" + +yargs@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" + integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A= + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0" From 18ea8d208af5b99e881d594ccbb29895e1005f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 15:25:48 +0100 Subject: [PATCH 13/22] Prettier --- config/levels.js | 3 +- lib/get-event-name.js | 7 ++-- lib/logger.js | 66 +++++++++++++++++++++++++------------- lib/prom-transport.js | 3 +- lib/truncate-utf8-bytes.js | 6 ++-- package.json | 5 +-- test/log-messages-test.js | 1 - test/logger-test.js | 20 ++++++++---- yarn.lock | 5 +++ 9 files changed, 77 insertions(+), 39 deletions(-) diff --git a/config/levels.js b/config/levels.js index 2161a04..3d5688d 100644 --- a/config/levels.js +++ b/config/levels.js @@ -12,7 +12,7 @@ const levels = { }; const aliases = { emergency: "emerg", - critical: "crit", + critical: "crit" }; const colors = { @@ -31,4 +31,3 @@ module.exports = { aliases, colors }; - diff --git a/lib/get-event-name.js b/lib/get-event-name.js index 2445bc0..880256f 100644 --- a/lib/get-event-name.js +++ b/lib/get-event-name.js @@ -1,8 +1,11 @@ "use strict"; function getEventName(logObject) { - const routingKey = logObject && logObject.meta ? logObject.meta.routingKey : ""; - return routingKey && (routingKey.match(/\./g) || []).length > 1 ? routingKey.split(".")[1] : ""; + const routingKey = + logObject && logObject.meta ? logObject.meta.routingKey : ""; + return routingKey && (routingKey.match(/\./g) || []).length > 1 + ? routingKey.split(".")[1] + : ""; } module.exports = getEventName; diff --git a/lib/logger.js b/lib/logger.js index f24fa7f..93087b5 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -18,7 +18,10 @@ const logLevels = { debug: 7 }; -const invertedLevels = Object.assign({}, ...Object.entries(logLevels).map(([a, b]) => ({[b]: a}))); +const invertedLevels = Object.assign( + {}, + ...Object.entries(logLevels).map(([a, b]) => ({[b]: a})) +); function init(config) { if (!config) { @@ -26,7 +29,9 @@ function init(config) { } const callingAppName = require(`${process.cwd()}/package.json`).name; - const callingAppMetricName = !callingAppName ? "undefined" : callingAppName.replace(/-/g, ""); + const callingAppMetricName = !callingAppName + ? "undefined" + : callingAppName.replace(/-/g, ""); const logCounterName = `${callingAppMetricName}_logged_total`; @@ -41,37 +46,52 @@ function init(config) { } const logLevel = config.logLevel || "info"; - const logJson = (config.logJson === undefined) ? true : config.logJson; + const logJson = config.logJson === undefined ? true : config.logJson; const root = path.resolve(__dirname.split("node_modules")[0]); - const fileName = path.join(root, "logs", `${process.env.NODE_ENV || "development"}.log`); + const fileName = path.join( + root, + "logs", + `${process.env.NODE_ENV || "development"}.log` + ); const transports = []; if (config.log === "file") { - transports.push(new winston.transports.File({ - filename: fileName, - json: logJson, - stringify: stringifier(logJson) - })); + transports.push( + new winston.transports.File({ + filename: fileName, + json: logJson, + stringify: stringifier(logJson) + }) + ); } if (config.log === "stdout") { - transports.push(new winston.transports.Console({ - colorize: false, - timestamp: true, - json: logJson, - stringify: stringifier(logJson) - })); + transports.push( + new winston.transports.Console({ + colorize: false, + timestamp: true, + json: logJson, + stringify: stringifier(logJson) + }) + ); } if (config.sysLogOpts) { - transports.push(new winston.transports.Syslog(Object.assign({ - localhost: process.env.HOSTNAME, - app_name: callingAppName, // eslint-disable-line camelcase - eol: "\n", - json: logJson, - stringify: stringifier(logJson) - }, config.sysLogOpts))); + transports.push( + new winston.transports.Syslog( + Object.assign( + { + localhost: process.env.HOSTNAME, + app_name: callingAppName, // eslint-disable-line camelcase + eol: "\n", + json: logJson, + stringify: stringifier(logJson) + }, + config.sysLogOpts + ) + ) + ); } const logger = new winston.Logger({ @@ -142,7 +162,7 @@ function init(config) { debug: (label, logObject) => { logger.debug(label, prepLogObject(logLevels.debug, logObject)); logCounter.inc({level: "debug"}); - }, + } }; } diff --git a/lib/prom-transport.js b/lib/prom-transport.js index bcb3c25..e034085 100644 --- a/lib/prom-transport.js +++ b/lib/prom-transport.js @@ -9,7 +9,8 @@ class PromTransport extends Transport { constructor(opts) { super(opts); this.name = "prom-transport"; - const callingAppMetricName = callingAppName && callingAppName.replace(/-/g, ""); + const callingAppMetricName = + callingAppName && callingAppName.replace(/-/g, ""); const logCounterName = `${callingAppMetricName}_logged_total`; this.logCounter = prometheusClient.register.getSingleMetric(logCounterName); diff --git a/lib/truncate-utf8-bytes.js b/lib/truncate-utf8-bytes.js index 7b8cd73..ba5c72b 100644 --- a/lib/truncate-utf8-bytes.js +++ b/lib/truncate-utf8-bytes.js @@ -1,7 +1,6 @@ "use strict"; // stolen from: https://raw.githubusercontent.com/parshap/truncate-utf8-bytes/master/lib/truncate.js - function isHighSurrogate(codePoint) { return codePoint >= 0xd800 && codePoint <= 0xdbff; } @@ -27,7 +26,10 @@ module.exports = function truncate(string, byteLength) { codePoint = string.charCodeAt(i); segment = string[i]; - if (isHighSurrogate(codePoint) && isLowSurrogate(string.charCodeAt(i + 1))) { + if ( + isHighSurrogate(codePoint) && + isLowSurrogate(string.charCodeAt(i + 1)) + ) { i += 1; segment += string[i]; } diff --git a/package.json b/package.json index 7692934..599c9d4 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "Ivan Malmberg", "Markus Ekholm" ], - "version": "1.9.1", + "version": "2.0.0", "scripts": { "test": "mocha --exit && eslint . --cache && depcheck --ignores=\"prettier\"", "posttest": "eslint --cache .", @@ -34,6 +34,7 @@ "eslint": "^4.19.1", "intercept-stdout": "^0.1.2", "mocha": "^5.2.0", - "mocha-cakes-2": "^2.0.1" + "mocha-cakes-2": "^2.0.1", + "prettier": "^1.15.3" } } diff --git a/test/log-messages-test.js b/test/log-messages-test.js index e93c00b..d99c5b7 100644 --- a/test/log-messages-test.js +++ b/test/log-messages-test.js @@ -39,7 +39,6 @@ // log[log.length - 4].metaData.shoud.eql(data); // }); - // it("should log a message", () => { // log[log.length - 3].message.should.eql("some message"); // log[log.length - 3].metaData.shoud.eql(data); diff --git a/test/logger-test.js b/test/logger-test.js index f0790e5..8137eea 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -18,17 +18,17 @@ describe("logger", () => { }); it("should log with meta", () => { - logger.info("some message", {"some": "info"}); + logger.info("some message", {some: "info"}); const log = transport.logs.shift(); log.should.include({level: "info", message: "some message"}); - log.metaData.should.eql({"some": "info"}); + log.metaData.should.eql({some: "info"}); }); it("should log splat multiple arguments with meta", () => { - logger.info("one", "two", "three", "four", {"some": "info"}); + logger.info("one", "two", "three", "four", {some: "info"}); const log = transport.logs.shift(); log.should.include({level: "info", message: "one two three four"}); - log.metaData.should.eql({"some": "info"}); + log.metaData.should.eql({some: "info"}); }); it("should log splat multiple arguments without meta", () => { @@ -39,9 +39,17 @@ describe("logger", () => { }); it("should log splat multiple objects with meta", () => { - logger.info("one", "two", {three: 3, four: 4}, {"correlationId": "coobar"}); + logger.info( + "one", + "two", + {three: 3, four: 4}, + {correlationId: "coobar"} + ); const log = transport.logs.shift(); - log.should.include({level: "info", message: "one two { three: 3, four: 4 }"}); + log.should.include({ + level: "info", + message: "one two { three: 3, four: 4 }" + }); log.metaData.should.eql({correlationId: "coobar"}); }); diff --git a/yarn.lock b/yarn.lock index 036a56b..20aa4b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1178,6 +1178,11 @@ prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" +prettier@^1.15.3: + version "1.15.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" + integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg== + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" From 04cf6ed3ddb2fe985eb2590cfbf788ff0ffa2f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 15:26:37 +0100 Subject: [PATCH 14/22] No more capture output --- package.json | 1 - yarn.lock | 42 ------------------------------------------ 2 files changed, 43 deletions(-) diff --git a/package.json b/package.json index 599c9d4..f93900b 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "chai": "^3.5.0", "depcheck": "^0.6.11", "eslint": "^4.19.1", - "intercept-stdout": "^0.1.2", "mocha": "^5.2.0", "mocha-cakes-2": "^2.0.1", "prettier": "^1.15.3" diff --git a/yarn.lock b/yarn.lock index 20aa4b9..215dd10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -740,12 +740,6 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -intercept-stdout@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/intercept-stdout/-/intercept-stdout-0.1.2.tgz#126abf1fae6c509a428a98c61a631559042ae9fd" - dependencies: - lodash.toarray "^3.0.0" - invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -893,46 +887,10 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash._arraycopy@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" - -lodash._basevalues@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - lodash.merge@^4.6.0: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" -lodash.toarray@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-3.0.2.tgz#2b204f0fa4f51c285c6f00c81d1cea5a23041179" - dependencies: - lodash._arraycopy "^3.0.0" - lodash._basevalues "^3.0.0" - lodash.keys "^3.0.0" - lodash@^4.14.0: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" From 2b1047aeb39e1b83f885ef7fcf1675f4e550a410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 15:40:25 +0100 Subject: [PATCH 15/22] Autowrapping in meta --- index.js | 9 +++++++ test/feature/logging-feature.js | 44 --------------------------------- test/logger-test.js | 33 ++++++++++++++++++++++--- 3 files changed, 39 insertions(+), 47 deletions(-) diff --git a/index.js b/index.js index 72bb9eb..ceea562 100644 --- a/index.js +++ b/index.js @@ -32,6 +32,14 @@ function truncateTooLong(info) { return info; } +function metaDataFormat(info) { + const meta = info.metaData && info.metaData.meta; + if (!meta && Object.keys(info.metaData).length > 0) { + info.metaData = {meta: info.metaData}; + } + return info; +} + function createLogger() { const transports = [new PromTransport()]; @@ -72,6 +80,7 @@ function createLogger() { format(splatEntry)(), format(location)(), format(truncateTooLong)(), + format(metaDataFormat)(), formatter ) }); diff --git a/test/feature/logging-feature.js b/test/feature/logging-feature.js index f4e68fc..5eb619b 100644 --- a/test/feature/logging-feature.js +++ b/test/feature/logging-feature.js @@ -50,50 +50,6 @@ Feature("Logging", () => { }); }); - - Scenario("Logging error with JSON format", () => { - const message = "Message"; - const data = { - "meta": { - "createdAt": "2017-09-24-00:00T00:00:00.000Z", - "updatedAt": "2017-09-24-00:00T00:00:00.000Z", - "correlationId": "sample-correlation-id" - } - }; - - When("doing some JSON logging", () => { - logger.error(message, data); - }); - - Then("log output should be JSON", () => { - const logContent = transport.logs.shift(); - logContent.logLevel.should.equal("error"); - logContent.location.should.be.ok; // eslint-disable-line no-unused-expressions - logContent.metaData.should.deep.equal(data); - logContent.message.should.equal(message); - }); - }); - - Scenario("Logging with string format", () => { - const stdoutContents = ""; - const message = "Message"; - const data = { - "meta": { - "createdAt": "2017-09-24-00:00T00:00:00.000Z", - "updatedAt": "2017-09-24-00:00T00:00:00.000Z", - "correlationId": "sample-correlation-id" - } - }; - - When("initializing the logger and doing some string logging", () => { - logger.debug(message, data); - }); - - Then("log output should be string", () => { - stdoutContents.should.be.a("string"); - }); - }); - Scenario("Logging should inc metric", () => { const message = "Message"; diff --git a/test/logger-test.js b/test/logger-test.js index 8137eea..1fb2f3e 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -21,14 +21,14 @@ describe("logger", () => { logger.info("some message", {some: "info"}); const log = transport.logs.shift(); log.should.include({level: "info", message: "some message"}); - log.metaData.should.eql({some: "info"}); + log.metaData.should.eql({meta: {some: "info"}}); }); it("should log splat multiple arguments with meta", () => { logger.info("one", "two", "three", "four", {some: "info"}); const log = transport.logs.shift(); log.should.include({level: "info", message: "one two three four"}); - log.metaData.should.eql({some: "info"}); + log.metaData.should.eql({meta: {some: "info"}}); }); it("should log splat multiple arguments without meta", () => { @@ -50,7 +50,7 @@ describe("logger", () => { level: "info", message: "one two { three: 3, four: 4 }" }); - log.metaData.should.eql({correlationId: "coobar"}); + log.metaData.should.eql({meta: {correlationId: "coobar"}}); }); describe("levels", () => { @@ -82,4 +82,31 @@ describe("logger", () => { }); }); }); + + describe("metaData", () => { + it("should let metaDatas key be meta", () => { + const data = { + "meta": { + "createdAt": "2017-09-24-00:00T00:00:00.000Z", + "updatedAt": "2017-09-24-00:00T00:00:00.000Z", + "correlationId": "sample-correlation-id" + } + }; + logger.info("message", data); + const log = transport.logs.shift(); + log.metaData.should.eql(data); + }); + + it("should wrap metaData in meta in not the case", () => { + const data = { + "createdAt": "2017-09-24-00:00T00:00:00.000Z", + "updatedAt": "2017-09-24-00:00T00:00:00.000Z", + "correlationId": "sample-correlation-id" + }; + logger.info("message", data); + const log = transport.logs.shift(); + log.metaData.should.eql({meta: data}); + }); + + }); }); From 7ddc31eeb380dfc4d326b047197aec9022592694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 15:51:23 +0100 Subject: [PATCH 16/22] Fixed location --- lib/get-loc.js | 2 +- test/logger-test.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/get-loc.js b/lib/get-loc.js index 63c6f5e..df0f625 100644 --- a/lib/get-loc.js +++ b/lib/get-loc.js @@ -4,7 +4,7 @@ const path = require("path"); function getLoc() { const originalPrepareStackTrace = Error.prepareStackTrace; Error.prepareStackTrace = (_, stack) => stack; - const stack = new Error().stack[3]; + const stack = new Error().stack[10]; Error.prepareStackTrace = originalPrepareStackTrace; let calleePath; diff --git a/test/logger-test.js b/test/logger-test.js index 1fb2f3e..69c79a0 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -107,6 +107,11 @@ describe("logger", () => { const log = transport.logs.shift(); log.metaData.should.eql({meta: data}); }); + }); + describe("location", () => { + logger.info("message"); + const log = transport.logs.shift(); + log.location.should.eql("test/logger-test.js:113"); }); }); From e14b1c8f51e75cca25ff4d3e40fbf5b2fd0e9a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 16:14:05 +0100 Subject: [PATCH 17/22] Metadata work flow --- index.js | 16 ++++++--- lib/splat-entry.js | 4 +-- test/feature/logging-feature.js | 4 +++ test/log-messages-test.js | 63 --------------------------------- test/meta-data-test.js | 43 ++++++++++++++++++++++ 5 files changed, 61 insertions(+), 69 deletions(-) delete mode 100644 test/log-messages-test.js create mode 100644 test/meta-data-test.js diff --git a/index.js b/index.js index ceea562..57e5d4a 100644 --- a/index.js +++ b/index.js @@ -40,7 +40,14 @@ function metaDataFormat(info) { return info; } -function createLogger() { +function metaDataFn(info, opts) { + if (opts.metaData) { + info.metaData = opts.metaData; + } + return info; +} + +function buildLogger(metaData) { const transports = [new PromTransport()]; const defaultFormatter = format.printf((info) => `${info.timestamp} - ${info.level}: ${info.message}`); @@ -75,9 +82,10 @@ function createLogger() { transports: transports, format: format.combine( format.metadata({key: "metaData"}), + format(metaDataFn)({metaData}), format.timestamp(), format(logLevel)(), - format(splatEntry)(), + format(splatEntry)({metaData}), format(location)(), format(truncateTooLong)(), format(metaDataFormat)(), @@ -89,6 +97,6 @@ function createLogger() { } module.exports = { - logger: createLogger(), - createLogger + logger: buildLogger(), + buildLogger }; diff --git a/lib/splat-entry.js b/lib/splat-entry.js index 062703e..aa54e7c 100644 --- a/lib/splat-entry.js +++ b/lib/splat-entry.js @@ -2,14 +2,14 @@ const util = require("util"); const config = require("exp-config").logging; -function splatEntry(info) { +function splatEntry(info, opts) { const splat = info[Symbol.for("splat")]; if (!splat || splat.length === 1) { return info; } const message = [...splat]; - if (typeof message[message.length - 1] === "object") { + if (!opts.metaData && typeof message[message.length - 1] === "object") { info.metaData = message.pop(); } diff --git a/test/feature/logging-feature.js b/test/feature/logging-feature.js index 5eb619b..378f5fc 100644 --- a/test/feature/logging-feature.js +++ b/test/feature/logging-feature.js @@ -5,6 +5,10 @@ const transport = require("../helpers/test-transport"); const prometheusClient = require("prom-client"); Feature("Logging", () => { + before(() => { + transport.logs = []; + }); + Scenario("Logging debug with JSON format", () => { const message = "Message"; const data = { diff --git a/test/log-messages-test.js b/test/log-messages-test.js deleted file mode 100644 index d99c5b7..0000000 --- a/test/log-messages-test.js +++ /dev/null @@ -1,63 +0,0 @@ -// "use strict"; - -// const path = require("path"); -// const fs = require("fs"); -// const createLogger = require("../lib/logger"); -// const fileName = path.join(__dirname, "..", "logs", "test.log"); -// const logger = createLogger({ -// log: "file", -// logLevel: "debug", -// logJson: true, -// truncateLog: true -// }); - -// describe("logging a message", () => { -// const data = { -// "meta": { -// "createdAt": "2017-09-24-00:00T00:00:00.000Z", -// "updatedAt": "2017-09-24-00:00T00:00:00.000Z", -// "correlationId": "sample-correlation-id" -// } -// }; - -// const log = []; - -// before(() => { -// logger.winstone.on("logged", (args) => { -// console.log("logged", args); -// }); - -// logger(data).debug("some message"); -// logger.info("some message", data); -// logger.info("some message"); -// logger("sample-correlation-id").info("some message"); -// log.push(...readLog()); -// }); - -// it("should log a message with metaData", () => { -// log[log.length - 4].message.should.eql("some message"); -// log[log.length - 4].metaData.shoud.eql(data); -// }); - -// it("should log a message", () => { -// log[log.length - 3].message.should.eql("some message"); -// log[log.length - 3].metaData.shoud.eql(data); -// }); - -// it("should not log meta if not given", () => { -// log[log.length - 2].message.should.eql("some message"); -// log[log.length - 2].metaData.should.eql({}); -// }); - -// it("should log correlationId if given as first argument", () => { -// log[log.length - 1].message.should.eql("some message"); -// log[log.length - 1].metaData.meta.correlationId.should.eql("sample-correlation-id"); -// }); -// }); - -// function readLog() { -// return fs.readFileSync(fileName, {"encoding": "utf-8"}) -// .trim() -// .split("\n") -// .map(JSON.parse); -// } diff --git a/test/meta-data-test.js b/test/meta-data-test.js new file mode 100644 index 0000000..96f343d --- /dev/null +++ b/test/meta-data-test.js @@ -0,0 +1,43 @@ +"use strict"; + +const {buildLogger} = require("../"); +const transport = require("./helpers/test-transport"); + +describe("logging messages with default metaData", () => { + const data = { + "meta": { + "correlationId": "sample-correlation-id", + "eventName": "someEvent" + } + }; + before(() => { + transport.logs = []; + }); + + it("should log a message with metaData", () => { + const logger = buildLogger(data); + logger.add(transport); + logger.info("some message"); + const log = transport.logs.shift(); + log.message.should.eql("some message"); + log.metaData.should.eql(data); + }); + + it("should log a message with metaData and splat", () => { + const logger = buildLogger(data); + logger.add(transport); + logger.info("some message", "one", {"true": false}); + const log = transport.logs.shift(); + log.message.should.eql("some message one { true: false }"); + log.metaData.should.eql(data); + }); + + it("should not log metaData if not given", () => { + const logger = buildLogger(); + logger.add(transport); + logger.info("some message"); + const log = transport.logs.shift(); + log.message.should.eql("some message"); + log.metaData.should.eql({}); + }); +}); From 1a69567c97a041aaa8528e15e92bfc549b15e846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 16:52:30 +0100 Subject: [PATCH 18/22] Fixed location (kinda) --- index.js | 13 +++++++---- lib/get-loc.js | 37 +++++++++++++++++++++++++++--- lib/truncate-utf8-bytes.js | 47 -------------------------------------- test/meta-data-test.js | 10 ++++++++ 4 files changed, 52 insertions(+), 55 deletions(-) delete mode 100644 lib/truncate-utf8-bytes.js diff --git a/index.js b/index.js index 57e5d4a..96fb885 100644 --- a/index.js +++ b/index.js @@ -7,8 +7,7 @@ const path = require("path"); const callingAppName = require(`${process.cwd()}/package.json`).name; const splatEntry = require("./lib/splat-entry"); const logLevels = require("./config/levels"); -const getLoc = require("./lib/get-loc"); -// const truncate = require("./lib/truncate-utf8-bytes"); +const {getLoc, caller} = require("./lib/get-loc"); require("winston-syslog").Syslog; // eslint-disable-line no-unused-expressions @@ -20,8 +19,12 @@ function logLevel(info) { return info; } -function location(info) { - info.location = getLoc(); +function location(info, opts) { + if (opts.caller !== __filename) { + info.location = getLoc(11); + } else { + info.location = getLoc(); + } return info; } @@ -86,7 +89,7 @@ function buildLogger(metaData) { format.timestamp(), format(logLevel)(), format(splatEntry)({metaData}), - format(location)(), + format(location)({caller: caller()}), format(truncateTooLong)(), format(metaDataFormat)(), formatter diff --git a/lib/get-loc.js b/lib/get-loc.js index df0f625..92dfac4 100644 --- a/lib/get-loc.js +++ b/lib/get-loc.js @@ -1,10 +1,10 @@ "use strict"; const path = require("path"); -function getLoc() { +function getLoc(stackLevel = 10) { const originalPrepareStackTrace = Error.prepareStackTrace; Error.prepareStackTrace = (_, stack) => stack; - const stack = new Error().stack[10]; + const stack = new Error().stack[stackLevel]; Error.prepareStackTrace = originalPrepareStackTrace; let calleePath; @@ -17,4 +17,35 @@ function getLoc() { return `${calleePath}:${stack.getLineNumber()}`; } -module.exports = getLoc; +/** + * Module wrapper of @substack's `caller.js` (stolen from https://github.com/totherik/caller/blob/master/index.js) + * @original: https://github.com/substack/node-resolve/blob/master/lib/caller.js + * @blessings: https://twitter.com/eriktoth/statuses/413719312273125377 + * @see https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi + */ +function caller(depth) { + let stack, file, frame; + + const pst = Error.prepareStackTrace; + Error.prepareStackTrace = function (_, innerStack) { + Error.prepareStackTrace = pst; + return innerStack; + }; + + stack = (new Error()).stack; + depth = !depth || isNaN(depth) ? 1 : (depth > stack.length - 2 ? stack.length - 2 : depth); + stack = stack.slice(depth + 1); + + do { + frame = stack.shift(); + file = frame && frame.getFileName(); + } while (stack.length && file === "module.js"); + + return file; +} + + +module.exports = { + getLoc, + caller +}; diff --git a/lib/truncate-utf8-bytes.js b/lib/truncate-utf8-bytes.js deleted file mode 100644 index ba5c72b..0000000 --- a/lib/truncate-utf8-bytes.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; -// stolen from: https://raw.githubusercontent.com/parshap/truncate-utf8-bytes/master/lib/truncate.js - -function isHighSurrogate(codePoint) { - return codePoint >= 0xd800 && codePoint <= 0xdbff; -} - -function isLowSurrogate(codePoint) { - return codePoint >= 0xdc00 && codePoint <= 0xdfff; -} - -const getLength = Buffer.byteLength.bind(Buffer); - -// Truncate string by size in bytes -module.exports = function truncate(string, byteLength) { - if (typeof string !== "string") { - throw new Error("Input must be string"); - } - - const charLength = string.length; - let curByteLength = 0; - let codePoint; - let segment; - - for (let i = 0; i < charLength; i += 1) { - codePoint = string.charCodeAt(i); - segment = string[i]; - - if ( - isHighSurrogate(codePoint) && - isLowSurrogate(string.charCodeAt(i + 1)) - ) { - i += 1; - segment += string[i]; - } - - curByteLength += getLength(segment); - - if (curByteLength === byteLength) { - return string.slice(0, i + 1); - } else if (curByteLength > byteLength) { - return string.slice(0, i - segment.length + 1); - } - } - - return string; -}; diff --git a/test/meta-data-test.js b/test/meta-data-test.js index 96f343d..78b66ad 100644 --- a/test/meta-data-test.js +++ b/test/meta-data-test.js @@ -40,4 +40,14 @@ describe("logging messages with default metaData", () => { log.message.should.eql("some message"); log.metaData.should.eql({}); }); + + it("should get correct location", () => { + const logger = buildLogger(data); + logger.add(transport); + logger.info("some message", "one", {"true": false}); + const log = transport.logs.shift(); + log.message.should.eql("some message one { true: false }"); + log.location.should.eql("test/meta-data-test.js:47"); + }); + }); From b35cc6a078f64281f9045c2237d2cfa166ebbe4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 16:57:29 +0100 Subject: [PATCH 19/22] No more logger --- lib/logger.js | 202 -------------------------------------------------- 1 file changed, 202 deletions(-) delete mode 100644 lib/logger.js diff --git a/lib/logger.js b/lib/logger.js deleted file mode 100644 index 93087b5..0000000 --- a/lib/logger.js +++ /dev/null @@ -1,202 +0,0 @@ -"use strict"; - -const path = require("path"); -const winston = require("winston"); -/* eslint-disable no-unused-expressions */ -require("winston-syslog").Syslog; -const prometheusClient = require("prom-client"); -const getEventName = require("./get-event-name"); - -const logLevels = { - emerg: 0, - alert: 1, - crit: 2, - error: 3, - warning: 4, - notice: 5, - info: 6, - debug: 7 -}; - -const invertedLevels = Object.assign( - {}, - ...Object.entries(logLevels).map(([a, b]) => ({[b]: a})) -); - -function init(config) { - if (!config) { - throw new Error("Error initializing logger, configuration object missing"); - } - - const callingAppName = require(`${process.cwd()}/package.json`).name; - const callingAppMetricName = !callingAppName - ? "undefined" - : callingAppName.replace(/-/g, ""); - - const logCounterName = `${callingAppMetricName}_logged_total`; - - let logCounter = prometheusClient.register.getSingleMetric(logCounterName); - - if (!logCounter) { - logCounter = new prometheusClient.Counter({ - name: logCounterName, - help: "Counts number of logs with loglevel as label", - labelNames: ["level", "eventName"] - }); - } - - const logLevel = config.logLevel || "info"; - const logJson = config.logJson === undefined ? true : config.logJson; - - const root = path.resolve(__dirname.split("node_modules")[0]); - const fileName = path.join( - root, - "logs", - `${process.env.NODE_ENV || "development"}.log` - ); - - const transports = []; - if (config.log === "file") { - transports.push( - new winston.transports.File({ - filename: fileName, - json: logJson, - stringify: stringifier(logJson) - }) - ); - } - - if (config.log === "stdout") { - transports.push( - new winston.transports.Console({ - colorize: false, - timestamp: true, - json: logJson, - stringify: stringifier(logJson) - }) - ); - } - - if (config.sysLogOpts) { - transports.push( - new winston.transports.Syslog( - Object.assign( - { - localhost: process.env.HOSTNAME, - app_name: callingAppName, // eslint-disable-line camelcase - eol: "\n", - json: logJson, - stringify: stringifier(logJson) - }, - config.sysLogOpts - ) - ) - ); - } - - const logger = new winston.Logger({ - levels: logLevels, - level: logLevel, - transports: transports - }); - - function prepLogObject(level, logObject) { - if (!logObject) { - logObject = {}; - } else { - logObject = JSON.parse(JSON.stringify(logObject)); - } - - const logData = {metaData: logObject}; - - if (level === logLevels.debug || level <= logLevels.error) { - logData.location = getLoc(); - } - - logData.logLevel = invertedLevels[level]; - - return logData; - } - - return { - emergency: (label, logObject) => { - logger.emerg(label, prepLogObject(logLevels.emerg, logObject)); - logCounter.inc({level: "emergency"}); - }, - - alert: (label, logObject) => { - logger.alert(label, prepLogObject(logLevels.alert, logObject)); - logCounter.inc({level: "alert"}); - }, - - critical: (label, logObject) => { - logger.crit(label, prepLogObject(logLevels.crit, logObject)); - logCounter.inc({level: "crit"}); - }, - - error: (label, logObject) => { - const metricLabels = {level: "error"}; - const eventName = getEventName(logObject); - if (eventName) { - metricLabels.eventName = eventName; - } - logger.error(label, prepLogObject(logLevels.error, logObject)); - logCounter.inc(metricLabels); - }, - - warning: (label, logObject) => { - logger.warning(label, prepLogObject(logLevels.warning, logObject)); - logCounter.inc({level: "warning"}); - }, - - notice: (label, logObject) => { - logger.notice(label, prepLogObject(logLevels.notice, logObject)); - logCounter.inc({level: "notice"}); - }, - - info: (label, logObject) => { - logger.info(label, prepLogObject(logLevels.info, logObject)); - logCounter.inc({level: "info"}); - }, - - debug: (label, logObject) => { - logger.debug(label, prepLogObject(logLevels.debug, logObject)); - logCounter.inc({level: "debug"}); - } - }; -} - -function stringifier(logJson) { - return (obj) => { - if (logJson) { - if (Buffer.byteLength(obj.message, "utf8") > 60 * 1024) { - obj.message = "too big to log"; - } - return JSON.stringify(obj); - } else { - let msg = obj.split("\n").join(" "); - if (Buffer.byteLength(msg, "utf8") > 60 * 1024) { - msg = "too big to log"; - } - return msg; - } - }; -} - -function getLoc() { - const originalPrepareStackTrace = Error.prepareStackTrace; - Error.prepareStackTrace = (_, stack) => stack; - const stack = new Error().stack[3]; - Error.prepareStackTrace = originalPrepareStackTrace; - - let calleePath; - if (global.__basePath) { - calleePath = path.relative(global.__basePath, stack.getFileName()); - } else { - calleePath = stack.getFileName(); - } - - return `${calleePath}:${stack.getLineNumber()}`; -} - -module.exports = init; From c1bb3aa930ed5f366ea443e47484c0929261da95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Thu, 17 Jan 2019 16:57:44 +0100 Subject: [PATCH 20/22] Format --- lib/get-loc.js | 10 +++++++--- test/logger-test.js | 14 +++++++------- test/meta-data-test.js | 11 +++++------ 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/lib/get-loc.js b/lib/get-loc.js index 92dfac4..ee0f4f7 100644 --- a/lib/get-loc.js +++ b/lib/get-loc.js @@ -32,8 +32,13 @@ function caller(depth) { return innerStack; }; - stack = (new Error()).stack; - depth = !depth || isNaN(depth) ? 1 : (depth > stack.length - 2 ? stack.length - 2 : depth); + stack = new Error().stack; + depth = + !depth || isNaN(depth) + ? 1 + : depth > stack.length - 2 + ? stack.length - 2 + : depth; stack = stack.slice(depth + 1); do { @@ -44,7 +49,6 @@ function caller(depth) { return file; } - module.exports = { getLoc, caller diff --git a/test/logger-test.js b/test/logger-test.js index 69c79a0..dabd261 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -86,10 +86,10 @@ describe("logger", () => { describe("metaData", () => { it("should let metaDatas key be meta", () => { const data = { - "meta": { - "createdAt": "2017-09-24-00:00T00:00:00.000Z", - "updatedAt": "2017-09-24-00:00T00:00:00.000Z", - "correlationId": "sample-correlation-id" + meta: { + createdAt: "2017-09-24-00:00T00:00:00.000Z", + updatedAt: "2017-09-24-00:00T00:00:00.000Z", + correlationId: "sample-correlation-id" } }; logger.info("message", data); @@ -99,9 +99,9 @@ describe("logger", () => { it("should wrap metaData in meta in not the case", () => { const data = { - "createdAt": "2017-09-24-00:00T00:00:00.000Z", - "updatedAt": "2017-09-24-00:00T00:00:00.000Z", - "correlationId": "sample-correlation-id" + createdAt: "2017-09-24-00:00T00:00:00.000Z", + updatedAt: "2017-09-24-00:00T00:00:00.000Z", + correlationId: "sample-correlation-id" }; logger.info("message", data); const log = transport.logs.shift(); diff --git a/test/meta-data-test.js b/test/meta-data-test.js index 78b66ad..a4073ce 100644 --- a/test/meta-data-test.js +++ b/test/meta-data-test.js @@ -5,9 +5,9 @@ const transport = require("./helpers/test-transport"); describe("logging messages with default metaData", () => { const data = { - "meta": { - "correlationId": "sample-correlation-id", - "eventName": "someEvent" + meta: { + correlationId: "sample-correlation-id", + eventName: "someEvent" } }; before(() => { @@ -26,7 +26,7 @@ describe("logging messages with default metaData", () => { it("should log a message with metaData and splat", () => { const logger = buildLogger(data); logger.add(transport); - logger.info("some message", "one", {"true": false}); + logger.info("some message", "one", {true: false}); const log = transport.logs.shift(); log.message.should.eql("some message one { true: false }"); log.metaData.should.eql(data); @@ -44,10 +44,9 @@ describe("logging messages with default metaData", () => { it("should get correct location", () => { const logger = buildLogger(data); logger.add(transport); - logger.info("some message", "one", {"true": false}); + logger.info("some message", "one", {true: false}); const log = transport.logs.shift(); log.message.should.eql("some message one { true: false }"); log.location.should.eql("test/meta-data-test.js:47"); }); - }); From c3f9bacc028e0e5e1d82eadef21f6ed645f550df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Mon, 21 Jan 2019 07:52:37 +0100 Subject: [PATCH 21/22] Prettier --- .prettierrc | 5 +++++ lib/get-event-name.js | 7 ++----- lib/get-loc.js | 7 +------ lib/prom-transport.js | 3 +-- test/logger-test.js | 7 +------ 5 files changed, 10 insertions(+), 19 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..1cbcaf6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "bracketSpacing": false, + "printWidth": 120, + "arrowParens": "always" +} diff --git a/lib/get-event-name.js b/lib/get-event-name.js index 880256f..2445bc0 100644 --- a/lib/get-event-name.js +++ b/lib/get-event-name.js @@ -1,11 +1,8 @@ "use strict"; function getEventName(logObject) { - const routingKey = - logObject && logObject.meta ? logObject.meta.routingKey : ""; - return routingKey && (routingKey.match(/\./g) || []).length > 1 - ? routingKey.split(".")[1] - : ""; + const routingKey = logObject && logObject.meta ? logObject.meta.routingKey : ""; + return routingKey && (routingKey.match(/\./g) || []).length > 1 ? routingKey.split(".")[1] : ""; } module.exports = getEventName; diff --git a/lib/get-loc.js b/lib/get-loc.js index ee0f4f7..d0d73aa 100644 --- a/lib/get-loc.js +++ b/lib/get-loc.js @@ -33,12 +33,7 @@ function caller(depth) { }; stack = new Error().stack; - depth = - !depth || isNaN(depth) - ? 1 - : depth > stack.length - 2 - ? stack.length - 2 - : depth; + depth = !depth || isNaN(depth) ? 1 : depth > stack.length - 2 ? stack.length - 2 : depth; stack = stack.slice(depth + 1); do { diff --git a/lib/prom-transport.js b/lib/prom-transport.js index e034085..bcb3c25 100644 --- a/lib/prom-transport.js +++ b/lib/prom-transport.js @@ -9,8 +9,7 @@ class PromTransport extends Transport { constructor(opts) { super(opts); this.name = "prom-transport"; - const callingAppMetricName = - callingAppName && callingAppName.replace(/-/g, ""); + const callingAppMetricName = callingAppName && callingAppName.replace(/-/g, ""); const logCounterName = `${callingAppMetricName}_logged_total`; this.logCounter = prometheusClient.register.getSingleMetric(logCounterName); diff --git a/test/logger-test.js b/test/logger-test.js index dabd261..180edab 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -39,12 +39,7 @@ describe("logger", () => { }); it("should log splat multiple objects with meta", () => { - logger.info( - "one", - "two", - {three: 3, four: 4}, - {correlationId: "coobar"} - ); + logger.info("one", "two", {three: 3, four: 4}, {correlationId: "coobar"}); const log = transport.logs.shift(); log.should.include({ level: "info", From d79ee0e16751aa57c9b4913deb7a9cc82361acda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Carl=C3=A9n?= Date: Mon, 21 Jan 2019 07:54:28 +0100 Subject: [PATCH 22/22] Newer syslog --- package.json | 2 +- test/logger-test.js | 2 +- yarn.lock | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f93900b..d73f835 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "exp-config": "^2.0.1", "prom-client": "^10.2.2", "winston": "^3.1.0", - "winston-syslog": "^1.0.0", + "winston-syslog": "^2.0.0", "winston-transport": "^3.2.1" }, "devDependencies": { diff --git a/test/logger-test.js b/test/logger-test.js index 180edab..aab4bb5 100644 --- a/test/logger-test.js +++ b/test/logger-test.js @@ -107,6 +107,6 @@ describe("logger", () => { describe("location", () => { logger.info("message"); const log = transport.logs.shift(); - log.location.should.eql("test/logger-test.js:113"); + log.location.should.eql("test/logger-test.js:108"); }); }); diff --git a/yarn.lock b/yarn.lock index 215dd10..91c9779 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1498,9 +1498,10 @@ which@^1.2.9: dependencies: isexe "^2.0.0" -winston-syslog@^1.0.0: - version "1.2.6" - resolved "https://registry.yarnpkg.com/winston-syslog/-/winston-syslog-1.2.6.tgz#4e7990ed0a9f1932187ddd6ec9e038357980961f" +winston-syslog@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/winston-syslog/-/winston-syslog-2.0.0.tgz#e41330ecffe37c1971e5d1144eff9ace32d5ba2c" + integrity sha512-20915SaP9DzXoY9gcb9Efyj+mKz4marNKadryDfgF3BwV2eqloN9drFa71P/+28hW61foUiLfRPeeVauwuimzQ== dependencies: cycle "~1.0.3" glossy "0.x.x"