Socket
Socket
Sign inDemoInstall

babel-plugin-debug-macros

Package Overview
Dependencies
Maintainers
1
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-debug-macros - npm Package Compare versions

Comparing version 0.0.3 to 0.0.4

74

dist/index.js

@@ -7,3 +7,15 @@ 'use strict';

exports.default = function (babel) {
var _macros = require('./lib/utils/macros');
var _macros2 = _interopRequireDefault(_macros);
var _fs = require('fs');
var _path = require('path');
var _normalizeOptions = require('./lib/utils/normalize-options');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function macros(babel) {
const { types: t } = babel;

@@ -20,27 +32,29 @@ let macroBuilder;

options = (0, _normalizeOptions.normalizeOptions)(state.opts);
macroBuilder = new _macros2.default(t, options);
},
this.macroBuilder = new _macros2.default(t, options);
exit(path) {
if (macroBuilder.importedDebugTools) {
macroBuilder.expand(path);
}
}
},
let body = path.get('body');
ImportDeclaration(path, state) {
let importPath = path.node.source.value;
body.forEach(item => {
if (item.isImportDeclaration()) {
let importPath = item.node.source.value;
let {
featureImportSpecifiers,
debugTools: { debugToolsImport },
envFlags: { flags: { DEBUG } }
} = options;
let {
featureSources,
debugTools: { debugToolsImport },
envFlags: { envFlagsImport, flags }
} = options;
let isFeaturesImport = featureImportSpecifiers.includes(importPath);
let isFeaturesImport = featureSources.includes(importPath);
if (isFeaturesImport && !DEBUG) {
macroBuilder.inlineFeatureFlags(path);
} else if (debugToolsImport && debugToolsImport === importPath) {
macroBuilder.collectDebugToolsSpecifiers(path.node.specifiers);
if (debugToolsImport && debugToolsImport === importPath) {
this.macroBuilder.collectDebugToolsSpecifiers(item.get('specifiers'));
}if (envFlagsImport && envFlagsImport === importPath) {
this.macroBuilder.collectEnvFlagSpecifiers(item.get('specifiers'));
}
}
});
},
exit(path) {
this.macroBuilder.expand(path);
}

@@ -50,18 +64,12 @@ },

ExpressionStatement(path) {
macroBuilder.build(path);
this.macroBuilder.build(path);
}
}
};
}
macros.cacheKey = function () {
return macros.toString();
};
var _macros = require('./lib/utils/macros');
var _macros2 = _interopRequireDefault(_macros);
var _fs = require('fs');
var _path = require('path');
var _normalizeOptions = require('./lib/utils/normalize-options');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = macros;

@@ -7,5 +7,6 @@ 'use strict';

class Builder {
constructor(t, externalizeHelpers) {
constructor(t, module, global) {
this.t = t;
this.helpers = externalizeHelpers;
this.module = module;
this.global = global;
this.expressions = [];

@@ -21,15 +22,14 @@ }

*
* (DEBUG && console.assert($PREDICATE, $MESSAGE));
* ($DEBUG && console.assert($PREDICATE, $MESSAGE));
*
* or
*
* (DEBUG && assert($PREDICATE, $MESSAGE));
* ($DEBUG && assert($PREDICATE, $MESSAGE));
*
* or
*
* (DEBUG && $GLOBAL_NS.assert($PREDICATE, $MESSAGE));
* ($DEBUG && $GLOBAL_NS.assert($PREDICATE, $MESSAGE));
*/
assert(path) {
let { helpers } = this;
this._createMacroExpression(path, helpers.debug);
this._createMacroExpression(path);
}

@@ -44,15 +44,14 @@

*
* (DEBUG && console.warn($MESSAGE));
* ($DEBUG && console.warn($MESSAGE));
*
* or
*
* (DEBUG && warn($MESSAGE));
* ($DEBUG && warn($MESSAGE));
*
* or
*
* (DEBUG && $GLOBAL_NS.warn($MESSAGE));
* ($DEBUG && $GLOBAL_NS.warn($MESSAGE));
*/
warn(path) {
let { helpers } = this;
this._createMacroExpression(path, helpers.debug);
this._createMacroExpression(path);
}

@@ -67,19 +66,18 @@

*
* (DEBUG && console.log($MESSAGE));
* ($DEBUG && console.log($MESSAGE));
*
* or
*
* (DEBUG && log($MESSAGE));
* ($DEBUG && log($MESSAGE));
*
* or
*
* (DEBUG && $GLOBAL_NS.log($MESSAGE));
* ($DEBUG && $GLOBAL_NS.log($MESSAGE));
*/
log(path) {
let { helpers } = this;
this._createMacroExpression(path, helpers.debug);
this._createMacroExpression(path);
}
_createMacroExpression(path, helpers) {
let { t } = this;
_createMacroExpression(path) {
let { t, module, global } = this;
let expression = path.node.expression;

@@ -89,6 +87,5 @@ let { callee, arguments: args } = expression;

if (helpers) {
let ns = helpers.global;
if (ns) {
callExpression = this._createGlobalExternalHelper(callee, args, ns);
if (module || global) {
if (global) {
callExpression = this._createGlobalExternalHelper(callee, args, global);
} else {

@@ -102,3 +99,3 @@ callExpression = expression;

let identifiers = this._getIdentifiers(args);
this.expressions.push([path, this._buildLogicalExpressions(identifiers, callExpression)]);
this.expressions.push([path, this._buildLogicalExpressions([], callExpression)]);
}

@@ -109,2 +106,6 @@

*
* deprecate($MESSAGE, $PREDICATE)
*
* or
*
* deprecate($MESSAGE, $PREDICATE, {

@@ -118,97 +119,53 @@ * $ID,

*
* (DEBUG && $PREDICATE && console.warn('DEPRECATED [$ID]: $MESSAGE. Will be removed in $UNIL. See $URL for more information.'));
* ($DEBUG && $PREDICATE && console.warn($MESSAGE));
*
* or
*
* (DEBUG && $PREDICATE && deprecate('DEPRECATED [$ID]: $MESSAGE. Will be removed in $UNIL. See $URL for more information.'));
* ($DEBUG && $PREDICATE && deprecate($MESSAGE, $PREDICATE, { $ID, $URL, $UNTIL }));
*
* or
*
* (DEBUG && $PREDICATE && $GLOBAL_NS.deprecate('DEPRECATED [$ID]: $MESSAGE. Will be removed in $UNIL. See $URL for more information.'));
* ($DEBUG && $PREDICATE && $GLOBAL_NS.deprecate($MESSAGE, $PREDICATE, { $ID, $URL, $UNTIL }));
*/
deprecate(path) {
let { t, helpers } = this;
let { t, module, global } = this;
let expression = path.node.expression;
let { callee, arguments: args } = expression;
let [message, predicate, metaExpression] = args;
let callee = expression.callee;
let args = expression.arguments;
let [message, predicate, meta] = args;
let meta = {
url: null,
id: null,
until: null
};
metaExpression.properties.forEach(prop => {
let { key, value } = prop;
meta[key.name] = value.value;
});
if (!meta.id) {
if (meta && meta.properties && !meta.properties.some(prop => prop.key.name === 'id')) {
throw new ReferenceError(`deprecate's meta information requires an "id" field.`);
}
if (!meta.until) {
if (meta && meta.properties && !meta.properties.some(prop => prop.key.name === 'until')) {
throw new ReferenceError(`deprecate's meta information requires an "until" field.`);
}
let deprecationMessage = this._generateDeprecationMessage(message, meta);
let deprecate;
let { debug } = helpers;
if (debug) {
let ns = debug.global;
if (ns) {
deprecate = this._createGlobalExternalHelper(callee, [deprecationMessage], ns);
if (module || global) {
if (global) {
deprecate = this._createGlobalExternalHelper(callee, args, global);
} else {
deprecate = path.node.expression;
deprecate.arguments = [deprecationMessage];
deprecate = expression;
}
} else {
deprecate = this._createConsoleAPI(t.identifier('warn'), [deprecationMessage]);
deprecate = this._createConsoleAPI(t.identifier('warn'), [message]);
}
this.expressions.push([path, this._buildLogicalExpressions([predicate], deprecate)]);
this.expressions.push([path, this._buildLogicalExpressions([t.unaryExpression('!', t.parenthesizedExpression(predicate))], deprecate)]);
}
/**
* Produces
*
* const $NAME = $DEBUG;
* Performs the actually expansion of macros
*/
debugFlag(name, debug) {
expandMacros(debugFlag) {
let { t } = this;
return this._createConstant(name, t.numericLiteral(debug));
}
/**
* Produces an array on "const" VariableDeclarations based on
* flags.
*/
flagConstants(specifiers, flagTable, source) {
let { t } = this;
return specifiers.map(specifier => {
let flag = flagTable[specifier.imported.name];
if (flag !== undefined) {
return this._createConstant(t.identifier(specifier.imported.name), t.numericLiteral(flag));
}
throw new Error(`Imported ${specifier.imported.name} from ${source} which is not a supported flag.`);
});
}
/**
* Performs the actually expansion of macros
*/
expandMacros(debugIdentifier) {
let flag = t.booleanLiteral(debugFlag);
for (let i = 0; i < this.expressions.length; i++) {
let [exp, logicalExp] = this.expressions[i];
exp.replaceWith(this.t.parenthesizedExpression(logicalExp(debugIdentifier)));
exp.replaceWith(t.parenthesizedExpression(logicalExp(flag)));
}
}
_createConstant(left, right) {
let { t } = this;
return t.variableDeclaration('const', [t.variableDeclarator(left, right)]);
}
_getIdentifiers(args) {

@@ -223,7 +180,2 @@ return args.filter(arg => this.t.isIdentifier(arg));

_createExternalHelper(identifier, args) {
let { t } = this;
return t.callExpression(t.identifier(type), args);
}
_createConsoleAPI(identifier, args) {

@@ -234,6 +186,2 @@ let { t } = this;

_generateDeprecationMessage(message, meta) {
return this.t.stringLiteral(`DEPRECATED [${meta.id}]: ${message.value}. Will be removed in ${meta.until}.${meta.url ? ` See ${meta.url} for more information.` : ''}`);
}
_buildLogicalExpressions(identifiers, callExpression) {

@@ -240,0 +188,0 @@ let { t } = this;

@@ -15,12 +15,21 @@ 'use strict';

const SUPPORTED_MACROS = ['assert', 'deprecate', 'warn', 'log'];
class Macros {
constructor(t, options) {
this.localDebugBindings = [];
this.isImportRemovable = false;
this.envFlagBindings = [];
this.hasEnvFlags = false;
this.envFlagsSource = options.envFlags.envFlagsImport;
this.importedDebugTools = false;
this.envFlags = options.envFlags.flags;
this.featureFlags = options.features;
this.debugHelpers = options.externalizeHelpers.debug;
this.isGlobals = true;
this.builder = new _builder2.default(t, options.externalizeHelpers);
this.featureSources = options.featureSources;
this.featuresMap = options.featuresMap;
this.svelteMap = options.svelteMap;
this.svelteVersions = options.svelte;
this.featureFlags = options.features || [];
this.debugHelpers = options.externalizeHelpers || {};
let { module, global } = this.debugHelpers;
this.builder = new _builder2.default(t, module, global);
}

@@ -34,31 +43,63 @@

let debugBinding = path.scope.getBinding(DEBUG);
let { builder } = this;
let { builder, envFlags } = this;
if (this._hasDebugModule(debugBinding)) {
this.builder.expandMacros(debugBinding.path.node.local);
this._inlineEnvFlags(debugBinding.path.parentPath);
} else {
let debugIdentifier = path.scope.generateUidIdentifier(DEBUG);
if (builder.expressions.length > 0) {
this._injectDebug(path, debugIdentifier);
}
this.builder.expandMacros(debugIdentifier);
debugBinding.path.parentPath.remove();
}
this._inlineFeatureFlags(path);
this._inlineSvelteFlags(path);
this._inlineEnvFlags(path);
this.builder.expandMacros(envFlags.DEBUG);
this._cleanImports(path);
}
inlineFeatureFlags(path) {
for (let i = 0; i < this.featureFlags.length; i++) {
let features = this.featureFlags[i];
if (features.featuresImport === path.node.source.value) {
let flagDeclarations = this.builder.flagConstants(path.node.specifiers, features.flags, path.node.source.value);
path.replaceWithMultiple(flagDeclarations);
break;
_inlineFeatureFlags(path) {
let { envFlags, builder, featureFlags, featuresMap } = this;
Object.keys(featuresMap).forEach(source => {
Object.keys(featuresMap[source]).forEach(flag => {
let binding = path.scope.getBinding(flag);
if (binding && featuresMap[source][flag] !== null) {
binding.referencePaths.forEach(p => p.replaceWith(builder.t.booleanLiteral(featuresMap[source][flag])));
binding.path.remove();
}
});
});
}
_inlineEnvFlags(path) {
let { envFlags, builder } = this;
Object.keys(envFlags).forEach(flag => {
let binding = path.scope.getBinding(flag);
if (binding) {
binding.referencePaths.forEach(p => p.replaceWith(builder.t.booleanLiteral(envFlags[flag])));
}
}
});
}
_inlineSvelteFlags(path) {
let { svelteMap, envFlags, builder } = this;
let sources = Object.keys(svelteMap);
sources.forEach(source => {
Object.keys(svelteMap[source]).forEach(flag => {
path.scope.getBinding(flag).referencePaths.forEach(p => {
if (envFlags.DEBUG) {
if (!svelteMap[source][flag]) {
let { t } = builder;
let consequent = p.parentPath.get('consequent');
consequent.unshiftContainer('body', builder.t.throwStatement(t.newExpression(t.identifier('Error'), [t.stringLiteral(`You indicated you don't have any deprecations, however you are relying on ${flag}.`)])));
}
} else {
let binding = path.scope.getBinding(flag);
if (binding) {
binding.referencePaths.forEach(p => p.replaceWith(builder.t.booleanLiteral(svelteMap[source][flag])));
binding.path.remove();
}
}
});
});
});
}
/**

@@ -70,4 +111,12 @@ * Collects the import bindings for the debug tools.

this._collectImportBindings(specifiers, this.localDebugBindings);
if (specifiers.length === this.localDebugBindings.length) {
this.isImportRemovable = true;
}
}
collectEnvFlagSpecifiers(specifiers) {
this.hasEnvFlags = true;
this._collectImportBindings(specifiers, this.envFlagBindings);
}
/**

@@ -79,3 +128,3 @@ * Builds the expressions that the CallExpression will expand into.

let { builder, localDebugBindings } = this;
if (builder.t.isCallExpression(expression) && localDebugBindings.indexOf(expression.callee.name) > -1) {
if (builder.t.isCallExpression(expression) && localDebugBindings.some(b => b.node.name === expression.callee.name)) {
let imported = path.scope.getBinding(expression.callee.name).path.node.imported.name;

@@ -88,37 +137,62 @@ this.builder[`${imported}`](path);

specifiers.forEach(specifier => {
this.localDebugBindings.push(specifier.local.name);
if (specifier.node.imported && SUPPORTED_MACROS.includes(specifier.node.imported.name)) {
buffer.push(specifier.get('local'));
}
});
}
_injectDebug(path, name) {
path.node.body.unshift(this.builder.debugFlag(name, this.envFlags.DEBUG));
}
_inlineEnvFlags(path) {
let flagDeclarations = this.builder.flagConstants(path.node.specifiers, this.envFlags, path.node.source.value);
path.replaceWithMultiple(flagDeclarations);
}
_hasDebugModule(debugBinding) {
let fromModule = debugBinding && debugBinding.kind === 'module';
let moduleName = fromModule && debugBinding.path.parent.source.value;
return moduleName === '@ember/env-flags';
return moduleName === this.envFlagsSource;
}
_detectForeignFeatureFlag(specifiers, source) {
let { featuresMap } = this;
specifiers.forEach(specifier => {
if (featuresMap[source][specifier.imported.name] !== null) {
throw new Error(`Imported ${specifier.imported.name} from ${source} which is not a supported flag.`);
}
});
}
_cleanImports(path) {
let { debugHelpers } = this;
let {
debugHelpers,
builder,
featureFlags,
featureSources
} = this;
if (debugHelpers) {
this.isGlobals = !!debugHelpers.global;
}
let body = path.get('body');
if (this.localDebugBindings.length > 0 && this.isGlobals) {
let importDeclaration = path.scope.getBinding(this.localDebugBindings[0]).path.parentPath;
if (!this.envFlags.DEBUG) {
for (let i = 0; i < body.length; i++) {
let decl = body[i];
// Note this nukes the entire ImportDeclaration so we simply can
// just grab one of the bindings to remove.
importDeclaration.remove();
if (builder.t.isImportDeclaration(decl)) {
let source = decl.node.source.value;
if (featureSources.includes(source)) {
if (decl.node.specifiers.length > 0) {
this._detectForeignFeatureFlag(decl.node.specifiers, source);
} else {
decl.remove();
break;
}
}
}
}
}
if (!debugHelpers.module) {
if (this.localDebugBindings.length > 0) {
if (this.isImportRemovable) {
this.localDebugBindings[0].parentPath.parentPath.remove();
} else {
this.localDebugBindings.forEach(binding => binding.parentPath.remove());
}
}
}
}
}
exports.default = Macros;

@@ -12,3 +12,3 @@ 'use strict';

let {
features,
features = [],
debugTools,

@@ -20,36 +20,42 @@ envFlags,

let featureImportSpecifiers = [];
if (features) {
features = features.map(feature => {
let featuresImport = feature.importSpecifier;
featureImportSpecifiers.push(featuresImport);
let name = feature.name;
let featureSources = [];
let featuresMap = {};
let svelteMap = {};
let hasSvelteBuild = false;
let flags = {};
Object.keys(feature.flags).forEach(flagName => {
let value = feature.flags[flagName];
if (!Array.isArray(features)) {
features = [features];
}
if (typeof value === 'string' && svelte[name]) {
flags[flagName] = (0, _semver.satisfies)(value, `>=${svelte[name]}`) | 0;
} else if (typeof value === 'number') {
flags[flagName] = value;
} else {
throw new Error(`Flags must be a scalar value or semver version`);
}
});
features = features.map(feature => {
let featuresSource = feature.source;
featureSources.push(featuresSource);
let name = feature.name;
return {
name,
featuresImport,
flags
};
let flags = {};
featuresMap[featuresSource] = {};
svelteMap[featuresSource] = {};
Object.keys(feature.flags).forEach(flagName => {
let value = feature.flags[flagName];
if (typeof value === 'string' && svelte[name]) {
hasSvelteBuild = true;
flags[flagName] = svelteMap[featuresSource][flagName] = (0, _semver.satisfies)(value, `>=${svelte[name]}`);
} else if (typeof value === 'boolean' || value === null) {
flags[flagName] = featuresMap[featuresSource][flagName] = value;
} else {
throw new Error(`Flags must be a scalar value or semver version`);
}
});
if (features.flags) {
featureFlags = features.flags;
}
}
return {
name,
source: feature.source,
flags
};
});
if (!debugTools) {
throw new Error('You must specify `debugTools.importSpecifier`');
throw new Error('You must specify `debugTools.source`');
}

@@ -59,3 +65,3 @@

if (debugTools) {
debugToolsImport = debugTools.importSpecifier;
debugToolsImport = debugTools.source;
}

@@ -67,3 +73,3 @@

if (envFlags) {
envFlagsImport = envFlags.importSpecifier;
envFlagsImport = envFlags.source;
if (envFlags.flags) {

@@ -76,10 +82,10 @@ _envFlags = envFlags.flags;

if (!externalizeHelpers) {
externalizeHelpers = {};
}
return {
featureImportSpecifiers,
featureSources,
externalizeHelpers,
features,
featuresMap,
svelteMap,
hasSvelteBuild,
svelte,
envFlags: {

@@ -86,0 +92,0 @@ envFlagsImport,

@@ -13,3 +13,3 @@ {

"name": "babel-plugin-debug-macros",
"version": "0.0.3",
"version": "0.0.4",
"description": "Debug macros and feature flag stripping",

@@ -16,0 +16,0 @@ "main": "dist/index.js",

@@ -15,15 +15,15 @@ # Babel Debug Macros And Feature Flags

envFlags: {
importSpecifier: '@ember/env-flags',
flags: { DEBUG: 1 }
source: '@ember/env-flags',
flags: { DEBUG: true }
},
// @required
debugTools: {
importSpecifier: 'debug-tools'
source: 'debug-tools'
},
// @optional
features: [{
features: {
name: 'ember-source',
importSpecifier: '@ember/features',
flags: { FEATURE_A: 0, FEATURE_B: 1, DEPRECATED_CONTROLLERS: "2.12.0" }
}],
source: '@ember/features',
flags: { FEATURE_A: false, FEATURE_B: true, DEPRECATED_CONTROLLERS: "2.12.0" }
},
// @optional

@@ -35,3 +35,3 @@ svelte: {

externalizeHelpers: {
module: 'my-helpers' // or true to retain the name in code
module: true,
// global: '__my_global_ns__'

@@ -69,7 +69,3 @@ }

```javascript
const DEBUG = 1;
const FEATURE_A = 0;
cosnt FEATURE_B = 1;
if (DEBUG) {
if (true) {
console.log('Hello from debug');

@@ -79,5 +75,5 @@ }

let woot;
if (FEATURE_A) {
if (false) {
woot = () => 'woot';
} else if (FEATURE_B) {
} else if (true) {
woot = () => 'toow';

@@ -100,5 +96,3 @@ }

```javascript
const DEBUG = 1;
(DEBUG && console.warn('this is a warning'));
(true && console.warn('this is a warning'));
```

@@ -119,5 +113,4 @@

```javascript
const DEBUG = 1;
(DEBUG && console.assert((() => { return 1 === 1;})(), 'this is a warning'));
(true && console.assert((() => { return 1 === 1;})(), 'this is a warning'));
```

@@ -132,7 +125,3 @@

deprecate('This is deprecated.', foo % 2, {
id: 'old-and-busted',
url: 'http://example.com',
until: '4.0.0'
});
deprecate('This is deprecated.', foo % 2);
```

@@ -143,7 +132,5 @@

```javascript
const DEBUG = 1;
let foo = 2;
(DEBUG && foo % 2 && console.warn('DEPRECATED [old-and-busted]: This is deprecated. Will be removed in 4.0.0. Please see http://example.com for more details.'));
(true && !(foo % 2) && console.warn('This is deprecated.'));
```

@@ -166,5 +153,3 @@

```javascript
const DEBUG = 1;
(DEBUG && Ember.warn('this is a warning'));
(true && Ember.warn('this is a warning'));
```

@@ -183,6 +168,3 @@

```javascript
const DEBUG = 1;
import { warn } from 'my-helpers';
(DEBUG && warn('this is a warning'));
(true && warn('this is a warning'));
```

@@ -189,0 +171,0 @@

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