UNPKG

nativescript

Version:

Command-line interface for building NativeScript projects

204 lines • 7.89 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Logger = void 0; const log4js = require("log4js"); const util = require("util"); const readline = require("readline"); const stream = require("stream"); const marked_1 = require("marked"); const _ = require("lodash"); const decorators_1 = require("../decorators"); const cli_layout_1 = require("./layouts/cli-layout"); const constants_1 = require("../../constants"); const yok_1 = require("../yok"); const color_1 = require("../../color"); const marked_terminal_1 = require("marked-terminal"); class Logger { constructor($config) { this.$config = $config; this.log4jsLogger = null; this.passwordRegex = /(password=).*?(['&,]|$)|(password["']?\s*:\s*["']).*?(["'])/i; this.passwordReplacement = "$1$3*******$2$4"; this.defaultLogLevel = this.$config.DEBUG ? constants_1.LoggerLevel.TRACE : constants_1.LoggerLevel.INFO; } initialize(opts) { opts = opts || {}; const { appenderOptions: appenderOpts, level } = opts; const appender = { type: "console", layout: { type: "messagePassThrough", }, }; if (appenderOpts) { _.merge(appender, appenderOpts); } const appenders = { out: appender, }; const categories = { default: { appenders: ["out"], level: level || this.defaultLogLevel, }, }; log4js.configure({ appenders, categories }); this.log4jsLogger = log4js.getLogger(); if (level === constants_1.LoggerLevel.TRACE || level === constants_1.LoggerLevel.ALL) { this.warn(`The "${level}" log level might print some sensitive data like secrets or access tokens in request URLs. Be careful when you share this output.`, { wrapMessageWithBorders: true }); } } initializeCliLogger(opts) { log4js.addLayout("cli", cli_layout_1.layout); this.initialize({ appenderOptions: { type: constants_1.LoggerAppenders.cliAppender, layout: { type: "cli" }, }, level: opts.level || this.defaultLogLevel, }); } getLevel() { this.initialize(); return this.log4jsLogger.level.toString(); } fatal(...args) { this.logMessage(args, constants_1.LoggerLevel.FATAL); } error(...args) { args.push({ [constants_1.LoggerConfigData.useStderr]: true }); this.logMessage(args, constants_1.LoggerLevel.ERROR); } warn(...args) { this.logMessage(args, constants_1.LoggerLevel.WARN); } info(...args) { this.logMessage(args, constants_1.LoggerLevel.INFO); } debug(...args) { const encodedArgs = this.getPasswordEncodedArguments(args); this.logMessage(encodedArgs, constants_1.LoggerLevel.DEBUG); } trace(...args) { const encodedArgs = this.getPasswordEncodedArguments(args); this.logMessage(encodedArgs, constants_1.LoggerLevel.TRACE); } prepare(item) { if (typeof item === "undefined" || item === null) { return "[no content]"; } if (typeof item === "string") { return item; } // do not try to read streams, because they may not be rewindable if (item instanceof stream.Readable) { return "[ReadableStream]"; } // There's no point in printing buffers if (item instanceof Buffer) { return "[Buffer]"; } return JSON.stringify(item); } printMarkdown(...args) { const opts = { unescape: true, link: color_1.color.red, strong: color_1.color.green.bold, firstHeading: color_1.color.blue.bold, tableOptions: { chars: { mid: "", "left-mid": "", "mid-mid": "", "right-mid": "" }, style: { "padding-left": 1, "padding-right": 1, head: ["green", "bold"], border: ["grey"], compact: false, }, }, }; marked_1.marked.use((0, marked_terminal_1.markedTerminal)(opts)); const formattedMessage = marked_1.marked.parse(util.format.apply(null, args)); this.info(formattedMessage, { [constants_1.LoggerConfigData.skipNewLine]: true }); } isVerbose() { return log4js.levels.DEBUG.isGreaterThanOrEqualTo(this.getLevel()); } clearScreen() { const repeatCount = process.stdout.rows - 2; const blank = repeatCount > 0 ? "\n".repeat(repeatCount) : ""; console.log(blank); readline.cursorTo(process.stdout, 0, 0); readline.clearScreenDown(process.stdout); } logMessage(inputData, logMethod) { this.initialize(); const logOpts = this.getLogOptionsForMessage(inputData); const data = logOpts.data; delete logOpts.data; for (const prop in logOpts) { this.log4jsLogger.addContext(prop, logOpts[prop]); } this.log4jsLogger[logMethod.toLowerCase()].apply(this.log4jsLogger, data); for (const prop in logOpts) { this.log4jsLogger.removeContext(prop); } } getLogOptionsForMessage(data) { const loggerOptionKeys = _.keys(constants_1.LoggerConfigData); const dataToCheck = data.filter((el) => { // objects created with Object.create(null) do not have `hasOwnProperty` function if (!!el && typeof el === "object" && el.hasOwnProperty && typeof el.hasOwnProperty === "function") { for (const key of loggerOptionKeys) { if (el.hasOwnProperty(key)) { // include only the elements which have one of the keys we've specified as logger options return true; } } } return false; }); const result = { data: _.difference(data, dataToCheck), }; for (const element of dataToCheck) { if (loggerOptionKeys.length === 0) { break; } const remainingOpts = _.cloneDeep(loggerOptionKeys); for (const prop of remainingOpts) { const hasProp = element && element.hasOwnProperty(prop); if (hasProp) { loggerOptionKeys.splice(loggerOptionKeys.indexOf(prop), 1); result[prop] = element[prop]; } } } return result; } getPasswordEncodedArguments(args) { return _.map(args, (argument) => { if (typeof argument === "string" && !!argument.match(/password/i)) { argument = argument.replace(this.passwordRegex, this.passwordReplacement); } return argument; }); } } exports.Logger = Logger; __decorate([ (0, decorators_1.cache)() ], Logger.prototype, "initialize", null); yok_1.injector.register("logger", Logger); //# sourceMappingURL=logger.js.map