decofun v1.3.0
Decofun – Debug tool
Decofun is a JavaScript function deanonymizer.
It parses your code and names any anonymous functions according to their context.
Version 1.2.x
Install
npm i decofunFeatures
Command Line Tool
sudo npm -g i decofunNew from version 1.2.x we can simply use the deco
executable in place of node to instrument
anonymous functions.
deco examples/loadableSince version 1.3.x the deco executable can also be
instructed to use the cute-stack module to prettify stack traces, just add a --cute flag
deco examples/loadable --cuteTo set the cute-stack's display type,
pass it as the value of --cute
deco examples/loadable --cute tableTo set the stack size pass a number
deco examples/loadable --cute 20To set both the display type and number, pass a JSON array
deco examples/loadable --cute '["table", 20]'Automatic Instrumentation
New from version 1.1.x, we can use decofun to automatically
instrument any required modules, simply call the auto method,
before requring any other modules
require('decofun').auto()
var myMod = require('./lib/myModule.js')
var somePub = require('somePublishedMod')Both myMod and somePub will now have their anonymous functions named.
Alternatively, decofun can be called directly as a function (without supplying a path argument) to achieve the same result:
require('decofun')() # same as require('decofun').auto()
var myMod = require('./lib/myModule.js')
var somePub = require('somePublishedMod')To undo automatic instrumentation and restore former
behavior, simply use the restore method:
var decofun = require('decofun');
decofun.auto();
var myMod = require('./aModToDebug')
decofun.restore();
var anotherMod = require('./noDebugNeededThx')Client-side Instrumenting
For instrumenting browser code, you can use the deco-server module.
There is a live deco-server running on heroku, for instance
we can deanonymize jQuery by with the following URL:
http://decofun.herokuapp.com/?addr=http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.js
A deco transform is also planned for those who
use browserify - for now we can simply
use a deco-server to host our browserified code.
Programmatic Transform
We can transform any string containing JavaScript with
the transform method.
var decofun = require('decofun')
var fs = require('fs');
var path = require('path')
var fixture = fs.readFileSync(path.join(__dirname, './fixture.js'));
console.log(decofun.transform(fixture))As with the auto method, transforms can also be achieved
with the polymorphic function representing the decofun module.
When we pass a string to the decofun function, it executes a
transform (and when we don't pass a string it calls decofun.auto):
console.log(decofun(fixture))
//same thing:
//console.log(decofun.transform(fixture))Tests
Run tests with
npm testExamples
The examples folder is a good place to start.
To see how a direct transform would work, from the install directory we could run these commands:
cat node_modules/decofun/examples/transform/fixture.js #view the original
node node_modules/decofun/examples/transform # view the resultTo see instrumentation upon require (the Auto feature),
run the following:
cat node_modules/decofun/examples/auto/fixture.js #view the original
node node_modules/decofun/examples/auto # view the resultfunctions assigned to variables
Are labelled "of var | line N".
var myFn = function () {}Transforms into:
var myFn = function asᅠvarᅠmyFnᅠㅣlineᅠ1 () {}function parameters
Are labelled "passed into | line N".
someFunc('blah', function () {})Transforms into:
someFunc('blah', function passedᅠintoᅠsomeFuncᅠㅣlineᅠ1 () {})method parameters
Are labelled "passed into ː | line N".
obj.prop(function () { })Transforms into:
obj.prop(function passedᅠintoᅠobjːpropᅠㅣlineᅠ1 () { })sub-object method parameters
Are labelled "passed into ː | line N".
obj.subobj.prop(function () { })Transforms into:
obj.subobj.prop(function passedᅠintoᅠsubobjːpropᅠㅣlineᅠ1 () { })returned functions
Are labelled "returned from | line N".
function f() {return function () { }}Transforms into:
function f() {return function returnedᅠfromᅠfᅠㅣlineᅠ1 () { }}returned functions of returned anonymous functions
Are labelled "returned from ᐸ <parent function (named)> ᐳ | line N".
function contain () {
return function () {
return function () {
}
}
}Transforms into:
function contain() {
return function returnedᅠfromᅠcontainᅠㅣlineᅠ2 () {
return function returnedᅠfromᅠᐸᅠreturnedᅠfromᅠcontainᅠᐳᅠㅣlineᅠ3 () {
}
}
}methods declared in object literals
Are labelled "as property ㅣ line N".
function contain () {
return {
propInLiteral: function () {}
}
}Transforms into:
function contain() {
return {
propInLiteral: function asᅠpropertyᅠpropInLiteralᅠㅣlineᅠ3 () {}
}
}methods assigned to instantiated objects
Are labelled "as property ㅣ line N".
var o = {}; o.p = function (cb) { }Transforms into:
var o = {}; o.p = function asᅠpropertyᅠpᅠㅣlineᅠ1 (cb) { }immediately invoked function expressions
Are labelled "IIFEㅣ line N".
!function() {}()
;(function(){}())Transforms into:
!function IIFEᅠㅣlineᅠ1() {}()
;(function IIFEᅠㅣlineᅠ2(){}())Kudos
Sponsered by nearForm