New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

babel-plugin-trace

Package Overview
Dependencies
Maintainers
2
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-trace - npm Package Compare versions

Comparing version 1.1.0 to 2.0.0-rc.1

macro.js

1105

lib/index.js

@@ -9,442 +9,22 @@ 'use strict';

exports.default = function (_ref11) {
var t = _ref11.types,
template = _ref11.template;
exports.getLogFunction = getLogFunction;
exports.handleLabeledStatement = handleLabeledStatement;
function _ref(_id) {
if (!Plugin(_id)) {
throw new TypeError('Function return value violates contract.\n\nExpected:\nPlugin\n\nGot:\n' + _inspect(_id));
exports.default = function (babel) {
function _ref12(_id14) {
if (!Plugin(_id14)) {
throw new TypeError('Function return value violates contract.\n\nExpected:\nPlugin\n\nGot:\n' + _inspect(_id14));
}
return _id;
return _id14;
}
if (!PluginParams(arguments[0])) {
throw new TypeError('Value of argument 0 violates contract.\n\nExpected:\nPluginParams\n\nGot:\n' + _inspect(arguments[0]));
if (!PluginParams(babel)) {
throw new TypeError('Value of argument "babel" violates contract.\n\nExpected:\nPluginParams\n\nGot:\n' + _inspect(babel));
}
var PRESERVE_CONTEXTS = normalizeEnv(process.env.TRACE_CONTEXT);
var PRESERVE_FILES = normalizeEnv(process.env.TRACE_FILE);
var PRESERVE_LEVELS = normalizeEnv(process.env.TRACE_LEVEL);
/**
* Normalize an environment variable, used to override plugin options.
*/
function normalizeEnv(input) {
function _ref2(_id2) {
if (!(Array.isArray(_id2) && _id2.every(function (item) {
return typeof item === 'string';
}))) {
throw new TypeError('Function "normalizeEnv" return value violates contract.\n\nExpected:\nstring[]\n\nGot:\n' + _inspect(_id2));
}
return _id2;
}
if (!(input == null || typeof input === 'string')) {
throw new TypeError('Value of argument "input" violates contract.\n\nExpected:\n?string\n\nGot:\n' + _inspect(input));
}
if (!input) {
return _ref2([]);
}
return _ref2(input.split(/\s*,\s*/).map(function (context) {
return context.toLowerCase().trim();
}).filter(function (id) {
return id;
}));
}
/**
* Like `template()` but returns an expression, not an expression statement.
*/
function expression(input) {
function _ref3(_id3) {
if (!Template(_id3)) {
throw new TypeError('Function "expression" return value violates contract.\n\nExpected:\nTemplate\n\nGot:\n' + _inspect(_id3));
}
return _id3;
}
if (!(typeof input === 'string')) {
throw new TypeError('Value of argument "input" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(input));
}
var fn = template(input);
if (!Template(fn)) {
throw new TypeError('Value of variable "fn" violates contract.\n\nExpected:\nTemplate\n\nGot:\n' + _inspect(fn));
}
return _ref3(function (ids) {
function _ref4(_id4) {
if (!Node(_id4)) {
throw new TypeError('Function return value violates contract.\n\nExpected:\nNode\n\nGot:\n' + _inspect(_id4));
}
return _id4;
}
if (!TemplateIds(ids)) {
throw new TypeError('Value of argument "ids" violates contract.\n\nExpected:\nTemplateIds\n\nGot:\n' + _inspect(ids));
}
var node = fn(ids);
if (!Node(node)) {
throw new TypeError('Value of variable "node" violates contract.\n\nExpected:\nNode\n\nGot:\n' + _inspect(node));
}
return _ref4(node.expression ? node.expression : node);
});
}
/**
* Normalize the plugin options.
*/
function normalizeOpts(opts) {
function _ref5(_id5) {
if (!PluginOptions(_id5)) {
throw new TypeError('Function "normalizeOpts" return value violates contract.\n\nExpected:\nPluginOptions\n\nGot:\n' + _inspect(_id5));
}
return _id5;
}
if (!PluginOptions(opts)) {
throw new TypeError('Value of argument "opts" violates contract.\n\nExpected:\nPluginOptions\n\nGot:\n' + _inspect(opts));
}
if (opts[$normalized]) {
return _ref5(opts);
}
if (!opts.aliases) {
opts.aliases = {
log: defaultLog,
trace: defaultLog,
warn: defaultLog
};
} else {
Object.keys(opts.aliases).forEach(function (key) {
if (typeof opts.aliases[key] === 'string' && opts.aliases[key]) {
var expr = expression(opts.aliases[key]);
if (!(typeof expr === 'function')) {
throw new TypeError('Value of variable "expr" violates contract.\n\nExpected:\n(Message) => Node\n\nGot:\n' + _inspect(expr));
}
opts.aliases[key] = function (message) {
function _ref6(_id6) {
if (!Node(_id6)) {
throw new TypeError('Function return value violates contract.\n\nExpected:\nNode\n\nGot:\n' + _inspect(_id6));
}
return _id6;
}
if (!Message(message)) {
throw new TypeError('Value of argument "message" violates contract.\n\nExpected:\nMessage\n\nGot:\n' + _inspect(message));
}
return _ref6(expr(message));
};
}
});
}
opts[$normalized] = true;
return _ref5(opts);
}
/**
* The default log() function.
*/
function defaultLog(message, metadata) {
function _ref7(_id7) {
if (!Node(_id7)) {
throw new TypeError('Function "defaultLog" return value violates contract.\n\nExpected:\nNode\n\nGot:\n' + _inspect(_id7));
}
return _id7;
}
if (!Message(message)) {
throw new TypeError('Value of argument "message" violates contract.\n\nExpected:\nMessage\n\nGot:\n' + _inspect(message));
}
if (!Metadata(metadata)) {
throw new TypeError('Value of argument "metadata" violates contract.\n\nExpected:\nMetadata\n\nGot:\n' + _inspect(metadata));
}
var prefix = metadata.context + ':';
if (metadata.indent) {
prefix += new Array(metadata.indent + 1).join(' ');
if (!(typeof prefix === 'string')) {
throw new TypeError('Value of variable "prefix" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(prefix));
}
}
if (t.isSequenceExpression(message.content)) {
return _ref7(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [t.stringLiteral(prefix)].concat(message.content.expressions)));
} else {
return _ref7(expression('console.log(PREFIX, CONTENT)')({
PREFIX: t.stringLiteral(prefix),
CONTENT: message.content
}));
}
}
function generatePrefix(dirname, basename) {
function _ref8(_id8) {
if (!(typeof _id8 === 'string')) {
throw new TypeError('Function "generatePrefix" return value violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(_id8));
}
return _id8;
}
if (!(typeof dirname === 'string')) {
throw new TypeError('Value of argument "dirname" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(dirname));
}
if (!(typeof basename === 'string')) {
throw new TypeError('Value of argument "basename" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(basename));
}
if (basename !== 'index') {
return basename;
}
basename = _path2.default.basename(dirname);
if (basename !== 'src' && basename !== 'lib') {
return basename;
}
return _ref8(_path2.default.basename(_path2.default.dirname(dirname)));
}
/**
* Collect the metadata for a given node path, which will be
* made available to logging functions.
*/
function collectMetadata(path, opts) {
function _ref9(_id9) {
if (!Metadata(_id9)) {
throw new TypeError('Function "collectMetadata" return value violates contract.\n\nExpected:\nMetadata\n\nGot:\n' + _inspect(_id9));
}
return _id9;
}
if (!NodePath(path)) {
throw new TypeError('Value of argument "path" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(path));
}
if (!PluginOptions(opts)) {
throw new TypeError('Value of argument "opts" violates contract.\n\nExpected:\nPluginOptions\n\nGot:\n' + _inspect(opts));
}
var filename = _path2.default.resolve(process.cwd(), path.hub.file.opts.filename);
if (!(typeof filename === 'string')) {
throw new TypeError('Value of variable "filename" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(filename));
}
var dirname = _path2.default.dirname(filename);
if (!(typeof dirname === 'string')) {
throw new TypeError('Value of variable "dirname" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(dirname));
}
var extname = _path2.default.extname(filename);
if (!(typeof extname === 'string')) {
throw new TypeError('Value of variable "extname" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(extname));
}
var basename = _path2.default.basename(filename, extname);
if (!(typeof basename === 'string')) {
throw new TypeError('Value of variable "basename" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(basename));
}
var prefix = generatePrefix(dirname, basename);
var names = [];
if (!(Array.isArray(names) && names.every(function (item) {
return typeof item === 'string';
}))) {
throw new TypeError('Value of variable "names" violates contract.\n\nExpected:\nstring[]\n\nGot:\n' + _inspect(names));
}
var indent = 0;
var parent = void 0;
if (!(parent == null || NodePath(parent))) {
throw new TypeError('Value of variable "parent" violates contract.\n\nExpected:\n?NodePath\n\nGot:\n' + _inspect(parent));
}
var parentName = path.getAncestry().slice(1).reduce(function (parts, item) {
if (!(Array.isArray(parts) && parts.every(function (item) {
return typeof item === 'string';
}))) {
throw new TypeError('Value of argument "parts" violates contract.\n\nExpected:\nstring[]\n\nGot:\n' + _inspect(parts));
}
if (!NodePath(item)) {
throw new TypeError('Value of argument "item" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(item));
}
if (item.isClassMethod()) {
if (!parent) {
parent = item;
}
parts.unshift(item.node.key.type === 'Identifier' ? item.node.key.name : '[computed method]');
} else if (item.isClassDeclaration()) {
if (!parent) {
parent = item;
}
parts.unshift(item.node.id ? item.node.id.name : '[anonymous class@' + item.node.loc.start.line + ']');
} else if (item.isFunction()) {
if (!parent) {
parent = item;
}
parts.unshift(item.node.id && item.node.id.name || '[anonymous@' + item.node.loc.start.line + ']');
} else if (item.isProgram()) {
if (!parent) {
parent = item;
}
} else if (!parent && !item.isClassBody() && !item.isBlockStatement()) {
indent++;
}
return parts;
}, []).join(':');
if (!(typeof parentName === 'string')) {
throw new TypeError('Value of variable "parentName" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(parentName));
}
var hasStartMessage = false;
var isStartMessage = false;
if (parent && !parent.isProgram()) {
_parent$get$get = parent.get('body').get('body');
if (!(_parent$get$get && (typeof _parent$get$get[Symbol.iterator] === 'function' || Array.isArray(_parent$get$get)))) {
throw new TypeError('Expected _parent$get$get to be iterable, got ' + _inspect(_parent$get$get));
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = _parent$get$get[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _parent$get$get;
var _child = _step.value;
if (!NodePath(_child)) {
throw new TypeError('Value of variable "child" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(_child));
}
if (_child.node[$handled]) {
hasStartMessage = true;
break;
}
if (!_child.isLabeledStatement()) {
break;
}
var label = _child.get('label');
if (!NodePath(label)) {
throw new TypeError('Value of variable "label" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(label));
}
if (opts.aliases[label.node.name]) {
hasStartMessage = true;
if (_child.node === path.node) {
isStartMessage = true;
}
break;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
var context = prefix + ':' + parentName;
return _ref9({ indent: indent, prefix: prefix, parentName: parentName, context: context, hasStartMessage: hasStartMessage, isStartMessage: isStartMessage, filename: filename, dirname: dirname, basename: basename, extname: extname });
}
/**
* Determine whether the given logging statement should be stripped.
*/
function shouldStrip(name, metadata, opts) {
if (!(typeof name === 'string')) {
throw new TypeError('Value of argument "name" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(name));
}
if (!Metadata(metadata)) {
throw new TypeError('Value of argument "metadata" violates contract.\n\nExpected:\nMetadata\n\nGot:\n' + _inspect(metadata));
}
if (!PluginOptions(opts)) {
throw new TypeError('Value of argument "opts" violates contract.\n\nExpected:\nPluginOptions\n\nGot:\n' + _inspect(opts));
}
if (!opts.strip) {
return false;
} else if (opts.strip === true) {
return !hasStripOverride(name, metadata);
} else if (typeof opts.strip === 'string') {
if (opts.strip === process.env.NODE_ENV) {
return !hasStripOverride(name, metadata);
}
} else if (opts.strip[process.env.NODE_ENV]) {
return !hasStripOverride(name, metadata);
}
return true;
}
function hasStripOverride(name, metadata) {
if (!(typeof name === 'string')) {
throw new TypeError('Value of argument "name" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(name));
}
if (!Metadata(metadata)) {
throw new TypeError('Value of argument "metadata" violates contract.\n\nExpected:\nMetadata\n\nGot:\n' + _inspect(metadata));
}
if (PRESERVE_CONTEXTS.length && PRESERVE_CONTEXTS.some(function (context) {
return metadata.context.toLowerCase().indexOf(context) !== -1;
})) {
return true;
} else if (PRESERVE_FILES.length && PRESERVE_FILES.some(function (filename) {
return metadata.filename.toLowerCase().indexOf(filename) !== -1;
})) {
return true;
} else if (PRESERVE_LEVELS.length && PRESERVE_LEVELS.some(function (level) {
return level === name.toLowerCase();
})) {
return true;
} else {
return false;
}
}
return _ref({
return _ref12({
visitor: {
Program: function Program(program, _ref12) {
var opts = _ref12.opts;
Program: function Program(program, _ref15) {
var opts = _ref15.opts;

@@ -461,68 +41,3 @@ if (!NodePath(program)) {

var label = path.get('label');
if (!NodePath(label)) {
throw new TypeError('Value of variable "label" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(label));
}
opts = normalizeOpts(opts);
if (!opts.aliases[label.node.name]) {
return;
}
var metadata = collectMetadata(path, opts);
if (!Metadata(metadata)) {
throw new TypeError('Value of variable "metadata" violates contract.\n\nExpected:\nMetadata\n\nGot:\n' + _inspect(metadata));
}
if (shouldStrip(label.node.name, metadata, opts)) {
path.remove();
return;
}
path.traverse({
"VariableDeclaration|Function|AssignmentExpression|UpdateExpression|YieldExpression|ReturnStatement": function VariableDeclarationFunctionAssignmentExpressionUpdateExpressionYieldExpressionReturnStatement(item) {
if (!NodePath(item)) {
throw new TypeError('Value of argument "item" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(item));
}
throw path.buildCodeFrameError('Logging statements cannot have side effects.');
},
ExpressionStatement: function ExpressionStatement(statement) {
if (!NodePath(statement)) {
throw new TypeError('Value of argument "statement" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(statement));
}
if (statement.node[$handled]) {
return;
}
var message = {
prefix: t.stringLiteral(metadata.prefix),
content: statement.get('expression').node,
hasStartMessage: t.booleanLiteral(metadata.hasStartMessage),
isStartMessage: t.booleanLiteral(metadata.isStartMessage),
indent: t.numericLiteral(metadata.indent),
parentName: t.stringLiteral(metadata.parentName),
filename: t.stringLiteral(metadata.filename),
dirname: t.stringLiteral(metadata.dirname),
basename: t.stringLiteral(metadata.basename),
extname: t.stringLiteral(metadata.extname)
};
if (!Message(message)) {
throw new TypeError('Value of variable "message" violates contract.\n\nExpected:\nMessage\n\nGot:\n' + _inspect(message));
}
var replacement = t.expressionStatement(opts.aliases[label.node.name](message, metadata));
replacement[$handled] = true;
statement.replaceWith(replacement);
}
});
if (path.get('body').isBlockStatement()) {
path.replaceWithMultiple(path.get('body').node.body);
} else {
path.replaceWith(path.get('body').node);
}
handleLabeledStatement(babel, path, opts);
}

@@ -555,5 +70,19 @@ });

var PluginTemplate = function () {
function PluginTemplate(input) {
return typeof input === 'function';
}
;
Object.defineProperty(PluginTemplate, Symbol.hasInstance, {
value: function value(input) {
return PluginTemplate(input);
}
});
return PluginTemplate;
}();
var PluginParams = function () {
function PluginParams(input) {
return input != null && input.types instanceof Object && typeof input.template === 'function';
return input != null && input.types instanceof Object && PluginTemplate(input.template);
}

@@ -575,5 +104,8 @@

return typeof _key === 'string' || Template(_key);
})) && (input.strip === undefined || typeof input.strip === 'boolean' || typeof input.strip === 'string' || input.strip != null && _typeof(input.strip) === 'object' && Object.keys(input.strip).every(function (key) {
})) && (input.strip === undefined || typeof input.strip === 'boolean' || input.strip != null && _typeof(input.strip) === 'object' && Object.keys(input.strip).every(function (key) {
var _key2 = input.strip[key];
return typeof _key2 === 'boolean';
return typeof _key2 === 'boolean' || _key2 != null && (typeof _key2 === 'undefined' ? 'undefined' : _typeof(_key2)) === 'object' && Object.keys(_key2).every(function (key) {
var _key3 = _key2[key];
return typeof _key3 === 'boolean';
});
}));

@@ -591,7 +123,35 @@ }

var LogFunction = function () {
function LogFunction(input) {
return typeof input === 'function';
}
;
Object.defineProperty(LogFunction, Symbol.hasInstance, {
value: function value(input) {
return LogFunction(input);
}
});
return LogFunction;
}();
var LogLevel = function () {
function LogLevel(input) {
return input === 'log' || input === 'warn' || input === 'error';
}
;
Object.defineProperty(LogLevel, Symbol.hasInstance, {
value: function value(input) {
return LogLevel(input);
}
});
return LogLevel;
}();
var Visitors = function () {
function Visitors(input) {
return input != null && (typeof input === 'undefined' ? 'undefined' : _typeof(input)) === 'object' && Object.keys(input).every(function (key) {
var _key3 = input[key];
return Visitor(_key3);
var _key4 = input[key];
return Visitor(_key4);
});

@@ -626,4 +186,4 @@ }

return input != null && (typeof input === 'undefined' ? 'undefined' : _typeof(input)) === 'object' && Object.keys(input).every(function (key) {
var _key4 = input[key];
return Node(_key4);
var _key5 = input[key];
return Node(_key5);
});

@@ -756,3 +316,538 @@ }

var PRESERVE_CONTEXTS = normalizeEnv(process.env.TRACE_CONTEXT);
var PRESERVE_FILES = normalizeEnv(process.env.TRACE_FILE);
var PRESERVE_LEVELS = normalizeEnv(process.env.TRACE_LEVEL);
/**
* Normalize an environment variable, used to override plugin options.
*/
function normalizeEnv(input) {
function _ref(_id) {
if (!(Array.isArray(_id) && _id.every(function (item) {
return typeof item === 'string';
}))) {
throw new TypeError('Function "normalizeEnv" return value violates contract.\n\nExpected:\nstring[]\n\nGot:\n' + _inspect(_id));
}
return _id;
}
if (!(input == null || typeof input === 'string')) {
throw new TypeError('Value of argument "input" violates contract.\n\nExpected:\n?string\n\nGot:\n' + _inspect(input));
}
if (!input) {
return _ref([]);
}
return _ref(input.split(',').map(function (context) {
return context.toLowerCase().trim();
}).filter(function (id) {
return id;
}));
}
/**
* Like `template()` but returns an expression, not an expression statement.
*/
function expression(input, template) {
function _ref2(_id2) {
if (!Template(_id2)) {
throw new TypeError('Function "expression" return value violates contract.\n\nExpected:\nTemplate\n\nGot:\n' + _inspect(_id2));
}
return _id2;
}
if (!(typeof input === 'string')) {
throw new TypeError('Value of argument "input" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(input));
}
if (!PluginTemplate(template)) {
throw new TypeError('Value of argument "template" violates contract.\n\nExpected:\nPluginTemplate\n\nGot:\n' + _inspect(template));
}
var fn = template(input);
if (!Template(fn)) {
throw new TypeError('Value of variable "fn" violates contract.\n\nExpected:\nTemplate\n\nGot:\n' + _inspect(fn));
}
return _ref2(function (ids) {
function _ref3(_id3) {
if (!Node(_id3)) {
throw new TypeError('Function return value violates contract.\n\nExpected:\nNode\n\nGot:\n' + _inspect(_id3));
}
return _id3;
}
if (!TemplateIds(ids)) {
throw new TypeError('Value of argument "ids" violates contract.\n\nExpected:\nTemplateIds\n\nGot:\n' + _inspect(ids));
}
var node = fn(ids);
if (!Node(node)) {
throw new TypeError('Value of variable "node" violates contract.\n\nExpected:\nNode\n\nGot:\n' + _inspect(node));
}
return _ref3(node.expression ? node.expression : node);
});
}
/**
* The default log() function.
*/
function getLogFunction(_ref13, logLevel) {
var t = _ref13.types,
template = _ref13.template;
function _ref4(_id4) {
if (!LogFunction(_id4)) {
throw new TypeError('Function "getLogFunction" return value violates contract.\n\nExpected:\nLogFunction\n\nGot:\n' + _inspect(_id4));
}
return _id4;
}
if (!PluginParams(arguments[0])) {
throw new TypeError('Value of argument 0 violates contract.\n\nExpected:\nPluginParams\n\nGot:\n' + _inspect(arguments[0]));
}
if (!LogLevel(logLevel)) {
throw new TypeError('Value of argument "logLevel" violates contract.\n\nExpected:\nLogLevel\n\nGot:\n' + _inspect(logLevel));
}
return _ref4(function log(message, metadata) {
function _ref5(_id5) {
if (!Node(_id5)) {
throw new TypeError('Function "log" return value violates contract.\n\nExpected:\nNode\n\nGot:\n' + _inspect(_id5));
}
return _id5;
}
if (!Message(message)) {
throw new TypeError('Value of argument "message" violates contract.\n\nExpected:\nMessage\n\nGot:\n' + _inspect(message));
}
if (!Metadata(metadata)) {
throw new TypeError('Value of argument "metadata" violates contract.\n\nExpected:\nMetadata\n\nGot:\n' + _inspect(metadata));
}
var prefix = metadata.context + ':';
if (metadata.indent) {
prefix += new Array(metadata.indent + 1).join(' ');
if (!(typeof prefix === 'string')) {
throw new TypeError('Value of variable "prefix" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(prefix));
}
}
if (t.isSequenceExpression(message.content)) {
return _ref5(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier(logLevel)), [t.stringLiteral(prefix)].concat(message.content.expressions)));
} else {
return _ref5(expression('console.LOGLEVEL(PREFIX, CONTENT)', template)({
LOGLEVEL: t.identifier(logLevel),
PREFIX: t.stringLiteral(prefix),
CONTENT: message.content
}));
}
});
}
/**
* Normalize the plugin options.
*/
function normalizeOpts(babel, opts) {
function _ref6(_id6) {
if (!PluginOptions(_id6)) {
throw new TypeError('Function "normalizeOpts" return value violates contract.\n\nExpected:\nPluginOptions\n\nGot:\n' + _inspect(_id6));
}
return _id6;
}
if (!PluginParams(babel)) {
throw new TypeError('Value of argument "babel" violates contract.\n\nExpected:\nPluginParams\n\nGot:\n' + _inspect(babel));
}
if (!PluginOptions(opts)) {
throw new TypeError('Value of argument "opts" violates contract.\n\nExpected:\nPluginOptions\n\nGot:\n' + _inspect(opts));
}
if (opts[$normalized]) {
return _ref6(opts);
}
if (!opts.aliases) {
var log = getLogFunction(babel, 'log');
opts.aliases = {
log: log,
trace: log,
warn: getLogFunction(babel, 'warn')
};
} else {
Object.keys(opts.aliases).forEach(function (key) {
if (typeof opts.aliases[key] === 'string' && opts.aliases[key]) {
var expr = expression(opts.aliases[key], babel.template);
if (!(typeof expr === 'function')) {
throw new TypeError('Value of variable "expr" violates contract.\n\nExpected:\n(Message) => Node\n\nGot:\n' + _inspect(expr));
}
opts.aliases[key] = function (message) {
function _ref7(_id7) {
if (!Node(_id7)) {
throw new TypeError('Function return value violates contract.\n\nExpected:\nNode\n\nGot:\n' + _inspect(_id7));
}
return _id7;
}
if (!Message(message)) {
throw new TypeError('Value of argument "message" violates contract.\n\nExpected:\nMessage\n\nGot:\n' + _inspect(message));
}
return _ref7(expr(message));
};
}
});
}
if (opts.strip === undefined) {
opts.strip = {
log: { production: true },
trace: true,
warn: { production: true }
};
}
opts[$normalized] = true;
return _ref6(opts);
}
function generatePrefix(dirname, basename) {
function _ref8(_id8) {
if (!(typeof _id8 === 'string')) {
throw new TypeError('Function "generatePrefix" return value violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(_id8));
}
return _id8;
}
if (!(typeof dirname === 'string')) {
throw new TypeError('Value of argument "dirname" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(dirname));
}
if (!(typeof basename === 'string')) {
throw new TypeError('Value of argument "basename" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(basename));
}
if (basename !== 'index') {
return basename;
}
basename = _path2.default.basename(dirname);
if (basename !== 'src' && basename !== 'lib') {
return basename;
}
return _ref8(_path2.default.basename(_path2.default.dirname(dirname)));
}
/**
* Collect the metadata for a given node path, which will be
* made available to logging functions.
*/
function collectMetadata(path, opts) {
function _ref9(_id9) {
if (!Metadata(_id9)) {
throw new TypeError('Function "collectMetadata" return value violates contract.\n\nExpected:\nMetadata\n\nGot:\n' + _inspect(_id9));
}
return _id9;
}
if (!NodePath(path)) {
throw new TypeError('Value of argument "path" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(path));
}
if (!PluginOptions(opts)) {
throw new TypeError('Value of argument "opts" violates contract.\n\nExpected:\nPluginOptions\n\nGot:\n' + _inspect(opts));
}
var filename = _path2.default.resolve(process.cwd(), path.hub.file.opts.filename);
if (!(typeof filename === 'string')) {
throw new TypeError('Value of variable "filename" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(filename));
}
var dirname = _path2.default.dirname(filename);
if (!(typeof dirname === 'string')) {
throw new TypeError('Value of variable "dirname" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(dirname));
}
var extname = _path2.default.extname(filename);
if (!(typeof extname === 'string')) {
throw new TypeError('Value of variable "extname" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(extname));
}
var basename = _path2.default.basename(filename, extname);
if (!(typeof basename === 'string')) {
throw new TypeError('Value of variable "basename" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(basename));
}
var prefix = generatePrefix(dirname, basename);
var names = [];
if (!(Array.isArray(names) && names.every(function (item) {
return typeof item === 'string';
}))) {
throw new TypeError('Value of variable "names" violates contract.\n\nExpected:\nstring[]\n\nGot:\n' + _inspect(names));
}
var indent = 0;
var parent = void 0;
if (!(parent == null || NodePath(parent))) {
throw new TypeError('Value of variable "parent" violates contract.\n\nExpected:\n?NodePath\n\nGot:\n' + _inspect(parent));
}
var parentName = path.getAncestry().slice(1).reduce(function (parts, item) {
if (!(Array.isArray(parts) && parts.every(function (item) {
return typeof item === 'string';
}))) {
throw new TypeError('Value of argument "parts" violates contract.\n\nExpected:\nstring[]\n\nGot:\n' + _inspect(parts));
}
if (!NodePath(item)) {
throw new TypeError('Value of argument "item" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(item));
}
if (item.isClassMethod()) {
if (!parent) {
parent = item;
}
parts.unshift(item.node.key.type === 'Identifier' ? item.node.key.name : '[computed method]');
} else if (item.isClassDeclaration()) {
if (!parent) {
parent = item;
}
parts.unshift(item.node.id ? item.node.id.name : '[anonymous class@' + item.node.loc.start.line + ']');
} else if (item.isFunction()) {
if (!parent) {
parent = item;
}
parts.unshift(item.node.id && item.node.id.name || '[anonymous@' + item.node.loc.start.line + ']');
} else if (item.isProgram()) {
if (!parent) {
parent = item;
}
} else if (!parent && !item.isClassBody() && !item.isBlockStatement()) {
indent++;
}
return parts;
}, []).join(':');
if (!(typeof parentName === 'string')) {
throw new TypeError('Value of variable "parentName" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(parentName));
}
var hasStartMessage = false;
var isStartMessage = false;
if (parent && !parent.isProgram()) {
_parent$get$get = parent.get('body').get('body');
if (!(_parent$get$get && (typeof _parent$get$get[Symbol.iterator] === 'function' || Array.isArray(_parent$get$get)))) {
throw new TypeError('Expected _parent$get$get to be iterable, got ' + _inspect(_parent$get$get));
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = _parent$get$get[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _parent$get$get;
var _child = _step.value;
if (!NodePath(_child)) {
throw new TypeError('Value of variable "child" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(_child));
}
if (_child.node[$handled]) {
hasStartMessage = true;
break;
}
if (!_child.isLabeledStatement()) {
break;
}
var label = _child.get('label');
if (!NodePath(label)) {
throw new TypeError('Value of variable "label" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(label));
}
if (opts.aliases[label.node.name]) {
hasStartMessage = true;
if (_child.node === path.node) {
isStartMessage = true;
}
break;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
var context = prefix + ':' + parentName;
return _ref9({ indent: indent, prefix: prefix, parentName: parentName, context: context, hasStartMessage: hasStartMessage, isStartMessage: isStartMessage, filename: filename, dirname: dirname, basename: basename, extname: extname });
}
/**
* Determine whether the given logging statement should be stripped.
*/
function shouldStrip(name, metadata, _ref14) {
var strip = _ref14.strip;
if (!(typeof name === 'string')) {
throw new TypeError('Value of argument "name" violates contract.\n\nExpected:\nstring\n\nGot:\n' + _inspect(name));
}
if (!Metadata(metadata)) {
throw new TypeError('Value of argument "metadata" violates contract.\n\nExpected:\nMetadata\n\nGot:\n' + _inspect(metadata));
}
if (!PluginOptions(arguments[2])) {
throw new TypeError('Value of argument 2 violates contract.\n\nExpected:\nPluginOptions\n\nGot:\n' + _inspect(arguments[2]));
}
switch (typeof strip === 'undefined' ? 'undefined' : _typeof(strip)) {
case 'boolean':
if (!strip) return false;
// strip === true
break;
case 'object':
var se = strip[name];
if (!se || (typeof se === 'undefined' ? 'undefined' : _typeof(se)) === 'object' && !se[process.env.NODE_ENV]) return false;
// strip[name] === true || strip[name][env] === true
break;
default:
return false;
}
if (PRESERVE_CONTEXTS.length) {
var context = metadata.context.toLowerCase();
if (PRESERVE_CONTEXTS.some(function (pc) {
return context.includes(pc);
})) return false;
}
if (PRESERVE_FILES.length) {
var _filename = metadata.filename.toLowerCase();
if (PRESERVE_FILES.some(function (pf) {
return _filename.includes(pf);
})) return false;
}
if (PRESERVE_LEVELS.length) {
var level = name.toLowerCase();
if (PRESERVE_LEVELS.some(function (pl) {
return level === pl;
})) return false;
}
return true;
}
function handleLabeledStatement(babel, path, opts) {
if (!PluginParams(babel)) {
throw new TypeError('Value of argument "babel" violates contract.\n\nExpected:\nPluginParams\n\nGot:\n' + _inspect(babel));
}
if (!NodePath(path)) {
throw new TypeError('Value of argument "path" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(path));
}
if (!PluginOptions(opts)) {
throw new TypeError('Value of argument "opts" violates contract.\n\nExpected:\nPluginOptions\n\nGot:\n' + _inspect(opts));
}
var t = babel.types;
var label = path.get('label');
if (!NodePath(label)) {
throw new TypeError('Value of variable "label" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(label));
}
opts = normalizeOpts(babel, opts);
if (!opts.aliases[label.node.name]) {
return;
}
var metadata = collectMetadata(path, opts);
if (!Metadata(metadata)) {
throw new TypeError('Value of variable "metadata" violates contract.\n\nExpected:\nMetadata\n\nGot:\n' + _inspect(metadata));
}
if (shouldStrip(label.node.name, metadata, opts)) {
path.remove();
return;
}
path.traverse({
"VariableDeclaration|Function|AssignmentExpression|UpdateExpression|YieldExpression|ReturnStatement": function VariableDeclarationFunctionAssignmentExpressionUpdateExpressionYieldExpressionReturnStatement(item) {
if (!NodePath(item)) {
throw new TypeError('Value of argument "item" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(item));
}
throw path.buildCodeFrameError('Logging statements cannot have side effects.');
},
ExpressionStatement: function ExpressionStatement(statement) {
if (!NodePath(statement)) {
throw new TypeError('Value of argument "statement" violates contract.\n\nExpected:\nNodePath\n\nGot:\n' + _inspect(statement));
}
if (statement.node[$handled]) {
return;
}
var message = {
prefix: t.stringLiteral(metadata.prefix),
content: statement.get('expression').node,
hasStartMessage: t.booleanLiteral(metadata.hasStartMessage),
isStartMessage: t.booleanLiteral(metadata.isStartMessage),
indent: t.numericLiteral(metadata.indent),
parentName: t.stringLiteral(metadata.parentName),
filename: t.stringLiteral(metadata.filename),
dirname: t.stringLiteral(metadata.dirname),
basename: t.stringLiteral(metadata.basename),
extname: t.stringLiteral(metadata.extname)
};
if (!Message(message)) {
throw new TypeError('Value of variable "message" violates contract.\n\nExpected:\nMessage\n\nGot:\n' + _inspect(message));
}
var replacement = t.expressionStatement(opts.aliases[label.node.name](message, metadata));
replacement[$handled] = true;
statement.replaceWith(replacement);
}
});
if (path.get('body').isBlockStatement()) {
path.replaceWithMultiple(path.get('body').node.body);
} else {
path.replaceWith(path.get('body').node);
}
}
/**
* # Trace

@@ -759,0 +854,0 @@ */

{
"name": "babel-plugin-trace",
"version": "1.1.0",
"version": "2.0.0-rc.1",
"description": "Super convenient syntax for execution tracing, logging and debugging JavaScript applications via a babel plugin.",

@@ -22,2 +22,3 @@ "main": "lib/index.js",

"babel-plugin",
"babel-plugin-macros",
"logging",

@@ -51,3 +52,6 @@ "trace",

"should": "^6.0.1"
},
"dependencies": {
"babel-plugin-macros": "^2.2.1"
}
}
# Babel Plugin: Trace
This is a [Babel](https://babeljs.io/) plugin which adds a straightforward, declarative syntax for adding debug logging to JavaScript applications.
This is a [Babel](https://babeljs.io/) plugin & macro which adds a straightforward, declarative syntax for adding debug logging to JavaScript applications.
[![Build Status](https://travis-ci.org/codemix/babel-plugin-trace.svg)](https://travis-ci.org/codemix/babel-plugin-trace)
# What?
## What?

@@ -13,3 +13,3 @@ It's common to insert `console.log()` statements to help keep track of the internal state of functions when writing tricky pieces of code. During development this is very useful, but it creates a lot of noise in the console, and when development of that particular piece of code is complete, the developer is likely to delete the `console.log()` calls. If we're lucky, they might leave comments in their place.

This plugin repurposes JavaScript LabeledStatements like `log:` and `trace:` to provide a logging / tracing syntax which can be selectively enabled or disabled at the folder, file, or function level at build time. Normally, these labels are only used as targets for labeled `break` and `continue` statements.
This plugin repurposes JavaScript [LabeledStatements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label) like `log:` and `trace:` to provide a logging / tracing syntax which can be selectively enabled or disabled at the folder, file, or function level at build time. Normally, these labels are only used as targets for labeled `break` and `continue` statements.

@@ -22,17 +22,17 @@ When disabled in production the logging statements are completely dropped out, incurring no overhead. The syntax looks like this:

async function authenticate (username, password) {
trace: 'authenticating user', username;
log: 'authenticating user', username;
const user = await db.select().from('users').where({username: username});
if (!user) {
trace: 'no such user';
log: 'no such user';
return false;
}
else if (!user.checkPassword(password)) {
trace: 'invalid password';
log: 'invalid password';
return false;
}
else if (!user.isActive) {
trace: 'user is not active';
log: 'user is not active';
return false;
}
trace: 'logging user', username, 'into the site';
log: 'logging user', username, 'into the site';
return true;

@@ -53,12 +53,14 @@ }

As well as `trace:`, you can also use `log:` and `warn:`, or specify your own using the `aliases` plugin option.
As well as `log:`, you can also use `trace:` and `warn:`, or specify your own using the `aliases` plugin option. By default all `trace:` logs will be stripped (unless specifically enabled) and `warn:` will use `console.warn` rather than `console.log`.
## Installation
# Installation & Configuration
Install via [npm](https://npmjs.org/package/babel-plugin-trace).
```sh
```
npm install --save-dev babel-plugin-trace
```
Then, in your babel configuration (usually in your `.babelrc` file), add `"trace"` to your list of plugins:
## Plugin Configuration
In your Babel configuration, add `"trace"` to your list of plugins. The default configuration will strip all logging from production builds, as well as trace logging from development and test environment, corresponding to this configuration:
```json

@@ -68,4 +70,6 @@ {

["trace", {
"env": {
"production": { "strip": true }
"strip": {
"log": { "production": true },
"trace": true,
"warn": { "production": true }
}

@@ -77,5 +81,3 @@ }]

The above example configuration will remove all tracing when `NODE_ENV=production`.
Alternatively, you may wish to disable all tracing by default, enabling it only for certain files or functions using environment variables:
`"strip"` may also take a `true` value to disable all logging by default. In this case you can still enable it for certain files or functions using environment variables:
```json

@@ -89,5 +91,29 @@ {

## Macro Configuration
# Environment Variables
As an alternative to use as a plugin, `babel-plugin-trace/macro` is provided for use together with [babel-plugin-macros](https://github.com/kentcdodds/babel-plugin-macros). This is relevant in particular if you're working with a [create-react-app](https://github.com/facebook/create-react-app) project, as that does not otherwise allow for Babel plugins to be used. With macro use, you'll need to import the macro in every file where you'd like to enable logging:
```js
import initTrace from 'babel-plugin-trace/macro'
initTrace()
log: 'This is', { a: 'message' }
```
To customise the logging labels, import them as named imports of the macro (the default import is still required, as the labels don't really match the imported variable bindings):
```js
import initTrace, { log, announce } from 'babel-plugin-trace/macro'
initTrace()
announce: 'This is', { an: 'announcement' }
```
Unfortunately the `initTrace` call is required until [kentcdodds/babel-plugin-macros#65](https://github.com/kentcdodds/babel-plugin-macros/pull/65) is merged, after which the API simplifies to:
```js
import 'babel-plugin-trace/macro'
log: 'This is', { another: 'message' }
```
## Environment Variables
### `TRACE_LEVEL` - Enable only specific logging levels

@@ -126,6 +152,5 @@ Log only `warn` statements.

## License
# License
Published by [codemix](http://codemix.com/) under a permissive MIT License, see [LICENSE.md](./LICENSE.md).

@@ -7,5 +7,7 @@ import fspath from "path";

type PluginTemplate = (source: string) => Template;
type PluginParams = {
types: Object;
template: (source: string) => Template;
template: PluginTemplate;
};

@@ -17,5 +19,10 @@

};
strip?: boolean|string|{[key: string]: boolean};
strip?: boolean | {
[key: string]: boolean | { [key: string]: boolean }
};
};
type LogFunction = (message: Message, metadata: Metadata) => Node;
type LogLevel = 'log' | 'warn' | 'error';
type Visitors = {

@@ -78,64 +85,34 @@ [key: string]: Visitor

const PRESERVE_CONTEXTS = normalizeEnv(process.env.TRACE_CONTEXT);
const PRESERVE_FILES = normalizeEnv(process.env.TRACE_FILE);
const PRESERVE_LEVELS = normalizeEnv(process.env.TRACE_LEVEL);
/**
* # Trace
* Normalize an environment variable, used to override plugin options.
*/
export default function ({types: t, template}: PluginParams): Plugin {
const PRESERVE_CONTEXTS = normalizeEnv(process.env.TRACE_CONTEXT);
const PRESERVE_FILES = normalizeEnv(process.env.TRACE_FILE);
const PRESERVE_LEVELS = normalizeEnv(process.env.TRACE_LEVEL);
/**
* Normalize an environment variable, used to override plugin options.
*/
function normalizeEnv (input: ?string): string[] {
if (!input) {
return [];
}
return input.split(/\s*,\s*/)
.map(context => context.toLowerCase().trim())
.filter(id => id);
function normalizeEnv (input: ?string): string[] {
if (!input) {
return [];
}
return input.split(',')
.map(context => context.toLowerCase().trim())
.filter(id => id);
}
/**
* Like `template()` but returns an expression, not an expression statement.
*/
function expression (input: string): Template {
const fn: Template = template(input);
return function (ids: TemplateIds): Node {
const node: Node = fn(ids);
return node.expression ? node.expression : node;
};
}
/**
* Like `template()` but returns an expression, not an expression statement.
*/
function expression (input: string, template: PluginTemplate): Template {
const fn: Template = template(input);
return function (ids: TemplateIds): Node {
const node: Node = fn(ids);
return node.expression ? node.expression : node;
};
}
/**
* Normalize the plugin options.
*/
function normalizeOpts (opts: PluginOptions): PluginOptions {
if (opts[$normalized]) {
return opts;
}
if (!opts.aliases) {
opts.aliases = {
log: defaultLog,
trace: defaultLog,
warn: defaultLog
};
}
else {
Object.keys(opts.aliases).forEach(key => {
if (typeof opts.aliases[key] === 'string' && opts.aliases[key]) {
const expr: ((message: Message) => Node) = expression(opts.aliases[key]);
opts.aliases[key] = (message: Message): Node => expr(message);
}
});
}
opts[$normalized] = true;
return opts;
}
/**
* The default log() function.
*/
function defaultLog (message: Message, metadata: Metadata): Node {
/**
* The default log() function.
*/
export function getLogFunction ({ types: t, template }: PluginParams, logLevel: LogLevel): LogFunction {
return function log (message: Message, metadata: Metadata): Node {
let prefix: string = `${metadata.context}:`;

@@ -149,3 +126,3 @@ if (metadata.indent) {

t.identifier('console'),
t.identifier('log')
t.identifier(logLevel)
),

@@ -156,3 +133,4 @@ [t.stringLiteral(prefix)].concat(message.content.expressions)

else {
return expression(`console.log(PREFIX, CONTENT)`)({
return expression(`console.LOGLEVEL(PREFIX, CONTENT)`, template)({
LOGLEVEL: t.identifier(logLevel),
PREFIX: t.stringLiteral(prefix),

@@ -163,179 +141,214 @@ CONTENT: message.content

}
}
function generatePrefix (dirname: string, basename: string): string {
if (basename !== 'index') {
return basename;
}
basename = fspath.basename(dirname);
if (basename !== 'src' && basename !== 'lib') {
return basename;
}
/**
* Normalize the plugin options.
*/
function normalizeOpts (babel: PluginParams, opts: PluginOptions): PluginOptions {
if (opts[$normalized]) {
return opts;
}
if (!opts.aliases) {
const log = getLogFunction(babel, 'log');
opts.aliases = {
log: log,
trace: log,
warn: getLogFunction(babel, 'warn')
};
}
else {
Object.keys(opts.aliases).forEach(key => {
if (typeof opts.aliases[key] === 'string' && opts.aliases[key]) {
const expr: ((message: Message) => Node) = expression(opts.aliases[key], babel.template);
opts.aliases[key] = (message: Message): Node => expr(message);
}
});
}
if (opts.strip === undefined) {
opts.strip = {
log: { production: true },
trace: true,
warn: { production: true }
};
}
opts[$normalized] = true;
return opts;
}
return fspath.basename(fspath.dirname(dirname));
function generatePrefix (dirname: string, basename: string): string {
if (basename !== 'index') {
return basename;
}
basename = fspath.basename(dirname);
if (basename !== 'src' && basename !== 'lib') {
return basename;
}
return fspath.basename(fspath.dirname(dirname));
}
/**
* Collect the metadata for a given node path, which will be
* made available to logging functions.
*/
function collectMetadata (path: NodePath, opts: PluginOptions): Metadata {
const filename: string = fspath.resolve(process.cwd(), path.hub.file.opts.filename);
const dirname: string = fspath.dirname(filename);
const extname: string = fspath.extname(filename);
const basename: string = fspath.basename(filename, extname);
const prefix: string = generatePrefix(dirname, basename);
const names: string[] = [];
let indent: number = 0;
let parent: ?NodePath;
/**
* Collect the metadata for a given node path, which will be
* made available to logging functions.
*/
function collectMetadata (path: NodePath, opts: PluginOptions): Metadata {
const filename: string = fspath.resolve(process.cwd(), path.hub.file.opts.filename);
const dirname: string = fspath.dirname(filename);
const extname: string = fspath.extname(filename);
const basename: string = fspath.basename(filename, extname);
const prefix: string = generatePrefix(dirname, basename);
const names: string[] = [];
let indent: number = 0;
let parent: ?NodePath;
const parentName: string = path.getAncestry().slice(1).reduce((parts: string[], item: NodePath) => {
if (item.isClassMethod()) {
if (!parent) {
parent = item;
}
parts.unshift(item.node.key.type === 'Identifier' ? item.node.key.name : '[computed method]');
const parentName: string = path.getAncestry().slice(1).reduce((parts: string[], item: NodePath) => {
if (item.isClassMethod()) {
if (!parent) {
parent = item;
}
else if (item.isClassDeclaration()) {
if (!parent) {
parent = item;
}
parts.unshift(item.node.id ? item.node.id.name : `[anonymous class@${item.node.loc.start.line}]`);
parts.unshift(item.node.key.type === 'Identifier' ? item.node.key.name : '[computed method]');
}
else if (item.isClassDeclaration()) {
if (!parent) {
parent = item;
}
else if (item.isFunction()) {
if (!parent) {
parent = item;
}
parts.unshift((item.node.id && item.node.id.name) || `[anonymous@${item.node.loc.start.line}]`);
parts.unshift(item.node.id ? item.node.id.name : `[anonymous class@${item.node.loc.start.line}]`);
}
else if (item.isFunction()) {
if (!parent) {
parent = item;
}
else if (item.isProgram()) {
if (!parent) {
parent = item;
}
parts.unshift((item.node.id && item.node.id.name) || `[anonymous@${item.node.loc.start.line}]`);
}
else if (item.isProgram()) {
if (!parent) {
parent = item;
}
else if (!parent && !item.isClassBody() && !item.isBlockStatement()) {
indent++;
}
else if (!parent && !item.isClassBody() && !item.isBlockStatement()) {
indent++;
}
return parts;
}, []).join(':');
let hasStartMessage: boolean = false;
let isStartMessage: boolean = false;
if (parent && !parent.isProgram()) {
for (let child: NodePath of parent.get('body').get('body')) {
if (child.node[$handled]) {
hasStartMessage = true;
break;
}
return parts;
}, []).join(':');
let hasStartMessage: boolean = false;
let isStartMessage: boolean = false;
if (parent && !parent.isProgram()) {
for (let child: NodePath of parent.get('body').get('body')) {
if (child.node[$handled]) {
hasStartMessage = true;
break;
if (!child.isLabeledStatement()) {
break;
}
const label: NodePath = child.get('label');
if (opts.aliases[label.node.name]) {
hasStartMessage = true;
if (child.node === path.node) {
isStartMessage = true;
}
if (!child.isLabeledStatement()) {
break;
}
const label: NodePath = child.get('label');
if (opts.aliases[label.node.name]) {
hasStartMessage = true;
if (child.node === path.node) {
isStartMessage = true;
}
break;
}
break;
}
}
const context: string = `${prefix}:${parentName}`;
return {indent, prefix, parentName, context, hasStartMessage, isStartMessage, filename, dirname, basename, extname};
}
const context: string = `${prefix}:${parentName}`;
return {indent, prefix, parentName, context, hasStartMessage, isStartMessage, filename, dirname, basename, extname};
}
/**
* Determine whether the given logging statement should be stripped.
*/
function shouldStrip (name: string, metadata: Metadata, opts: PluginOptions): boolean {
if (!opts.strip) {
/**
* Determine whether the given logging statement should be stripped.
*/
function shouldStrip (name: string, metadata: Metadata, { strip }: PluginOptions): boolean {
switch (typeof strip) {
case 'boolean':
if (!strip) return false;
// strip === true
break;
case 'object':
const se = strip[name];
if (!se || (typeof se === 'object' && !se[process.env.NODE_ENV])) return false;
// strip[name] === true || strip[name][env] === true
break;
default:
return false;
}
else if (opts.strip === true) {
return !hasStripOverride(name, metadata);
}
else if (typeof opts.strip === 'string') {
if (opts.strip === process.env.NODE_ENV) {
return !hasStripOverride(name, metadata);
}
}
else if (opts.strip[process.env.NODE_ENV]) {
return !hasStripOverride(name, metadata);
}
return true;
}
if (PRESERVE_CONTEXTS.length) {
const context = metadata.context.toLowerCase();
if (PRESERVE_CONTEXTS.some(pc => context.includes(pc))) return false;
}
if (PRESERVE_FILES.length) {
const filename = metadata.filename.toLowerCase();
if (PRESERVE_FILES.some(pf => filename.includes(pf))) return false;
}
if (PRESERVE_LEVELS.length) {
const level = name.toLowerCase();
if (PRESERVE_LEVELS.some(pl => level === pl)) return false;
}
return true;
}
function hasStripOverride (name: string, metadata: Metadata) {
if (PRESERVE_CONTEXTS.length && PRESERVE_CONTEXTS.some(context => metadata.context.toLowerCase().indexOf(context) !== -1)) {
return true;
}
else if (PRESERVE_FILES.length && PRESERVE_FILES.some(filename => metadata.filename.toLowerCase().indexOf(filename) !== -1)) {
return true;
}
else if (PRESERVE_LEVELS.length && PRESERVE_LEVELS.some(level => level === name.toLowerCase())) {
return true;
}
else {
return false;
}
export function handleLabeledStatement (babel: PluginParams, path: NodePath, opts: PluginOptions): void {
const t = babel.types;
const label: NodePath = path.get('label');
opts = normalizeOpts(babel, opts);
if (!opts.aliases[label.node.name]) {
return;
}
const metadata: Metadata = collectMetadata(path, opts);
if (shouldStrip(label.node.name, metadata, opts)) {
path.remove();
return;
}
path.traverse({
"VariableDeclaration|Function|AssignmentExpression|UpdateExpression|YieldExpression|ReturnStatement" (item: NodePath): void {
throw path.buildCodeFrameError(`Logging statements cannot have side effects.`);
},
ExpressionStatement (statement: NodePath): void {
if (statement.node[$handled]) {
return;
}
const message: Message = {
prefix: t.stringLiteral(metadata.prefix),
content: statement.get('expression').node,
hasStartMessage: t.booleanLiteral(metadata.hasStartMessage),
isStartMessage: t.booleanLiteral(metadata.isStartMessage),
indent: t.numericLiteral(metadata.indent),
parentName: t.stringLiteral(metadata.parentName),
filename: t.stringLiteral(metadata.filename),
dirname: t.stringLiteral(metadata.dirname),
basename: t.stringLiteral(metadata.basename),
extname: t.stringLiteral(metadata.extname)
};
const replacement = t.expressionStatement(opts.aliases[label.node.name](message, metadata));
replacement[$handled] = true;
statement.replaceWith(replacement);
}
});
if (path.get('body').isBlockStatement()) {
path.replaceWithMultiple(path.get('body').node.body);
}
else {
path.replaceWith(path.get('body').node);
}
}
/**
* # Trace
*/
export default function (babel: PluginParams): Plugin {
return {
visitor: {
Program (program: NodePath, {opts}) {
Program (program: NodePath, { opts }) {
program.traverse({
LabeledStatement (path: NodePath): void {
const label: NodePath = path.get('label');
opts = normalizeOpts(opts);
if (!opts.aliases[label.node.name]) {
return;
}
const metadata: Metadata = collectMetadata(path, opts);
if (shouldStrip(label.node.name, metadata, opts)) {
path.remove();
return;
}
path.traverse({
"VariableDeclaration|Function|AssignmentExpression|UpdateExpression|YieldExpression|ReturnStatement" (item: NodePath): void {
throw path.buildCodeFrameError(`Logging statements cannot have side effects.`);
},
ExpressionStatement (statement: NodePath): void {
if (statement.node[$handled]) {
return;
}
const message: Message = {
prefix: t.stringLiteral(metadata.prefix),
content: statement.get('expression').node,
hasStartMessage: t.booleanLiteral(metadata.hasStartMessage),
isStartMessage: t.booleanLiteral(metadata.isStartMessage),
indent: t.numericLiteral(metadata.indent),
parentName: t.stringLiteral(metadata.parentName),
filename: t.stringLiteral(metadata.filename),
dirname: t.stringLiteral(metadata.dirname),
basename: t.stringLiteral(metadata.basename),
extname: t.stringLiteral(metadata.extname)
};
const replacement = t.expressionStatement(opts.aliases[label.node.name](message, metadata));
replacement[$handled] = true;
statement.replaceWith(replacement);
}
});
if (path.get('body').isBlockStatement()) {
path.replaceWithMultiple(path.get('body').node.body);
}
else {
path.replaceWith(path.get('body').node);
}
handleLabeledStatement(babel, path, opts);
}
});
}
}
};
}
class Thing {
foo () {
trace: "foo";
log: "foo";
if (true) {
trace: "bar";
log: "bar";
if (true) {
trace: "qux";
log: "qux";
(() => {
trace: "nested";
warn: "nested";
})();

@@ -19,2 +19,2 @@ }

thing.foo();
}
}
export default function demo () {
trace: "hello world";
log: "hello world";
if (Math.random() > 0.5) {
trace: "Got result.";
log: "Got result.";
}
else {
trace: "Got result."
log: "Got result."
}
}
}
export default function demo () {
trace: {
log: {
"hello world";
"foo bar";
}
}
}
export default function demo () {
trace: "hello world", "foo", "bar";
}
log: "hello world", "foo", "bar";
}
export default function demo () {
trace: "hello world";
}
log: "hello world";
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc