@sidneys/logger
Advanced tools
Comparing version 1.0.3 to 1.0.4
331
index.js
@@ -9,3 +9,6 @@ 'use strict'; | ||
*/ | ||
const fs = require('fs-extra'); | ||
const os = require('os'); | ||
const path = require('path'); | ||
const util = require('util'); | ||
@@ -19,113 +22,283 @@ /** | ||
const appRootPath = require('app-root-path')['path']; | ||
const Appdirectory = require('appdirectory'); | ||
const chalk = require('chalk'); | ||
const chalkline = require('chalkline'); | ||
const minimist = require('minimist'); | ||
const tryRequire = require('try-require'); | ||
const requiredCount = require('@sidneys/required-count'); | ||
const isDebug = require('@sidneys/is-env')('debug'); | ||
const isNolog = require('@sidneys/is-env'))('nolog'); | ||
const present = require('present'); | ||
/** @namespace remote.process */ | ||
/** | ||
* Application | ||
* @constant | ||
* @default | ||
*/ | ||
const appName = packageJson.name; | ||
/** | ||
* @return {Boolean} | ||
* @function | ||
* | ||
* @public | ||
* Filesystem | ||
* @constant | ||
* @default | ||
*/ | ||
let lookupEnvironment = () => { | ||
let name = _.lowerCase(module.exports.environmentName); | ||
const appLogDirectory = (new Appdirectory(appName)).userLogs(); | ||
const appLogFile = path.join(appLogDirectory, `${appName}.log`); | ||
// Lookup global CLI arguments | ||
let globalArgvObj = {}; | ||
try { globalArgvObj = minimist(process.argv); } catch (err) {} | ||
// Lookup "npm run script" arguments | ||
let npmArgvObj = {}; | ||
try { npmArgvObj = minimist(JSON.parse(process.env.npm_config_argv).original); } catch (err) {} | ||
/** | ||
* @constant | ||
* @default | ||
*/ | ||
const typeToChalkStyle = { | ||
debug: 'cyan', | ||
log: 'cyan', | ||
info: 'magenta', | ||
warn: 'yellow', | ||
error: 'red' | ||
}; | ||
// Lookup Electron arguments | ||
let electronArgvObj = {}; | ||
const electron = tryRequire('electron'); | ||
if (electron && electron.remote && electron.remote.process) { | ||
try { | ||
electronArgvObj = minimist(electron.remote.process.argv); | ||
} catch (err) {} | ||
} | ||
/** | ||
* @constant | ||
* @default | ||
*/ | ||
let typeToRgb = { | ||
debug: [100, 100, 100], | ||
log: [0, 128, 255], | ||
info: [255, 100, 150], | ||
warn: [200, 100, 30], | ||
error: [230, 70, 50] | ||
}; | ||
// Node | ||
const nodeEnvName = process.env['NODE_ENV']; | ||
const npmScriptName = process.env.hasOwnProperty('npm_lifecycle_event') ? process.env['npm_lifecycle_event'] : false; | ||
/** | ||
* @constant | ||
* @default | ||
*/ | ||
const typeEmojiMap = { | ||
debug: 'đ§', | ||
log: 'đ', | ||
info: 'âšī¸', | ||
warn: 'â ī¸', | ||
error: 'đ¨' | ||
}; | ||
// Global | ||
const globalValue = process.env[_.lowerCase(name)] || process.env[_.upperCase(name)]; | ||
/** @namespace fs.mkdirp */ | ||
/** @namespace fs.appendFile */ | ||
let isEnv = | ||
// if DEBUG=1, not if DEBUG=0 | ||
globalValue && _.isFinite(parseInt(globalValue)) && parseInt(globalValue) > 0 || | ||
// if DEBUG=text | ||
globalValue && !_.isFinite(parseInt(globalValue)) && Boolean(globalValue) === true || | ||
// if NODE_ENV=environmentName | ||
nodeEnvName === name || | ||
// global CLI arguments | ||
globalArgvObj[name] === true || | ||
// "npm run script" arguments | ||
npmArgvObj[name] === true || | ||
// Electron arguments | ||
electronArgvObj[name] === true || | ||
// npm script name from package.json | ||
npmScriptName && npmScriptName.includes(`:${name}`); | ||
/** | ||
* Log to console and file | ||
* @param {*} entry - Log Message | ||
*/ | ||
let writeToFile = function(entry) { | ||
const globalOptions = module.exports.options; | ||
return Boolean(isEnv); | ||
if (!globalOptions.write || isNolog) { return; } | ||
const date = (new Date()); | ||
const dateString = date.toISOString().replace(/Z|T|\..+/gi, ' ').trim().split(' ').reverse().join(' '); | ||
const logEntry = '[' + dateString + '] ' + entry; | ||
// Create Directory | ||
fs.mkdirp(path.dirname(appLogFile), (err) => { | ||
if (err) { | ||
console.error('logger', 'writeToFile', 'fs.mkdirp', err); | ||
return; | ||
} | ||
// Append Log | ||
fs.appendFile(appLogFile, (`${logEntry}${os.EOL}`), (err) => { | ||
if (err) { | ||
console.error('logger', 'writeToFile', 'fs.appendFile', err); | ||
} | ||
}); | ||
}); | ||
}; | ||
/** @namespace chalkline.white */ | ||
/** | ||
* Prints Environment once | ||
* Format log messages | ||
* @param {string} type - Type | ||
* @param {array} message - Message | ||
* @returns {Object} | ||
*/ | ||
let printEnvironmentName = () => { | ||
const active = lookupEnvironment(); | ||
const count = requiredCount.getCount(); | ||
const name = module.exports.environmentName; | ||
const style = chalk['white'].bold; | ||
const title = 'environment'; | ||
let previousTimestamp; | ||
let parseMessage = (type, message) => { | ||
const globalOptions = module.exports.options; | ||
if (count === 0 && active) { | ||
if (process.type === 'renderer') { | ||
// Chrome Developer Console | ||
console.log( | ||
`%c${title}: ${name}`, | ||
'padding: 0.5rem 50% 0.5rem 0.5rem; white-space: nowrap; background-color: rgb(100, 100, 100); color: white; text-transform: uppercase; font-weight: bold; line-height: 2rem;' | ||
); | ||
} else { | ||
// Terminal | ||
chalkline.white(); | ||
console.log( | ||
style('ENVIRONMENT:'), | ||
style(_.upperCase(name)) | ||
); | ||
chalkline.white(); | ||
const namespace = globalOptions.namespace; | ||
const namespaceList = _.map(global[packageJson.name].namespaces, 'namespace'); | ||
const namespacePosition = namespaceList.indexOf(namespace); | ||
const namespaceThread = namespacePosition & 1; | ||
const chalkStyle = chalk[typeToChalkStyle[type]]; | ||
const indent = (process.type !== 'renderer') ? `i [${namespace}] `.length : `i [${namespace}] `.length; | ||
let body; | ||
let title; | ||
let timestamp; | ||
for (let index in message) { | ||
if (message.hasOwnProperty(index)) { | ||
if (_.isObjectLike(message[index])) { | ||
if (_.isArray(message[index])) { | ||
message[index] = os.EOL + ' '.repeat(indent) + '[' + os.EOL + ' '.repeat(indent + 2) + message[index].join(',' + os.EOL + ' '.repeat(indent + 2)) + os.EOL + ' '.repeat(indent) + ']'; | ||
} else { | ||
message[index] = os.EOL + util.inspect(message[index], { | ||
depth: null, showProxy: true, showHidden: true | ||
}); | ||
message[index] = message[index].replace(new RegExp(os.EOL, 'gi'), `${os.EOL}${' '.repeat(indent)}`); | ||
} | ||
message[index - 1] = `${message[index - 1]}`; | ||
} | ||
} | ||
} | ||
if (message.length > 1) { | ||
title = message[0]; | ||
message.shift(); | ||
} | ||
body = message.join(' '); | ||
// if there's no title, remove body | ||
if (!title) { title = body; } | ||
// consolidate title, body | ||
if (title === body) { body = ''; } | ||
// timestamp | ||
if (globalOptions.timestamp) { | ||
if (!previousTimestamp) { previousTimestamp = present(); } | ||
timestamp = `${(present() - previousTimestamp).toFixed(4)} ms`; | ||
previousTimestamp = present(); | ||
} else { | ||
timestamp = ''; | ||
} | ||
return { | ||
chalk: chalkStyle, | ||
emoji: typeEmojiMap[type], | ||
body: body, | ||
namespace: namespace, | ||
rgb: typeToRgb[type].join(), | ||
timestamp: timestamp, | ||
title: title, | ||
type: _.toUpper(type), | ||
thread: namespaceThread | ||
}; | ||
}; | ||
/** | ||
* Print Devtools | ||
* @param {String} type - Logtype | ||
* @param {Array} message - Message | ||
* @returns {void} | ||
*/ | ||
let printBrowser = function(type, message) { | ||
if (message.length === 0) { return; } | ||
let init = () => { | ||
const parsed = parseMessage(type, message); | ||
printEnvironmentName(); | ||
console.log( | ||
`${parsed.emoji} %c[%s] %c %c%s%c %c%s%c %s`, | ||
//%c | ||
`background-color: rgba(${parsed.rgb}, 0.2); color: rgba(${parsed.rgb}, 0.8); padding: 0 0px; font-weight: normal`, | ||
//%s | ||
parsed.namespace, | ||
//%c | ||
'', | ||
//%c | ||
`background-color: rgba(${parsed.rgb}, 0.0); color: rgba(${parsed.rgb}, 1.0); padding: 0 0px; font-weight: bold`, | ||
//%s | ||
parsed.title, | ||
//%c | ||
'', | ||
//%c | ||
`background-color: rgba(${parsed.rgb}, 0.1); color: rgba(${parsed.rgb}, 1.0); padding: 0 0px; font-weight: normal`, | ||
//%s | ||
parsed.body, | ||
//%c | ||
`background-color: rgba(${parsed.rgb}, 0.0); color: rgba(${parsed.rgb}, 0.5); padding: 0 0px; font-weight: normal`, | ||
//%s | ||
parsed.timestamp | ||
); | ||
writeToFile(util.format( | ||
`[renderer] [${parsed.type}] [%s] %s %s`, | ||
parsed.namespace, parsed.title, parsed.body | ||
)); | ||
}; | ||
/** | ||
* Print Terminal | ||
* @param {String} type - Logtype | ||
* @param {Array} message - Message | ||
* @returns {void} | ||
*/ | ||
let printCli = function(type, message) { | ||
if (message.length === 0) { return; } | ||
const parsed = parseMessage(type, message); | ||
console.log(util.format( | ||
`${parsed.emoji} [%s] %s %s %s`, | ||
//[%s] | ||
parsed.thread ? parsed.chalk(parsed.namespace) : parsed.chalk.underline(parsed.namespace), | ||
//%s | ||
parsed.chalk.bold(parsed.title), | ||
//%s | ||
parsed.chalk(parsed.body), | ||
//%s | ||
parsed.timestamp | ||
)); | ||
writeToFile(util.format( | ||
`[main] [${parsed.type}] [%s] %s %s`, | ||
parsed.namespace, parsed.title, parsed.body | ||
)); | ||
}; | ||
/** | ||
* @returns {Function} | ||
*/ | ||
let print = (process.type === 'renderer') ? printBrowser.bind(console) : printCli; | ||
/** | ||
* @exports | ||
* @param {String} name - Environment name | ||
* @return {Boolean} Environment status | ||
* @param {Object} options - Logger options | ||
* @returns {Object} | ||
*/ | ||
module.exports = (name) => { | ||
module.exports.environmentName = name; | ||
module.exports.environmentActive = lookupEnvironment(); | ||
module.exports = (options) => { | ||
init(); | ||
const file = (module.parent && module.parent.filename) || module.filename; | ||
const namespace = path.basename(file) || packageJson.name; | ||
return module.exports.environmentActive; | ||
// Instance Options | ||
let defaultOptions = { | ||
namespace: namespace, | ||
timestamp: true, | ||
write: false | ||
}; | ||
options = _.defaultsDeep(options, defaultOptions); | ||
module.exports.options = options; | ||
// Global Configuration | ||
global[packageJson.name] = { | ||
namespaces: [] | ||
}; | ||
global[packageJson.name].namespaces.push(options); | ||
// Remove filename from cache, enables detection of requiring module names | ||
delete require.cache[__filename]; | ||
return { | ||
debug() { if (isDebug) { print('debug', Array.from(arguments))} }, | ||
log() { print('log', Array.from(arguments)) }, | ||
info() { print('log', Array.from(arguments)) }, | ||
warn() { print('warn', Array.from(arguments)) }, | ||
error() { print('error', Array.from(arguments)) } | ||
}; | ||
}; | ||
{ | ||
"name": "@sidneys/logger", | ||
"version": "1.0.3", | ||
"version": "1.0.4", | ||
"description": "ES6-based logger with focus on Electron cross-platform Desktop apps", | ||
@@ -34,11 +34,10 @@ "license": "MIT", | ||
"dependencies": { | ||
"@sidneys/required-count": "^1.0.1", | ||
"@sidneys/is-env": "^1.0.2", | ||
"app-root-path": "^2.0.1", | ||
"appdirectory": "^0.1.0", | ||
"chalk": "^2.3.0", | ||
"chalkline": "^0.0.5", | ||
"lodash": "^4.17.4", | ||
"minimist": "^1.2.0", | ||
"try-require": "^1.2.1" | ||
"present": "^1.0.0" | ||
}, | ||
"main": "index.js" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 5 instances in 1 package
11891
6
254
1
1
+ Added@sidneys/is-env@^1.0.2
+ Addedappdirectory@^0.1.0
+ Addedpresent@^1.0.0
+ Added@sidneys/is-env@1.143.0(transitive)
+ Addedansi-styles@4.3.0(transitive)
+ Addedappdirectory@0.1.0(transitive)
+ Addedchalk@4.1.2(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addedhas-flag@4.0.0(transitive)
+ Addedpresent@1.0.0(transitive)
+ Addedsupports-color@7.2.0(transitive)
- Removed@sidneys/required-count@^1.0.1
- Removedchalkline@^0.0.5
- Removedminimist@^1.2.0
- Removedtry-require@^1.2.1