Security News
Node.js EOL Versions CVE Dubbed the "Worst CVE of the Year" by Security Experts
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
Software complexity analysis of JavaScript-family abstract syntax trees. The back-end for complexity-report.
This library deliberately excludes logic for parsing source code and for navigating parse trees. Both the syntax tree and a matching syntax tree walker are inputs to escomplex, meaning it is not tied to any particular language, parser or data format.
Currently the library reports on:
arguments
object.
Lower is better.require
.
Analysed statically
from the function signature,
so no accounting is made
for dynamic calls
where a variable or function is
obscuring the nature of the dependency.
Lower is better.It is important to note that none of these metrics can compete with the insight of a competent developer. At best, they are an automatable warning system, which can help to identify areas of code that warrant closer inspection by a human being.
The library is published on npm
under the name escomplex
.
To install,
you can add it to the dependencies
in your package.json
file
or simply run:
npm install escomplex
You can load escomplex
in your own code
by calling require
:
var escomplex = require('escomplex');
It exports one function,
called analyse
:
var result = escomplex.analyse(ast, walker, options);
The first argument, ast
,
must be either
an abstract syntax tree
or an array of syntax trees.
If it is an array,
each tree should include
an extra property, path
,
that is either a relative or full path
to the equivalent module on disk.
As well as identifying
each of the result objects,
that path is also used
during dependency analysis.
The second argument, walker
,
must be a syntax tree walker.
The third argument, options
,
is an optional object
containing properties that modify
some of the complexity calculations:
options.logicalor
:
Boolean indicating whether operator ||
should be considered a source of cyclomatic complexity,
defaults to true
.options.switchcase
:
Boolean indicating whether switch
statements
should be considered a source of cyclomatic complexity,
defaults to true
.options.forin
:
Boolean indicating whether for
...in
loops
should be considered a source of cyclomatic complexity,
defaults to false
.options.trycatch
:
Boolean indicating whether catch
clauses
should be considered a source of cyclomatic complexity,
defaults to false
.options.newmi
:
Boolean indicating whether the maintainability
index should be rebased on a scale from 0 to 100,
defaults to false
.If a single abstract syntax tree object
is passed in the ast
argument,
the result will be a report object
that looks like the following:
{
maintainability: 171,
dependencies: [],
aggregate: {
sloc: {
logical: 0,
physical: 0
},
params: 0,
cyclomatic: 1,
cyclomaticDensity: 1,
halstead: {
vocabulary: 0,
difficulty: 0,
volume: 0,
effort: 0,
bugs: 0,
time: 0
}
},
functions: [
{
name: '',
line: 0,
sloc: {
logical: 0,
physical: 0
},
params: 0,
cyclomatic: 1,
cyclomaticDensity: 1,
halstead: {
vocabulary: 0,
difficulty: 0,
volume: 0,
effort: 0,
bugs: 0,
time: 0
}
},
...
]
}
The meaning of those values, briefly, is as follows (see metrics for more information on each one):
report.maintainability
:
The maintainability index for the module.report.dependencies
:
The array of CommonJS/AMD dependencies for the module.report.aggregate.sloc.physical
:
Physical lines of code for the module.
Will be undefined
if the syntax tree
is not annotated
with line number data.report.aggregate.sloc.logical
:
Logical lines of code for the module.report.aggregate.params
:
Parameter count for the module.report.aggregate.cyclomatic
:
Cyclomatic complexity for the module.report.aggregate.cyclomaticDensity
:
Cyclomatic complexity density for the module.report.aggregate.halstead.vocabulary
:
Halstead vocabulary size for the module.report.aggregate.halstead.difficulty
:
Halstead difficulty for the module.report.aggregate.halstead.volume
:
Halstead volume for the module.report.aggregate.halstead.effort
:
Halstead effort for the module.report.aggregate.halstead.bugs
:
Halstead bugs for the module.report.aggregate.halstead.time
:
Halstead time for the module.report.functions[n].name
:
Function name.report.functions[n].line
:
Line number that the function starts on.
Will be undefined
if the syntax tree
is not annotated
with line number data.report.functions[n].sloc.physical
:
Physical lines of code for the function.
Will be undefined
if the syntax tree
is not annotated
with line number data.report.functions[n].sloc.logical
:
Logical lines of code for the function.report.functions[n].params
:
Parameter count for the function.report.functions[n].cyclomatic
:
Cyclomatic complexity for the function.report.functions[n].cyclomaticDensity
:
Cyclomatic complexity density for the function.report.functions[n].halstead.vocabulary
:
Halstead vocabulary size for the function.report.functions[n].halstead.difficulty
:
Halstead difficulty for the function.report.functions[n].halstead.volume
:
Halstead volume for the function.report.functions[n].halstead.effort
:
Halstead effort for the function.report.functions[n].halstead.bugs
:
Halstead bugs for the function.report.functions[n].halstead.time
:
Halstead time for the function.If an array of syntax trees
is passed in the ast
argument,
the result will be an object
that looks like the following:
{
reports: [
...
],
adjacencyMatrix: [
[ 0 ]
],
firstOrderDensity: 0,
visibilityMatrix: [
[ 0 ]
],
changeCost: 100,
coreSize: 100
}
Those properties are defined as follows:
result.reports
:
An array of report objects,
each one in the same format
described above
but with an extra property path
that matches the path
property
from its corresponding syntax tree.
This path
property is required
because the reports array gets sorted
during dependency analysis.result.adjacencyMatrix
:
The adjacency
design structure matrix (DSM)
for the project.
This is a two-dimensional array,
each dimension with the same order and length
as the reports
array.
Each row and column
represents its equivalent
indexed module
from the reports
array,
with values along the horizontal
being 1
when that module
directly depends on another
and values along the vertical
being 1
when that module
is directly depended on by another.
All other values are 0
.result.firstOrderDensity
:
The first-order density for the project.result.visibilityMatrix
:
The visibility DSM for the project.
Like the adjacency matrix,
but expanded to incorporate
indirect dependencies.result.changeCost
:
The change cost for the project.result.coreSize
:
The core size for the project.Refer to the contrubution guidelines before submitting a pull request.
Source code is in /src
.
Unit tests are in /test
.
You can run the tests with npm test
.
You can run the linter with npm run lint
.
Make sure you've installed
all the dependencies
with npm install
first.
FAQs
Software complexity analysis of JavaScript-family abstract syntax trees.
The npm package escomplex receives a total of 3,478 weekly downloads. As such, escomplex popularity was classified as popular.
We found that escomplex demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
Security News
cURL and Go security teams are publicly rejecting CVSS as flawed for assessing vulnerabilities and are calling for more accurate, context-aware approaches.
Security News
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.